i am really stuck on this:
I have longitude / latitude points to draw on a google map within an android app.
Therefor I created a class extending Overlay...
I get the current longitude/latitude portion of view via:
GeoPoint topLeft = proj.fromPixels(0, 0);
GeoPoint bottomRight = proj.fromPixels(width-1, height-1);
int topLat = topLeft.getLatitudeE6();
int topLon = topLeft.getLongitudeE6();
int bottomLat = bottomRight.getLatitudeE6();
int bottomLon = bottomRight.getLongitudeE6();
The following works (only latitudes):
if(latLon[0] >= bottomLat && latLon[0] <= topLat){ // do something; }
but this does not work (longitudes):
if(latLon[1] >= topLon && latLon[1] <= bottomLon) { // do something; }
latLon[0] is the latitude I want to check
latLon[1] is the longitude I want to check
Anybody an idea?
Greetz!
Longitude numbers are negative from the 0 meridian in England, westward. They're negative in North America and South America.
Use a google map and insert your marker on it.
See below :
public class MapActivity extends GeolocationActivity implements GoogleMap.OnInfoWindowClickListener{
private final String TAG = "MapFragment";
private MapView _mapView;
private GoogleMap _gmap;
/**
* the logo of the marker on the map
*/
private Bitmap _littlePin;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.map);
_mapView = (MapView) findViewById(R.id.location_map);
_mapView.onCreate(savedInstanceState);
_gmap = _mapView.getMap(); // initalise the map
if (_gmap != null)
{
setUpMap();
}
}
/**
* set up the map; Add the market on it with a blue dot for the location of the user in real time
* #return false if something goes wrong, true otherwise
* _latitude = latitude of the user, get from the GeolocationActivity
* _longitude = longitude of the user, get from the GeolocationActivity
*/
private boolean setUpMap()
{
// Gets to GoogleMap from the MapView and does initialization stuff
_gmap.getUiSettings().setMyLocationButtonEnabled(false);
_gmap.setMyLocationEnabled(true);
if (_gmap == null) {
Toast.makeText(this, "Google Maps not available", Toast.LENGTH_LONG).show();
return false;
}
// Needs to call MapsInitializer before doing any CameraUpdateFactory calls
MapsInitializer.initialize(this);
BitmapDrawable bitmapDrawable = (BitmapDrawable) getResources().getDrawable(R.drawable.pin); // file stored in /res/drawable/
Bitmap bitmap = bitmapDrawable.getBitmap();
_littlePin = Bitmap.createScaledBitmap(bitmap, 96, 96, false); // 96/96px
_gmap.setOnInfoWindowClickListener(this);// add listener on this class
// here the _lat and _long should be the user of this cafe, at the moment I am using the one of the user
this.addMarker("Cafe", "Best cafe in London", new LatLng(_latitude, _longitude));
// camera, 13 if the zoon, you can change it manually, or dynamically in order to see all your markers
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(new LatLng(_latitude, _longitude), 13);
_gmap.animateCamera(cameraUpdate); // zoom effect
return true;
}
/**
* Add markers on the map view
* #param title title of place / marker
* #param description short description
* #param position geposition, LatLng object, filled with latitude and longitude.
*/
private void addMarker(String title, String description, LatLng position)
{
_gmap.addMarker(new MarkerOptions()
.position(position)
.title(title)
.snippet(description)
.icon(BitmapDescriptorFactory.fromBitmap(_littlePin)));
}
/**
* The user click on the marker on the map, this callback is called
* #param marker clicked marker
*/
#Override
public void onInfoWindowClick(Marker marker) {
Log.d(TAG, "onMarkerClick " + marker.getTitle());
}
#Override
public void onResume() {
_mapView.onResume();
super.onResume();
}
#Override
public void onDestroy() {
super.onDestroy();
_mapView.onDestroy();
}
#Override
public void onLowMemory() {
super.onLowMemory();
_mapView.onLowMemory();
}
}
Here is a good example which gonna help you.
and the github with the code sample is here.
Hope this help.
Related
When I click somewhere on map, app draw polyline between current location and destination (click). I want that destination marker is clicking by himself all the time (every few seconds), so on user movement new polylines are drawing (updating the last one).
I tried with handler and bunch of the things and didn't find solution.
Any answer would be highly appreciated.
private ArrayList<LatLng> mClickedPoints;
/** Setting onclick listener for the map */
mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
#Override
public void onMapClick(LatLng point) {
/**
* Clearing map if user clicks on map more then one time.
* Reseting View widgets and arrays, adding points of interests
*/
if (mClickedPoints.size() > 1) {
mMap.clear();
mClickedPoints.clear();
mClickedPoints = new ArrayList<>();
}
/** Adding current location to the ArrayList */
mClickedPoints.add(start);
Log.i("current location", start.toString());
MarkerOptions options = new MarkerOptions();
options.position(start);
/** Destination click */
mClickedPoints.add(point);
/** Setting the position of the marker */
options.position(point);
/** Checks if start and end locations are captured */
if (mClickedPoints.size() >= 2) {
orig = mClickedPoints.get(0);
dest = mClickedPoints.get(1);
}
mMap.addMarker(options);
request_directions_and_get_response();
}
});
onLocationChanged() override:
#Override
public void onLocationChanged(Location location) {
mLastLocation = location;
if (mCurrLocationMarker != null) {
mCurrLocationMarker.remove();
}
/** Setting current location marker */
start = new LatLng(location.getLatitude(),location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(start);
markerOptions.title("Current Location");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
mCurrLocationMarker = mMap.addMarker(markerOptions);
}
In order to use the clicked points ArrayList as you have it now, you'll need to remove the previous origin, then add the current origin to the start of the ArrayList, and then get re-calculated directions based on the new current location.
Something like this:
#Override
public void onLocationChanged(Location location) {
mLastLocation = location;
if (mCurrLocationMarker != null) {
mCurrLocationMarker.remove();
}
/** Setting current location marker */
start = new LatLng(location.getLatitude(),location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(start);
markerOptions.title("Current Location");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
mCurrLocationMarker = mMap.addMarker(markerOptions);
//If there is a previous route drawn:
if (mClickedPoints.size() >= 2) {
//remove the old origin:
mClickedPoints.remove(0);
//add the new one at the 0th position:
mClickedPoints.add(0, start);
//set orig and dest for directions:
orig = mClickedPoints.get(0);
dest = mClickedPoints.get(1);
//get updated directions:
request_directions_and_get_response();
}
}
This application purposed to get the distance from 2 points of coordinate. The ways is just to click in the map of the position place that you want to count the distance. But there's problem in the point's start, where the application cannot changes the position place.
this is my code:
public class MapsActivity extends FragmentActivity {
// the Google Map object
private GoogleMap mMap;
//ArrayList markerPoints;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// we set the layout for the Activity
setContentView(R.layout.activity_maps);
// the geocoder is instantiated for the first time
geocoder=new Geocoder(this);
// if there isn't a map, it will be created
setUpMapIfNeeded();
}
// LatLng objects store a pair of terrestrial coordinates (latitude and longitude)
private static LatLng STARTING_MARKER_POSITION =new LatLng(3.099465, 101.717111);
/* distanceFrom indicates the starting point to calculate the distance from.
It's initialized with STARTING_MARKER_POSITION
*/
private LatLng distanceFrom= STARTING_MARKER_POSITION;
// line will be drawn at the click event
private Polyline line=null;
// A Geocoder can transform a pair of latitude/longitude into a street address and viceversa.
// We'll use it in the listener
private static Geocoder geocoder=null;
private GoogleMap.OnMapClickListener clickListener=new GoogleMap.OnMapClickListener() {
#Override
public void onMapClick(final LatLng pos) {
// this method is called when the user taps the map
// if a line already appears, it's removed
if (line!=null)
line.remove();
// a new line is created
line = mMap.addPolyline(new PolylineOptions()
.add(distanceFrom, pos)
.width(9) // width of the line
.color(Color.BLUE)); // line color
// call the converter object for geocoding invocation and distance calculation
new AddressConverter().execute(distanceFrom, pos);
}
};
#Override
protected void onResume() {
super.onResume();
// the availability of the GoogleMap will be checked before the Activity starts interacting with the user
setUpMapIfNeeded();
}
private void setUpMapIfNeeded() {
// the map is created only it has not been initialized
if (mMap == null) {
// the map is located in the layout
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
// if a map exists, we proceed with initialization
if (mMap != null) {
setUpMap();
}
}
}
// Now it's time to configure the map. We can add markers, shapes, event handlers and so on
private void setUpMap() {
// the camera will be positioned according to the new coordinates
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(STARTING_MARKER_POSITION, 14));
// we choose the type of the map: Satellite in this case
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
// markerOptions describes the marker we want to place
MarkerOptions markerOptions=new MarkerOptions()
.position(STARTING_MARKER_POSITION)
.draggable(true);
// the marker has to be draggable as we'll move it
// the marker is rendered on the map
mMap.addMarker(markerOptions);
// we define the object to invoke when the marker is dragged
mMap.setOnMarkerDragListener(new GoogleMap.OnMarkerDragListener()
{
#Override
public void onMarkerDragStart(Marker arg0)
{
// this method is called when the drag starts
// the operation we need is the cancellation of a preexisting line
if (line!=null)
line.remove();
}
#Override
public void onMarkerDragEnd(final Marker pos)
{
// we get the final position of the marker
distanceFrom=pos.getPosition();
}
#Override
public void onMarkerDrag(Marker arg0)
{
// operations performed during the movement. Nothing to do
}
});
// the callback to invoke is set
mMap.setOnMapClickListener(clickListener);
}
// we want to know which address corresponds to this location
// we use AsyncTask to perform slower operations on a separate thread
private class AddressConverter extends AsyncTask<LatLng,Void,String>
{
// The ProgressDialog window we'll show during the calculation
private ProgressDialog progress=null;
// this method is called before the background job starts. It works on the main thread
#Override
protected void onPreExecute() {
// ProgressDialog is shown
progress= ProgressDialog.show(MapsActivity.this,"Distance calculator","We are calcultating the distance...", true,false);
}
// this method works on a separate thread
// it performs geocoding operations to retrieve the address of the points and calculates the distance in meters between them
#Override
protected String doInBackground(LatLng... params) {
float[] distance=new float[1];
try {
// the Location class contains what we need to calculate distances
Location.distanceBetween(params[0].latitude,params[0].longitude,params[1].latitude,params[1].longitude,distance);
// geocoding operations
List<Address> fromResult=geocoder.getFromLocation(params[0].latitude,params[0].longitude,1);
List<Address> toResult=geocoder.getFromLocation(params[1].latitude,params[1].longitude,1);
// the message informs the user about the distance from the marker to the point selected with the click
// if we have got both the addresses, we use them to compose the message, otherwise we show only the distance
if (fromResult.size()>0 && toResult.size()>0)
{
// ((TextView) findViewById(R.id.tvDuration)).setText(route.duration.text);
return "The distance between " + getAddressDescription(fromResult.get(0)) + " and " + getAddressDescription(toResult.get(0)) + " is " + Math.round(distance[0]) + " meters";
}
else
return "The distance is " + Math.round(distance[0]) + " meters";
}
catch (IOException e) {
return "The distance is " + Math.round(distance[0]) + " meters";
}
}
#Override
protected void onPostExecute(String message)
{
if (progress!=null)
progress.dismiss();
// The builder of the window is instantiated
AlertDialog.Builder builder=new AlertDialog.Builder(MapsActivity.this);
builder.setTitle("Distance");
builder.setMessage(message);
// the Alert dialog appears
builder.show();
}
}
// this method only formats the message with addresses
private String getAddressDescription(Address a)
{
String city=a.getLocality();
String address=a.getAddressLine(0);
return "'"+address+"' ("+city+")";
}}
Use distanceBetween() method, It will give you exact distance in meters.
Location.distanceBetween(double startLatitude, double startLongitude,
double endLatitude, double endLongitude, float[] results);
Hi,
I'm a newbie in developing ArcGIS maps. Currently, I am able to display the map. But how can I create a default location using the longitude and latitude and implement this in my code?
For example, I want to set these coordinates: (1.3002, 103.8641). When you open the map, it will automatically zoom in to those coordinates.
Thank you in advance.
This is my code:
public class HelloWorld extends Activity {
MapView mMapView = null;
ArcGISTiledMapServiceLayer tileLayer;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Retrieve the map and initial extent from XML layout
mMapView = (MapView)findViewById(R.id.map);
/* create a #ArcGISTiledMapServiceLayer */
tileLayer = new ArcGISTiledMapServiceLayer(
"http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer");
// Add tiled layer to MapView
mMapView.addLayer(tileLayer);
}
#Override
protected void onPause() {
super.onPause();
mMapView.pause();
}
#Override
protected void onResume() {
super.onResume();
mMapView.unpause();
}
}
Before adding any layers to the MapView, set its OnStatusChangedListener. Add code to the listener that projects the longitude/latitude coordinates to map coordinates and centers the map at the map coordinates.
You could do it like this:
mMapView = (MapView)findViewById(R.id.map);
final double longitude = 103.8641;
final double latitude = 1.3002;
mMapView.setOnStatusChangedListener(new OnStatusChangedListener() {
#Override
public void onStatusChanged(Object source, STATUS status) {
if (STATUS.INITIALIZED.equals(status)) {
Point mapPoint = GeometryEngine.project(longitude, latitude, mMapView.getSpatialReference());
mMapView.centerAt(mapPoint, false);
}
}
});
/* create a #ArcGISTiledMapServiceLayer */
tileLayer = new ArcGISTiledMapServiceLayer(
"http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer");
// Add tiled layer to MapView
mMapView.addLayer(tileLayer);
If you want to both center and zoom to a certain scale, you can call zoomToScale instead of centerAt.
I'm building an app that allows a user to set a proximity alarm by selecting a marker and clicking on the info window to confirm. I need to be able to get the latitude and longitude from the marker so I can use the coordinates to set up the radius.
googleMap.setOnInfoWindowClickListener(
new OnInfoWindowClickListener(){
public void onInfoWindowClick(Marker marker) {
//click function
Toast.makeText(getBaseContext(),
"Info Window clicked#" + marker.getPosition(),
Toast.LENGTH_SHORT).show();
LocationManager lm;
double lat=0;
double long1=0; //Defining Latitude & Longitude
float radius=3000;
lm=(LocationManager) getSystemService(LOCATION_SERVICE);
Intent i= new Intent("com.example.sleepertrain5.proximityalert"); //Custom Action
PendingIntent pi = PendingIntent.getBroadcast(getApplicationContext(), -1, i, 0);
lm.addProximityAlert(lat, long1, radius, -1, pi);
So far, I've only been able to find marker.getLocation() which doesn't allow direct variable setting. Is there a way to do this?
Have you tried this:
map.setInfoWindowAdapter(new InfoWindowAdapter() {
// Use default InfoWindow frame
#Override
public View getInfoWindow(Marker args) {
return null;
}
// Defines the contents of the InfoWindow
#Override
public View getInfoContents(Marker args)
{
LatLng clickedMarkerLatLng = args.getPosition();
double latitude = clickedMarkerLatLng.latitude;
double longitude = clickedMarkerLatLng.longitude;
....
}
I hope this code helps you :
#Override
public void onMapLongClick(LatLng point) {
Latitude lat = point.getLatitude();
Longitude lng = point.getLongitude();
}
What I need to do, is when the "user" marker gets into (let's say 50 meters radius) the radius of one of the place of interest marker popus an dialog ( showplaceDialog() ).
How can I do it? I have simply no clue of how to do it...
This is how I put the "user" marker, which moves as location changes.
#Override
public void onLocationChanged(Location location) {
Log.d("Location", "onLocationChanged with location " + location.toString());
if(overlayMarkerYou == null) {
overlayMarkerYou = new MyOverlay(getResources().getDrawable(R.drawable.marker_you),mapView);
mapView.getOverlays().add(overlayMarkerYou);
}else{
mapView.getOverlays().remove(overlayMarkerYou);
mapView.invalidate();
overlayMarkerYou = new MyOverlay(getResources().getDrawable(R.drawable.marker_you),mapView);
mapView.getOverlays().add(overlayMarkerYou);
}
if (location != null) {
mapView.invalidate();
GeoPoint gpt = new GeoPoint(microdegrees(location.getLatitude()),microdegrees(location.getLongitude()));
mapController.setCenter(gpt);
overlayMarkerYou.addPoint(gpt, getString(R.string.markerYou), getString(R.string.markerYouDescription));
}
}
And this is how I put multiple markers for places of interest
public void putPlacesOfInterest(){
this.dh = new DataHelper(ShowMap.this);
List<Pontos> list = this.dh.selectAll();
for(Pontos p : list){
markerPlaces.add(new OverlayItem(p.getName().toString(), Long.toString(p.getId()), new GeoPoint(p.getLat(), p.getLng())));
}
mMyLocationOverlay = new ItemizedIconOverlay<OverlayItem>(markerPlaces, new OnItemGestureListener<OverlayItem>() {
#Override
public boolean onItemLongPress(int index, OverlayItem item) {
Toast.makeText(ShowMap.this, "" + item.mTitle, Toast.LENGTH_SHORT).show();
return true;
}
#Override
public boolean onItemSingleTapUp(int index, OverlayItem item) {
showplaceDialog(Integer.parseInt(item.mDescription),item.mTitle);
return true;
}
}, mResourceProxy);
mapView.getOverlays().add(mMyLocationOverlay);
mapView.invalidate();
}
I would recommend looking into the addProximityAlert() function available in the LocationManager class. I am not sure how many listeners you are able to register though.
Your other choice is to do a check on every location update. When your app gets a onLocationChanged() callback you can loop through your places of interest, and check to see if they are within 50 meters of the current location. To make this even easier, you can use the distanceTo() method in the Location class.