/* 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.mapdemo; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.GoogleMap.OnMapLongClickListener; import com.google.android.gms.maps.GoogleMap.OnMarkerDragListener; import com.google.android.gms.maps.SupportMapFragment; import com.google.android.gms.maps.model.BitmapDescriptorFactory; import com.google.android.gms.maps.model.Circle; import com.google.android.gms.maps.model.CircleOptions; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.Marker; import com.google.android.gms.maps.model.MarkerOptions; import android.graphics.Color; import android.graphics.Point; import android.location.Location; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.view.View; import android.widget.SeekBar; import android.widget.SeekBar.OnSeekBarChangeListener; import java.util.ArrayList; import java.util.List; /** * This shows how to draw circles on a map. */ public class CircleDemoActivity extends FragmentActivity implements OnSeekBarChangeListener, OnMarkerDragListener, OnMapLongClickListener { private static final LatLng SYDNEY = new LatLng(-33.87365, 151.20689); private static final double DEFAULT_RADIUS = 1000000; public static final double RADIUS_OF_EARTH_METERS = 6371009; private static final int WIDTH_MAX = 50; private static final int HUE_MAX = 360; private static final int ALPHA_MAX = 255; private GoogleMap mMap; private List<DraggableCircle> mCircles = new ArrayList<DraggableCircle>(1); private SeekBar mColorBar; private SeekBar mAlphaBar; private SeekBar mWidthBar; private int mStrokeColor; private int mFillColor; private class DraggableCircle { private final Marker centerMarker; private final Marker radiusMarker; private final Circle circle; private double radius; public DraggableCircle(LatLng center, double radius) { this.radius = radius; centerMarker = mMap.addMarker(new MarkerOptions() .position(center) .draggable(true)); radiusMarker = mMap.addMarker(new MarkerOptions() .position(toRadiusLatLng(center, radius)) .draggable(true) .icon(BitmapDescriptorFactory.defaultMarker( BitmapDescriptorFactory.HUE_AZURE))); circle = mMap.addCircle(new CircleOptions() .center(center) .radius(radius) .strokeWidth(mWidthBar.getProgress()) .strokeColor(mStrokeColor) .fillColor(mFillColor)); } public DraggableCircle(LatLng center, LatLng radiusLatLng) { this.radius = toRadiusMeters(center, radiusLatLng); centerMarker = mMap.addMarker(new MarkerOptions() .position(center) .draggable(true)); radiusMarker = mMap.addMarker(new MarkerOptions() .position(radiusLatLng) .draggable(true) .icon(BitmapDescriptorFactory.defaultMarker( BitmapDescriptorFactory.HUE_AZURE))); circle = mMap.addCircle(new CircleOptions() .center(center) .radius(radius) .strokeWidth(mWidthBar.getProgress()) .strokeColor(mStrokeColor) .fillColor(mFillColor)); } public boolean onMarkerMoved(Marker marker) { if (marker.equals(centerMarker)) { circle.setCenter(marker.getPosition()); radiusMarker.setPosition(toRadiusLatLng(marker.getPosition(), radius)); return true; } if (marker.equals(radiusMarker)) { radius = toRadiusMeters(centerMarker.getPosition(), radiusMarker.getPosition()); circle.setRadius(radius); return true; } return false; } public void onStyleChange() { circle.setStrokeWidth(mWidthBar.getProgress()); circle.setFillColor(mFillColor); circle.setStrokeColor(mStrokeColor); } } /** Generate LatLng of radius marker */ private static LatLng toRadiusLatLng(LatLng center, double radius) { double radiusAngle = Math.toDegrees(radius / RADIUS_OF_EARTH_METERS) / Math.cos(Math.toRadians(center.latitude)); return new LatLng(center.latitude, center.longitude + radiusAngle); } private static double toRadiusMeters(LatLng center, LatLng radius) { float[] result = new float[1]; Location.distanceBetween(center.latitude, center.longitude, radius.latitude, radius.longitude, result); return result[0]; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.circle_demo); mColorBar = (SeekBar) findViewById(R.id.hueSeekBar); mColorBar.setMax(HUE_MAX); mColorBar.setProgress(0); mAlphaBar = (SeekBar) findViewById(R.id.alphaSeekBar); mAlphaBar.setMax(ALPHA_MAX); mAlphaBar.setProgress(127); mWidthBar = (SeekBar) findViewById(R.id.widthSeekBar); mWidthBar.setMax(WIDTH_MAX); mWidthBar.setProgress(10); setUpMapIfNeeded(); } @Override protected void onResume() { super.onResume(); setUpMapIfNeeded(); } private void setUpMapIfNeeded() { // Do a null check to confirm that we have not already instantiated the map. if (mMap == null) { // Try to obtain the map from the SupportMapFragment. mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)) .getMap(); // Check if we were successful in obtaining the map. if (mMap != null) { setUpMap(); } } } private void setUpMap() { mColorBar.setOnSeekBarChangeListener(this); mAlphaBar.setOnSeekBarChangeListener(this); mWidthBar.setOnSeekBarChangeListener(this); mMap.setOnMarkerDragListener(this); mMap.setOnMapLongClickListener(this); mFillColor = Color.HSVToColor( mAlphaBar.getProgress(), new float[] {mColorBar.getProgress(), 1, 1}); mStrokeColor = Color.BLACK; DraggableCircle circle = new DraggableCircle(SYDNEY, DEFAULT_RADIUS); mCircles.add(circle); // Move the map so that it is centered on the initial circle mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(SYDNEY, 4.0f)); } @Override public void onStopTrackingTouch(SeekBar seekBar) { // Don't do anything here. } @Override public void onStartTrackingTouch(SeekBar seekBar) { // Don't do anything here. } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if (seekBar == mColorBar) { mFillColor = Color.HSVToColor(Color.alpha(mFillColor), new float[] {progress, 1, 1}); } else if (seekBar == mAlphaBar) { mFillColor = Color.argb(progress, Color.red(mFillColor), Color.green(mFillColor), Color.blue(mFillColor)); } for (DraggableCircle draggableCircle : mCircles) { draggableCircle.onStyleChange(); } } @Override public void onMarkerDragStart(Marker marker) { onMarkerMoved(marker); } @Override public void onMarkerDragEnd(Marker marker) { onMarkerMoved(marker); } @Override public void onMarkerDrag(Marker marker) { onMarkerMoved(marker); } private void onMarkerMoved(Marker marker) { for (DraggableCircle draggableCircle : mCircles) { if (draggableCircle.onMarkerMoved(marker)) { break; } } } @Override public void onMapLongClick(LatLng point) { // We know the center, let's place the outline at a point 3/4 along the view. View view = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)) .getView(); LatLng radiusLatLng = mMap.getProjection().fromScreenLocation(new Point( view.getHeight() * 3 / 4, view.getWidth() * 3 / 4)); // ok create it DraggableCircle circle = new DraggableCircle(point, radiusLatLng); mCircles.add(circle); } }