Back to project page geoar-app.
The source code is released under:
Apache License
If you think the Android project geoar-app listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
/** * Copyright 2012 52North Initiative for Geospatial Open Source Software GmbH *//from w w w . java2 s .co m * 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 org.n52.geoar.map.view; import java.util.HashMap; import java.util.Map; import org.mapsforge.android.maps.MapController; import org.mapsforge.android.maps.mapgenerator.tiledownloader.MapnikTileDownloader; import org.mapsforge.android.maps.overlay.ArrayCircleOverlay; import org.mapsforge.android.maps.overlay.OverlayCircle; import org.mapsforge.core.GeoPoint; import org.n52.geoar.R; import org.n52.geoar.map.view.GeoARMapView.OnZoomChangeListener; import org.n52.geoar.map.view.overlay.DataSourcesOverlay; import org.n52.geoar.map.view.overlay.DataSourcesOverlay.OnOverlayItemTapListener; import org.n52.geoar.map.view.overlay.OverlayType; import org.n52.geoar.newdata.CheckList; import org.n52.geoar.newdata.CheckList.OnCheckedChangedListener; import org.n52.geoar.newdata.DataSourceHolder; import org.n52.geoar.newdata.DataSourceInstanceHolder; import org.n52.geoar.newdata.PluginActivityContext; import org.n52.geoar.newdata.PluginLoader; import org.n52.geoar.tracking.location.LocationHandler; import org.n52.geoar.tracking.location.LocationHandler.OnLocationUpdateListener; import android.annotation.SuppressLint; import android.app.AlertDialog; import android.app.AlertDialog.Builder; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.Style; import android.location.Location; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.view.Gravity; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.View.OnLayoutChangeListener; import android.view.View.OnTouchListener; import android.view.ViewGroup; import android.widget.FrameLayout.LayoutParams; import com.actionbarsherlock.app.SherlockFragment; import com.actionbarsherlock.view.MenuItem; import com.vividsolutions.jts.geom.Geometry; /** * * @author Arne de Wall <a.dewall@52North.org> * */ public class MapFragment extends SherlockFragment { private GeoARMapView mapView; private MapActivityContext mapActivity; // Special context to use MapView // without MapActivity private LocationOverlay locationOverlay; // Overlay fields private Map<DataSourceInstanceHolder, DataSourceOverlayHandler> overlayHandlerMap; private DataSourcesOverlay dataSourcesOverlay; // Listener for data source enabled state private OnCheckedChangedListener<DataSourceInstanceHolder> dataSourceListener = new OnCheckedChangedListener<DataSourceInstanceHolder>() { @Override public void onCheckedChanged(DataSourceInstanceHolder item, boolean newState) { if (newState == true && !overlayHandlerMap.containsKey(item)) { // new data source selected -> add new overlay handler DataSourceOverlayHandler overlayHandler = new DataSourceOverlayHandler( dataSourcesOverlay, item); overlayHandlerMap.put(item, overlayHandler); overlayHandler.updateOverlay(mapView, true); } else if (newState == false) { // data source disabled -> remove corresponding overlay handler DataSourceOverlayHandler overlayHandler = overlayHandlerMap .remove(item); if (overlayHandler != null) { overlayHandler.destroy(); } } } }; @Override public void onCreate(Bundle savedInstanceState) { setHasOptionsMenu(true); super.onCreate(savedInstanceState); } @Override public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) { return inflater.inflate(R.layout.map_fragment, container, false); } @SuppressLint("NewApi") @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); // Add MapView programmatically, since it needs a special context // depending on a call to getActivity, so it happens here and not in // onCreateView. System.gc(); mapActivity = new MapActivityContext(getActivity()); mapView = new GeoARMapView(mapActivity); // Offline rendering here // setMapFile(new File(Environment.getExternalStorageDirectory() // + "/GeoAR/map.map")); mapView.setClickable(true); // setRenderTheme(DEFAULT_RENDER_THEME); mapView.setMapGenerator(new MapnikTileDownloader()); mapView.setBuiltInZoomControls(true); mapView.getMapZoomControls().setZoomControlsGravity( Gravity.LEFT | Gravity.TOP); // controller.setZoom(15); // controller.setCenter(new GeoPoint(51.965344, 7.600003)); // // Coesfelder // Kreuz // LocationHandler.setManualLocation(new GeoLocation(51.965344, // 7.600003)); // Data source handling overlayHandlerMap = new HashMap<DataSourceInstanceHolder, DataSourceOverlayHandler>(); dataSourcesOverlay = new DataSourcesOverlay(); dataSourcesOverlay .setOverlayItemTapListener(new OnOverlayItemTapListener() { @Override public boolean onOverlayItemTap( OverlayType<? extends Geometry> item) { Builder builder = new AlertDialog.Builder(getActivity()); builder.setTitle(item.getTitle()) .setMessage(item.getDescription()) .setNeutralButton(R.string.cancel, null); PluginActivityContext pluginActivityContext = new PluginActivityContext(item.getDataSourceInstance() .getParent().getPluginHolder() .getPluginContext(), getActivity()); // TODO use view caching with convertView parameter View featureView = item.getVisualization() .getFeatureView(item.getSpatialEntity(), null, null, pluginActivityContext); if (featureView != null) { builder.setView(featureView); } builder.show(); return true; } }); mapView.getOverlays().add(dataSourcesOverlay); mapView.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View arg0, MotionEvent motionEvent) { // Use motion event to inform overlay handlers that they // should update their data if needed if (motionEvent.getAction() == MotionEvent.ACTION_UP || motionEvent.getAction() == MotionEvent.ACTION_CANCEL) { updateOverlays(); } return false; } }); mapView.setOnZoomChangeListener(new OnZoomChangeListener() { @Override public void onZoomChange() { updateOverlays(); } }); // Get Layout root ViewGroup layout = (ViewGroup) getView(); layout.addView(mapView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); layout.requestLayout(); // add overlay handler for each enabled data source for (DataSourceHolder dataSource : PluginLoader.getDataSources()) { CheckList<DataSourceInstanceHolder> instances = dataSource .getInstances(); for (DataSourceInstanceHolder instance : instances .getCheckedItems()) { DataSourceOverlayHandler overlayHandler = new DataSourceOverlayHandler( dataSourcesOverlay, instance); overlayHandlerMap.put(instance, overlayHandler); } // register for update events instances.addOnCheckedChangeListener(dataSourceListener); } if (Build.VERSION.SDK_INT >= 11) { // use layout change listener to get notified when mapview is // layouted and has valid projection information mapView.addOnLayoutChangeListener(new OnLayoutChangeListener() { @SuppressLint("NewApi") @Override public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { if (oldRight != right || oldBottom != bottom || oldTop != top || oldLeft != left) { // View layouted first time -> update overlays, // projection // will be valid updateOverlays(); mapView.removeOnLayoutChangeListener(this); } } }); } else { // Fallback for older Versions, update after timeout new Handler().postDelayed(new Runnable() { @Override public void run() { } }, 2000); } } private void showOwnLocation() { if (locationOverlay == null) { locationOverlay = new LocationOverlay(); mapView.getOverlays().add(locationOverlay); } OnLocationUpdateListener updateListener = new OnLocationUpdateListener() { @Override public void onLocationChanged(Location location) { GeoPoint center = new GeoPoint(location.getLatitude(), location.getLongitude()); locationOverlay.setLocation(center, location.hasAccuracy() ? location.getAccuracy() : 50); mapView.getController().setZoom(16); mapView.getController().setCenter(center); } }; LocationHandler.getSingleLocation(updateListener, 5000); // TODO lock while getting position Location lastKnownLocation = LocationHandler.getLastKnownLocation(); if (lastKnownLocation != null) { updateListener.onLocationChanged(lastKnownLocation); } } private void updateOverlays() { for (DataSourceOverlayHandler handler : overlayHandlerMap.values()) { handler.updateOverlay(mapView, false); } } @Override public void onCreateOptionsMenu(com.actionbarsherlock.view.Menu menu, com.actionbarsherlock.view.MenuInflater inflater) { inflater.inflate(R.menu.menu_map, menu); super.onCreateOptionsMenu(menu, inflater); } @Override public void onDestroy() { for (DataSourceHolder dataSource : PluginLoader.getDataSources()) { dataSource.getInstances().removeOnCheckedChangeListener( dataSourceListener); } for (DataSourceOverlayHandler handler : overlayHandlerMap.values()) { handler.destroy(); } overlayHandlerMap.clear(); super.onDestroy(); } @Override public void onDestroyView() { mapActivity.destroy(); ((ViewGroup) getView()).removeView(mapView); dataSourcesOverlay.clear(); super.onDestroyView(); } @Override public void onPause() { mapActivity.pause(); for (DataSourceOverlayHandler handler : overlayHandlerMap.values()) { handler.cancel(); } super.onPause(); } @Override public void onResume() { mapActivity.resume(); if (!mapView.getMapPosition().isValid()) { MapController controller = mapView.getController(); controller.setZoom(15); controller.setCenter(new GeoPoint(51.935008, 7.652111)); // 52N } super.onResume(); } @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == R.id.item_ownlocation) { showOwnLocation(); return true; } return super.onOptionsItemSelected(item); } private class LocationOverlay extends ArrayCircleOverlay { private OverlayCircle locationCircle; public LocationOverlay() { super(null, null); Paint paintLocationFill = new Paint(); paintLocationFill.setStyle(Style.FILL); paintLocationFill.setColor(Color.BLUE); paintLocationFill.setAlpha(120); paintLocationFill.setAntiAlias(true); Paint paintLocationOutline = new Paint(); paintLocationOutline.setStyle(Style.STROKE); paintLocationOutline.setColor(Color.BLUE); paintLocationOutline.setAlpha(200); paintLocationOutline.setAntiAlias(true); locationCircle = new OverlayCircle(paintLocationFill, paintLocationOutline); addCircle(locationCircle); } public void setLocation(GeoPoint center, float radius) { locationCircle.setCircleData(center, radius); requestRedraw(); } } }