From the Maps Javascript API docs for Polyline (note the path
property):
The ordered sequence of coordinates of the Polyline. This path may be
specified using either a simple array of LatLngs, or an MVCArray of
LatLngs. Note that if you pass a simple array, it will be converted to
an MVCArray Inserting or removing LatLngs in the MVCArray will
automatically update the polyline on the map.
Knowing that, I'd try it like this:
// I assume you've got your GPS signal pumping updates to your client.
// Insert a new GPS point into your Polyline's point array.
function OnGpsPulse(newLat, newLon)
{
// Insert a new point at the end of the LatLng Array.
pointIndex = flightPlanCoordinates.length;
flightPlanCoordinates[pointIndex]=new google.maps.LatLng(newLat, newLon);
// And the line should automatically update in the map.
}
As an afterthought, each GPS pulse should be dispatching an event that you may need/want to handle in two places. First, if you want to store vehicles' positions indefinitely, you'll need to collect them server-side and push them into your database. However, if you just want a vehicle to draw a line while it travels, you can keep that functionality in the client.
Yes, you can use custom tiles with Android Maps API v2 - you can see a fully working example in our OpenTripPlanner for Android app on Github. (You can also download the app directly from Google Play)
We support the following tile providers:
- LyrkOpenStreetMap
- MapQuestOpenStreetMap
- Mapnik
- CycleMap
- Google (normal, satellite, hybrid, terrain)
Our CustomUrlTileProvider class can be seen here on Github, and I've also pasted it below:
public class CustomUrlTileProvider extends UrlTileProvider {
private String baseUrl;
public CustomUrlTileProvider(int width, int height, String url) {
super(width, height);
this.baseUrl = url;
}
@Override
public URL getTileUrl(int x, int y, int zoom) {
try {
return new URL(baseUrl.replace("{z}", "" + zoom).replace("{x}", "" + x)
.replace("{y}", "" + y));
} catch (MalformedURLException e) {
e.printStackTrace();
}
return null;
}
}
And here's the code that switches between map tile providers, based on user preference:
/**
* Changes the tiles used to display the map and sets max zoom level.
*
* @param overlayString tiles URL for custom tiles or description for
* Google ones
*/
public void updateOverlay(String overlayString) {
int tile_width = OTPApp.CUSTOM_MAP_TILE_SMALL_WIDTH;
int tile_height = OTPApp.CUSTOM_MAP_TILE_SMALL_HEIGHT;
if (overlayString == null) {
overlayString = mPrefs.getString(OTPApp.PREFERENCE_KEY_MAP_TILE_SOURCE,
mApplicationContext.getResources()
.getString(R.string.map_tiles_default_server));
}
if (mSelectedTileOverlay != null) {
mSelectedTileOverlay.remove();
}
if (overlayString.startsWith(OTPApp.MAP_TILE_GOOGLE)) {
int mapType = GoogleMap.MAP_TYPE_NORMAL;
if (overlayString.equals(OTPApp.MAP_TILE_GOOGLE_HYBRID)) {
mapType = GoogleMap.MAP_TYPE_HYBRID;
} else if (overlayString.equals(OTPApp.MAP_TILE_GOOGLE_NORMAL)) {
mapType = GoogleMap.MAP_TYPE_NORMAL;
} else if (overlayString.equals(OTPApp.MAP_TILE_GOOGLE_TERRAIN)) {
mapType = GoogleMap.MAP_TYPE_TERRAIN;
} else if (overlayString.equals(OTPApp.MAP_TILE_GOOGLE_SATELLITE)) {
mapType = GoogleMap.MAP_TYPE_SATELLITE;
}
mMap.setMapType(mapType);
mMaxZoomLevel = mMap.getMaxZoomLevel();
} else {
if (overlayString.equals(getResources().getString(R.string.tiles_mapnik))) {
mMaxZoomLevel = getResources().getInteger(R.integer.tiles_mapnik_max_zoom);
} else if (overlayString.equals(getResources().getString(R.string.tiles_lyrk))) {
mMaxZoomLevel = getResources().getInteger(R.integer.tiles_lyrk_max_zoom);
tile_width = OTPApp.CUSTOM_MAP_TILE_BIG_WIDTH;
tile_height = OTPApp.CUSTOM_MAP_TILE_BIG_HEIGHT;
} else {
mMaxZoomLevel = getResources().getInteger(R.integer.tiles_maquest_max_zoom);
}
mMap.setMapType(GoogleMap.MAP_TYPE_NONE);
CustomUrlTileProvider mTileProvider = new CustomUrlTileProvider(
tile_width,
tile_height, overlayString);
mSelectedTileOverlay = mMap.addTileOverlay(
new TileOverlayOptions().tileProvider(mTileProvider)
.zIndex(OTPApp.CUSTOM_MAP_TILE_Z_INDEX));
if (mMap.getCameraPosition().zoom > mMaxZoomLevel) {
mMap.moveCamera(CameraUpdateFactory.zoomTo(mMaxZoomLevel));
}
}
}
Here's a screenshot of the MapQuest OpenStreetMap tiles:
For more information on making your own tiles, see the Google documentation for TileOverlay as well as the OpenStreetMap wiki for "Creating your own tiles".
Specifically, the Google documentation says:
Note that the world is projected using the Mercator projection (see Wikipedia) with the left (west) side of the map corresponding to -180 degrees of longitude and the right (east) side of the map corresponding to 180 degrees of longitude. To make the map square, the top (north) side of the map corresponds to 85.0511 degrees of latitude and the bottom (south) side of the map corresponds to -85.0511 degrees of latitude. Areas outside this latitude range are not rendered.
At each zoom level, the map is divided into tiles and only the tiles that overlap the screen are downloaded and rendered. Each tile is square and the map is divided into tiles as follows:
At zoom level 0, one tile represents the entire world. The coordinates of that tile are (x, y) = (0, 0).
At zoom level 1, the world is divided into 4 tiles arranged in a 2 x 2 grid.
...
- At zoom level N, the world is divided into 4N tiles arranged in a 2N x 2N grid.
Note that the minimum zoom level that the camera supports (which can depend on various factors) is GoogleMap.getMinZoomLevel and the maximum zoom level is GoogleMap.getMaxZoomLevel.
The coordinates of the tiles are measured from the top left (northwest) corner of the map. At zoom level N, the x values of the tile coordinates range from 0 to 2N - 1 and increase from west to east and the y values range from 0 to 2N - 1 and increase from north to south.
The formatted URLs that are used within OTP Android to reference each tile provider look like:
So, for the above providers the tile images are PNG files arranged in the directory structure indicated by the Google documentation. You would follow a similar format to create your own map tiles hosted on your own server. Note that these URLs/images must be publicly accessible to the mobile device (i.e., cannot be password protected).
Best Answer
I did a work project like what you described with no experience in the Google Maps API, PHP or mySQL. I worked from this document from Google's developer's resources: From info window to Database.
For my project:
Make sure you do validation on your php processing page too to avoid SQL injection.