I'm new to android development and I've done some applications involving Google maps. What I'm trying to develop now is an Optimal Path Finder App. I know that there are many application already available for this purpose, but I plan to do this on my own. I'm planning to use Dijkstra's algorithm for this purpose. The initial input is the source and destination, and the output must be the optimal path drawn on a Google map between the source and destination. I've an idea about the steps needed to do this application.
Step 1 : Extract the intermediate places between the source and destination.
Step 2 : Add these nodes to a graph data structure.
Step 3 : Apply Dijkstra's Algorithm and find the path.
Step 4 : Draw the path on a Google map.
Am I thinking in the right way?
Yes you're thinking in the right way :) ! Also consider openstreetmaps for the data source and mapsforge as an offline map tile provider.
Try this:
1.put ruledijkstra.html onto folder asset
2.load using this code:
private void getLocation(){
WebSettings webSettings = mWebView.getSettings();
mWebView.loadUrl("file:///android_asset/maps.html");
String path="javascript:loadAtStart(-6.184505,106.797685,11)";
mWebView.loadUrl(path);
}
3.code for asset:
ruledijkstra.html or you can google:etc
http://www.zlink.com.br/optimap/index.php?&loc0=-7.1209077392192785,-34.9075984954834&loc1=-7.121418750873643,-34.903221130371094&loc2=-7.128828355854018,-34.93025779724121
Related
So Mapbox provides an awesome Navigation SDK for Android, and what I have been trying to do is create my own routes, representing each point as a Feature in a Geojson file, and then passing them on to the MapMatching module to get directions that I can then pass to the Navigation Engine.
My solution evolves into two main parts. The first one involves iterating through the points I want navigation to go through, by adding them as input to the .coordinates element of MapboxMapMatching.builder() and subsequently converting this to
.toDirectionRoute(); per Mapbox instructions and example here: https://www.mapbox.com/android-docs/java/examples/use-map-matching/
private void getWaypointRoute(List<Point> features) {
originPosition = features.get(0);
destinationPosition = features.get(features.size() - 1);
MapboxMapMatching.builder()
.accessToken(Mapbox.getAccessToken())
.coordinates(features)
.steps(true) // Setting this will determine whether to return steps and turn-by-turn instructions.
.voiceInstructions(true)
.bannerInstructions(true)
.profile(DirectionsCriteria.PROFILE_DRIVING)
.build().enqueueCall(new Callback<MapMatchingResponse>() {
#Override
public void onResponse(Call<MapMatchingResponse> call, Response<MapMatchingResponse> response) {
if (response.body() == null) {
Log.e(TAG, "Map matching has failed.");
return;
}
if (response.isSuccessful()) {
currentRoute = response.body().matchings().get(0).toDirectionRoute();
The second bit involves just passing 'currentRoute' to the NavigationLauncher as shown below:
NavigationLauncherOptions options = NavigationLauncherOptions.builder()
.origin(origin)
.destination(destination)
.directionsRoute(currentRoute)
.shouldSimulateRoute(simulateRoute)
.enableOffRouteDetection(false)
.build();
// Call this method with Context from within an Activity
NavigationLauncher.startNavigation(MainActivity.this, options);
An example of the route can be seen here Android Simulator Snapshot with Route . Each point across the route, is an intersection, and corresponds to a feature in my GeoJson file. The problem becomes when I launch the navigation. Every time, either in the simulator or on a real device, each point is interpreted as a destination so the voice command goes 'You have reached your first (second, third etc) destination'. I find this annoying as I would like to have a single route with a destination and that's it. I would just like to have this points so I have my own custom path, instead of the shortest path typically returned by routing applications. I try to avoid the problem by setting voiceInstructions off but then the system goes bananans and the navigation screen moves to lat, lng (0,0) which is pretty much somewhere West of Africa. Any help on how I could resolve this it would be greatly appreciated and I would be happy to buy a beer or two for the person that provides the right answer. I have reached out to Mapbox Support as well but we have not found an answer to the problem so I asked them to escalate it internally within their engineering team, as I believe, although the problem I am solving is not uncommon, it is still not very much tested by developers. Cheers!
So here I am and after the kind support of Mapbox Support and Rafa Gutierrez
I can now answer this post myself.
The problem has been arising due to MapboxMapMatching automatically setting .coordinates as waypoints. If instead, one edits explicitly the waypoints variable to have only two waypoints: origin and destination, then the system is able to process the input customised route without translating each input coordinate as a waypoint. The code example below hopefully clarifies the point described above:
MapboxMapMatching.builder()
.accessToken(Mapbox.getAccessToken())
.coordinates(lineStringRep.coordinates())
.waypoints(OD)
.steps(true)
.voiceInstructions(true)
.bannerInstructions(true)
.profile(DirectionsCriteria.PROFILE_DRIVING)
.build().enqueueCall(new Callback<MapMatchingResponse>()
where OD is an array of integers storing the first (origin) and last index (destination) of your coordinates
OD[0] = 0;
OD[1] = features.size() - 1;
is it possible to follow a path on google map android (Programmatically) if my android device getting away from the path it notify or show alert that your not following your path
Help will be appriciated,
Thank's :)
Yes, it's possible by several ways. For example you can use PolyUtil.isLocationOnPath(LatLng point, java.util.List<LatLng> polyline, boolean geodesic, double tolerance) from Google Maps Android API Utility Library. In this case you need to check (with isLocationOnPath()) if user location laying on segment of the polyline of your path. Something like that:
if (!PolyUtil.isLocationOnPath(userLocationPoint, pathPolyline.getPoints(), true, 50)) {
// user away of pathPolyline more than 50 meters
// show your alert here
...
}
}
where 50 - is tolerance (in meters).
NB! It's not a complete solution - just approach.
Also you can use geofence monitoring for several waypoints (with a limit of 100 per device user).
I use MapBox Android SDK 0.7.2 to get tiles from MapBox web service:
WebSourceTileLayer webSourceTileLayer = new WebSourceTileLayer("MapBox", "http://api.tiles.mapbox.com/v4/examples.map-zr0njcqy/-73.99,40.70,13/256x256.png?access_token=<my key>");
webSourceTileLayer.setName("MapBox")
.setAttribution("© MapBox © OpenStreetMap")
.setMinimumZoomLevel(1)
.setMaximumZoomLevel(18);
mapView.setTileSource(webSourceTileLayer);
mapView.setZoom(12);
mapView.setCenter(mapView.getTileProvider().getCenterCoordinate());
so I get back a 256x256 png format tile. But the tile repeats in the screen while I suppose it should be one tile in the screen. Any suggestion is appreciated.
Are you looking to just download the one tile from the Mapbox Web Service API? If so using a regular Android HTTP client (ex: URLConnnection class) to download it and then paint it on the Canvas would serve this better. TileLayers like WebSourceTileLayer are meant to download many different tiles and display them on the MapView as described.
I am working on custom map app and i want to use google map tiles for background ? There is one class TileProvider in api but i don't know how to initialize it every time i try it goes something like this ?
TileProvider tileProvider=new TileProvider() {
#Override
public Tile getTile(int i, int i2, int i3) {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
};
how to override getTile function to get tiles from google map server?
Any example will be appreciated ?I know getTile function need x,y and zoom value to return tile.
So quick answer is that you can get the Google Map tiles from the following URL:
http://mt1.google.com/vt/lyrs={t}&x={x}&y={y}&z={z}
Where {t} is the type of map (satellite, road, hybrid, etc) and the other attributes are specifying the coordinates and zoom level.
The possible values for {t} are as follows:
Default - m
Roads only - h
Roads simplified - r
Satellite - s
Satellite hybrid - y
Terrain - t
Terrain hybrid - p
That being said you do want to make sure what you're doing is NOT a violation of the terms & services. Specifically Google WILL allow you to cache their tiles provided that you are doing so ONLY in order to improve performance and that you delete their tiles at least every 30 days, and finally you don't pull down their tiles in an attempt to make your own mapping service.
You may want to read the Google Maps Terms of Service - https://developers.google.com/maps/terms - specifically section 10.1.1
I have written a radar weather app using osmdroid for map tiles, and manually overlaying NOAA ridge radar data. Everything Is working great except that the radar images are unprojected, while the openstreetmap tiles are in transverse Mercator projection. The weather lies within the bounds it should but the data is distorted.
I see three ways to fix this (in order of preference) but am having trouble with all three:
1) find a source of radar data already projected in mercator - hours of Googling later, I've found nothing
2) programmatically reproject the images right after I download them. Does anyone know a good API for this?
3) project them on the fly, perhaps with openlayers.im reading that can openlayers reproject,but can it be used over top of an osmdroid mapview?
Any ideas? Thanks for any help
Mike
GDAL is the way to go. There is no official Android build that I know of however some people have been successful in getting it running on Android. For example, Nutiteq has a build in the libs folder of their AdvancedMap3D sample project. Put the contents of both armeabi folders in your project's lib folder and you should be able to access the GDAL packages.
Then take a look at the GDAL in Java page. Look at the gdalinfo.java sample to get a feel for how to load and examine the parts of a GDAL dataset. To reproject your dataset, you will do something along the lines of:
SpatialReference sr = new SpatialReference();
sr.ImportFromProj4("+proj=merc +datum=WGS84");
String result[] = new String[1];
sr.ExportToPrettyWkt(result, 1);
String oldProjection = mDataset.getProjection();
String newProjection = result[0];
Dataset newDataset = gdal.AutoCreateWarpedVRT(mDataset, oldProjection, newProjection, gdalconst.GRA_NearestNeighbour, 0.0);
Dataset savedDataset = mDriver.CreateCopy(outpath, newDataset, 0, new String[] { "COMPRESS=LZW", "PREDICTOR=2" }, null, null);
newDataset.delete();
savedDataset.delete();
You may need to make a few adjustments, but that should get you most of the way there.