Java tutorial
/* * Copyright (C) 2012 The Android Open Source Project * * 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 com.example.map; import android.graphics.Point; import android.os.Bundle; import android.os.Handler; import android.os.SystemClock; import android.support.v4.app.FragmentActivity; import android.view.animation.Interpolator; import android.view.animation.LinearInterpolator; import com.example.db.Contact; import com.example.db.DatabaseHandler; import com.example.listview.R; import com.google.android.gms.maps.CameraUpdate; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.GoogleMapOptions; import com.google.android.gms.maps.Projection; import com.google.android.gms.maps.SupportMapFragment; import com.google.android.gms.maps.model.BitmapDescriptorFactory; import com.google.android.gms.maps.model.CameraPosition; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.LatLngBounds; import com.google.android.gms.maps.model.Marker; import com.google.android.gms.maps.model.MarkerOptions; import java.text.DecimalFormat; import java.util.HashMap; import java.util.List; import java.util.Map; /** * This shows how to create a simple activity with a map and a marker on the map. * <p/> * Notice how we deal with the possibility that the Google Play services APK is not * installed/enabled/updated on a user's device. */ public class BasicMapActivity extends FragmentActivity { /** * Note that this may be null if the Google Play services APK is not available. */ private GoogleMap mMap; private SupportMapFragment mMapFragment; DatabaseHandler mDb; List<Contact> mContacts; CameraUpdate cu; Map<Integer, Marker> markers; Map<Marker, Contact> markerContacts; Marker me; static DecimalFormat DIST_FORMAT = new DecimalFormat("#.#"); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.map); mDb = new DatabaseHandler(this); init(); if (savedInstanceState == null) setUpMapIfNeeded(); } @Override protected void onResume() { super.onResume(); //retrieve fragment mMapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_container); if (mMapFragment != null) { mMap = mMapFragment.getMap(); mMap.setMyLocationEnabled(true); mMap.setInfoWindowAdapter(new PopupAdapter(getLayoutInflater())); LatLngBounds.Builder builder = new LatLngBounds.Builder(); if (markers == null) { markers = new HashMap<Integer, Marker>(); markerContacts = new HashMap<Marker, Contact>(); for (Contact place : mContacts) { Marker marker = mMap.addMarker(new MarkerOptions() .position(new LatLng(place.getLat(), place.getLon())).title(place.getName()) .snippet(place.getAddress()) .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE))); markers.put(place.getId(), marker); markerContacts.put(marker, place); builder.include(marker.getPosition()); } LatLngBounds bounds = builder.build(); cu = CameraUpdateFactory.newLatLngBounds(bounds, 20); boolean post = mMapFragment.getView().post(new Runnable() { @Override public void run() { mMap.animateCamera(cu); me = mMap.addMarker(new MarkerOptions().position(mMap.getCameraPosition().target) .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ROSE))); } }); } mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() { @Override public boolean onMarkerClick(Marker marker) { Contact place = markerContacts.get(marker); if (place != null) { marker.setSnippet(place.getAddress()); marker.showInfoWindow(); return true; } return false; } }); mMap.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() { @Override public void onCameraChange(final CameraPosition cameraPosition) { me.setPosition(cameraPosition.target); double lat = cameraPosition.target.latitude; double lon = cameraPosition.target.longitude; mContacts = mDb.getContactByDist(lat, lon, 5); for (Marker marker : markers.values()) { marker.setVisible(false); } //add new markers within set distance for (Contact place : mContacts) { double lat2 = place.getLat(); double lon2 = place.getLon(); double distance = hdistance(Math.toRadians(lat), Math.toRadians(lon), Math.toRadians(lat2), Math.toRadians(lon2)); Marker marker = markers.get(place.getId()); marker.setSnippet(DIST_FORMAT.format(distance) + " km away"); marker.setVisible(true); } if (mContacts.size() > 0) markers.get(mContacts.get(0).getId()).showInfoWindow(); } }); //.icon(BitmapDescriptorFactory.fromResource(R.drawable.android_platform))); } } public void animateMarker(final Marker marker, final LatLng toPosition, final boolean hideMarker) { final Handler handler = new Handler(); final long start = SystemClock.uptimeMillis(); Projection proj = mMap.getProjection(); Point startPoint = proj.toScreenLocation(marker.getPosition()); final LatLng startLatLng = proj.fromScreenLocation(startPoint); final long duration = 500; final Interpolator interpolator = new LinearInterpolator(); handler.post(new Runnable() { @Override public void run() { long elapsed = SystemClock.uptimeMillis() - start; float t = interpolator.getInterpolation((float) elapsed / duration); double lng = t * toPosition.longitude + (1 - t) * startLatLng.longitude; double lat = t * toPosition.latitude + (1 - t) * startLatLng.latitude; marker.setPosition(new LatLng(lat, lng)); if (t < 1.0) { // Post again 16ms later. handler.postDelayed(this, 16); } else { if (hideMarker) { marker.setVisible(false); } else { marker.setVisible(true); } } } }); } private double hdistance(double lat, double lon, double lat2, double lon2) { final double EARTH_RADIUS = 6367.45; //km double deltaLat = lat2 - lat; double deltaLon = lon2 - lon; double a = Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2) + Math.cos(lat) * Math.cos(lat2) * Math.sin(deltaLon / 2) * Math.sin(deltaLon / 2); double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); return EARTH_RADIUS * c; } /** * Sets up the map if it is possible to do so (i.e., the Google Play services APK is correctly * installed) and the map has not already been instantiated.. This will ensure that we only ever * call {@link #setUpMap()} once when {@link #mMap} is not null. * <p/> * If it isn't installed {@link SupportMapFragment} (and * {@link com.google.android.gms.maps.MapView MapView}) will show a prompt for the user to * install/update the Google Play services APK on their device. * <p/> * A user can return to this FragmentActivity after following the prompt and correctly * installing/updating/enabling the Google Play services. Since the FragmentActivity may not have been * completely destroyed during this process (it is likely that it would only be stopped or * paused), {@link #onCreate(android.os.Bundle)} may not be called again so we should call this method in * {@link #onResume()} to guarantee that it will be called. */ private void setUpMapIfNeeded() { GoogleMapOptions options = new GoogleMapOptions(); options.mapType(GoogleMap.MAP_TYPE_NORMAL).compassEnabled(true).rotateGesturesEnabled(false) .tiltGesturesEnabled(false); mMapFragment = SupportMapFragment.newInstance(options); getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, mMapFragment, "map").commit(); } /** * This is where we can add markers or lines, add listeners or move the camera. In this case, we * just add a marker near Africa. * <p/> * This should only be called once and when we are sure that {@link #mMap} is not null. */ private void setUpMap() { } private void init() { mContacts = mDb.getAllContacts(); } }