Java tutorial
/* * Copyright 2011 Google Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package osm.custommaps.create; import android.app.Activity; import android.app.Dialog; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.graphics.Bitmap; import android.graphics.Matrix; import android.graphics.Point; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.util.DisplayMetrics; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.view.ViewParent; import android.view.Window; import android.widget.Button; import android.widget.ImageButton; import android.widget.PopupMenu; import android.widget.SeekBar; import android.widget.Toast; import org.osmdroid.ResourceProxy; import org.osmdroid.api.IGeoPoint; import org.osmdroid.util.GeoPoint; import org.osmdroid.views.MapView; import org.osmdroid.views.overlay.DirectedLocationOverlay; import org.osmdroid.views.overlay.MinimapOverlay; import org.osmdroid.views.overlay.ScaleBarOverlay; import org.osmdroid.views.overlay.compass.CompassOverlay; import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider; import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay; import java.util.ArrayList; import java.util.List; import osm.custommaps.CustomMaps; import osm.custommaps.HelpDialogManager; import osm.custommaps.ImageHelper; import osm.custommaps.PtSizeFixer; import osm.custommaps.R; import osm.custommaps.WMS.WMSTileSourceFactory; /** * PreviewMapActivity shows the created map aligned on top of Google Map. * * @author Marko Teittinen */ public class PreviewMapActivity extends FragmentActivity { private static final String EXTRA_PREFIX = "osm.custommaps"; public static final String BITMAP_FILE = EXTRA_PREFIX + ".BitmapFile"; public static final String IMAGE_POINTS = EXTRA_PREFIX + ".ImagePoints"; public static final String TIEPOINTS = EXTRA_PREFIX + ".Tiepoints"; public static final String CORNER_GEO_POINTS = EXTRA_PREFIX + ".CornerGeoPoints"; public static final String PREFS_NAME = "osm.custommaps"; public static final String PREFS_TILE_SOURCE = "tilesource"; public static final String PREFS_SCROLL_X = "scrollX"; public static final String PREFS_SCROLL_Y = "scrollY"; public static final String PREFS_ZOOM_LEVEL = "MAP_ZOOM_LEVEL"; public static final String PREFS_SHOW_LOCATION = "showLocation"; public static final String PREFS_SHOW_COMPASS = "showCompass"; private static final String LOG_TAG = "Custom Maps"; protected DirectedLocationOverlay myLocationOverlay; protected boolean mTrackingMode; Button mTrackingModeButton; float mAzimuthAngleSpeed = 0.0f; private MapView mapView; private Button saveButton; private ImageButton mapModeButton; private SeekBar transparencyBar; private WarpedImageOverlay imageOverlay; private Matrix imageToGeo; private IGeoPoint mapImageCenter; private List<IGeoPoint> imageCornerGeoPoints; private int latSpanE6; private int lonSpanE6; private SharedPreferences mPrefs; private MyLocationNewOverlay mLocationOverlay; private CompassOverlay mCompassOverlay; private MinimapOverlay mMinimapOverlay; private ScaleBarOverlay mScaleBarOverlay; private ResourceProxy mResourceProxy; private HelpDialogManager helpDialogManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.requestWindowFeature(Window.FEATURE_NO_TITLE); Context context = getApplicationContext(); setContentView(R.layout.createpreview); DisplayMetrics dm = getApplicationContext().getResources().getDisplayMetrics(); MapView mapTryView = (MapView) findViewById(R.id.custom_mapview); mapTryView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); // add the mapview to display mapView = mapTryView; mapView.setMaxZoomLevel(20); mapView.setMinZoomLevel(3); mapView.setTileSource(WMSTileSourceFactory.BING_HYBRID); ViewParent p = mapView.getParent(); if (p instanceof ViewGroup) { mapView.setMaxZoomLevel(20); mapView.setMinZoomLevel(3); ViewGroup layout = (ViewGroup) p; LayoutParams layoutParams = mapView.getLayoutParams(); try { mPrefs = getSharedPreferences(PREFS_NAME, MODE_PRIVATE); layout.removeView(mapView); layout.addView(mapView, layoutParams); this.mLocationOverlay = new MyLocationNewOverlay(context, new GpsMyLocationProvider(context), mapView); mScaleBarOverlay = new ScaleBarOverlay(context); mScaleBarOverlay.setCentred(true); mScaleBarOverlay.setScaleBarOffset(dm.widthPixels / 2, 10); mapView.setBuiltInZoomControls(true); mapView.setMultiTouchControls(true); mapView.getController().setZoom(mPrefs.getInt(PREFS_ZOOM_LEVEL, 5)); mapView.scrollTo(mPrefs.getInt(PREFS_SCROLL_X, 0), mPrefs.getInt(PREFS_SCROLL_Y, 0)); mLocationOverlay.enableMyLocation(); } catch (IllegalArgumentException ex) { Log.e(CustomMaps.LOG_TAG, "Failed to create a map matching the signature key"); Button saveButton = (Button) findViewById(R.id.save); saveButton.setEnabled(false); return; } } prepareUI(); if (PtSizeFixer.isFixNeeded((Activity) null)) { PtSizeFixer.fixView(saveButton.getRootView()); } mapView.setBuiltInZoomControls(true); // Create overlay String fileName = getIntent().getStringExtra(BITMAP_FILE); Bitmap mapImage = ImageHelper.loadImage(fileName, true); if (mapImage == null) { // Failed to load image, cancel activity Toast.makeText(this, R.string.editor_image_load_failed, Toast.LENGTH_LONG).show(); setResult(RESULT_CANCELED); finish(); return; } imageOverlay = new WarpedImageOverlay(context, mapImage); List<Point> imagePoints; imagePoints = new ArrayList<Point>(); int[] imagePointArray = getIntent().getIntArrayExtra(IMAGE_POINTS); for (int i = 0; i + 1 < imagePointArray.length; i += 2) { imagePoints.add(new Point(imagePointArray[i], imagePointArray[i + 1])); } List<IGeoPoint> geoPoints = new ArrayList<IGeoPoint>(); int[] geoPointArray = getIntent().getIntArrayExtra(TIEPOINTS); for (int i = 0; i + 1 < geoPointArray.length; i += 2) { geoPoints.add(new GeoPoint(geoPointArray[i], geoPointArray[i + 1])); } imageOverlay.setTiepoints(imagePoints, geoPoints); mapView.getOverlays().add(imageOverlay); transparencyBar.setProgress(50); imageOverlay.setTransparency(50); helpDialogManager = new HelpDialogManager(this, HelpDialogManager.HELP_PREVIEW_CREATE, getString(R.string.preview_help)); // Compute geo location of map image center if (!imageOverlay.computeImageWarp(mapView)) { mapImageCenter = mapView.getMapCenter(); //TODO Changed to IGeoPoint on the variable latSpanE6 = mapView.getLatitudeSpan(); lonSpanE6 = mapView.getLongitudeSpan(); return; } // Get matrix for converting image points to geo points imageToGeo = new Matrix(); imageToGeo.set(imageOverlay.computeImageToGeoMatrix(mapView)); // Convert center point to geo Point center = new Point(mapImage.getWidth() / 2, mapImage.getHeight() / 2); mapImageCenter = imageToGeoPoint(imageToGeo, center); // Find lat and lon spans computeImageCornerGeoPoints(); int minLatE6 = Integer.MAX_VALUE; int maxLatE6 = Integer.MIN_VALUE; int minLonE6 = Integer.MAX_VALUE; int maxLonE6 = Integer.MIN_VALUE; for (IGeoPoint gp : imageCornerGeoPoints) { minLatE6 = Math.min(minLatE6, gp.getLatitudeE6()); maxLatE6 = Math.max(maxLatE6, gp.getLatitudeE6()); minLonE6 = Math.min(minLonE6, gp.getLongitudeE6()); maxLonE6 = Math.max(maxLonE6, gp.getLongitudeE6()); } latSpanE6 = maxLatE6 - minLatE6; lonSpanE6 = maxLonE6 - minLonE6; } @Override protected void onResume() { super.onResume(); if (mapView != null) { mapView.getController().setCenter(mapImageCenter); mapView.getController().zoomToSpan(latSpanE6, lonSpanE6); helpDialogManager.onResume(); } if (mPrefs.getBoolean(PREFS_SHOW_LOCATION, false)) { this.mLocationOverlay.enableMyLocation(); } } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); if (imageOverlay != null) { imageOverlay.setTransparency(transparencyBar.getProgress()); helpDialogManager.onRestoreInstanceState(savedInstanceState); } } @Override protected void onSaveInstanceState(Bundle outState) { if (helpDialogManager != null) { helpDialogManager.onSaveInstanceState(outState); } super.onSaveInstanceState(outState); } public void computeAndReturnTiepoints() { if (imageToGeo == null) { imageOverlay.computeImageWarp(mapView); imageToGeo = imageOverlay.computeImageToGeoMatrix(mapView); computeImageCornerGeoPoints(); } int[] cornerGeoPoints = new int[8]; int i = 0; for (IGeoPoint gp : imageCornerGeoPoints) { cornerGeoPoints[i++] = gp.getLatitudeE6(); cornerGeoPoints[i++] = gp.getLongitudeE6(); } Intent result = getIntent(); result.putExtra(CORNER_GEO_POINTS, cornerGeoPoints); setResult(RESULT_OK, result); mLocationOverlay.disableMyLocation(); mapView.setMultiTouchControls(false); finish(); } @Override protected void onPause() { if (helpDialogManager != null) { helpDialogManager.onPause(); } if (isFinishing() && imageOverlay != null) { Bitmap image = imageOverlay.getImage(); if (image != null && !image.isRecycled()) { image.recycle(); imageOverlay.setImage(null); } } super.onPause(); } @Override public boolean onCreateOptionsMenu(Menu menu) { return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { return true; } @Override protected Dialog onCreateDialog(int id) { return helpDialogManager.onCreateDialog(id); } @Override protected void onPrepareDialog(int id, Dialog dialog) { helpDialogManager.onPrepareDialog(id, dialog); } // -------------------------------------------------------------------------- // Image overlay helper methods private void computeImageCornerGeoPoints() { Bitmap mapImage = imageOverlay.getImage(); // List corners starting from lower left going counter clockwise List<Point> corners = new ArrayList<Point>(); corners.add(new Point(0, mapImage.getHeight())); corners.add(new Point(mapImage.getWidth(), mapImage.getHeight())); corners.add(new Point(mapImage.getWidth(), 0)); corners.add(new Point(0, 0)); // Convert to geo points imageCornerGeoPoints = new ArrayList<IGeoPoint>(); for (Point pt : corners) { IGeoPoint geoPoint = imageToGeoPoint(imageToGeo, pt); imageCornerGeoPoints.add(geoPoint); } } private IGeoPoint imageToGeoPoint(Matrix converter, Point imagePoint) { float[] coords = new float[] { imagePoint.x, imagePoint.y }; converter.mapPoints(coords); return new GeoPoint(Math.round(coords[1] * 1E6f), Math.round(coords[0] * 1E6f)); } void updateUIWithTrackingMode() { if (mTrackingMode) { mTrackingModeButton.setBackgroundResource(R.drawable.btn_tracking_on); if (myLocationOverlay.isEnabled() && myLocationOverlay.getLocation() != null) { mapView.getController().animateTo(myLocationOverlay.getLocation()); } mapView.setMapOrientation(-mAzimuthAngleSpeed); mTrackingModeButton.setKeepScreenOn(true); } else { mTrackingModeButton.setBackgroundResource(R.drawable.btn_tracking_off); mapView.setMapOrientation(0.0f); mTrackingModeButton.setKeepScreenOn(false); } } // -------------------------------------------------------------------------- // Prepare UI elements private void prepareUI() { saveButton = (Button) findViewById(R.id.save); mapModeButton = (ImageButton) findViewById(R.id.mapmode); transparencyBar = (SeekBar) findViewById(R.id.transparencyBar); saveButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { computeAndReturnTiepoints(); } }); mapModeButton.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { PopupMenu popupMenu = new PopupMenu(getApplicationContext(), view); popupMenu.inflate(R.menu.menu_options); popupMenu.show(); popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { switch (item.toString()) { case "Google Satellite": mapView.invalidate(); mapView.setMaxZoomLevel(20); mapView.setMinZoomLevel(3); mapView.setTileSource(WMSTileSourceFactory.GOOGLE_SATELLITE); break; case "Google Maps": mapView.invalidate(); mapView.setMaxZoomLevel(20); mapView.setMinZoomLevel(3); mapView.setTileSource(WMSTileSourceFactory.GOOGLE_MAPS); break; case "Google Terrain": mapView.invalidate(); mapView.setMaxZoomLevel(20); mapView.setMinZoomLevel(3); mapView.setTileSource(WMSTileSourceFactory.GOOGLE_TERRAIN); break; case "Bing Maps": mapView.invalidate(); mapView.setMaxZoomLevel(20); mapView.setMinZoomLevel(3); mapView.setTileSource(WMSTileSourceFactory.BING_MAPS); break; case "Bing Earth": mapView.invalidate(); mapView.setMaxZoomLevel(20); mapView.setMinZoomLevel(3); mapView.setTileSource(WMSTileSourceFactory.BING_EARTH); break; case "Bing Hybrid": mapView.invalidate(); mapView.setMaxZoomLevel(20); mapView.setMinZoomLevel(3); mapView.setTileSource(WMSTileSourceFactory.BING_HYBRID); break; case "Mapquest Aerial": mapView.invalidate(); mapView.setMaxZoomLevel(20); mapView.setMinZoomLevel(3); mapView.setTileSource(WMSTileSourceFactory.MAPQUESTAERIAL_US); break; case "Mapquest OSM": mapView.invalidate(); mapView.setMaxZoomLevel(20); mapView.setMinZoomLevel(3); mapView.setTileSource(WMSTileSourceFactory.MAPQUESTOSM); break; case "Mapnik": mapView.invalidate(); mapView.setMaxZoomLevel(20); mapView.setMinZoomLevel(3); mapView.setTileSource(WMSTileSourceFactory.MAPNIK); break; } return false; } }); } }); transparencyBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { private void updateImageOverlay(int value) { imageOverlay.setTransparency(value); mapView.invalidate(); } @Override public void onStopTrackingTouch(SeekBar seekBar) { updateImageOverlay(seekBar.getProgress()); } @Override public void onStartTrackingTouch(SeekBar seekBar) { updateImageOverlay(seekBar.getProgress()); } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if (fromUser) { updateImageOverlay(seekBar.getProgress()); } } }); } }