Openlayers + OSM tiles on iPad / iPhone - android

I use OpenStreetMap on a responsive Website and have some display issues.
The map is displayed very well on my Samsung S4 with Android.
The Map is not displayed on my iPad2 with OS5 or Sony Z with Android
I use
map = new OpenLayers.Map("basicMap");
var mapnik = new OpenLayers.Layer.OSM();
map.addLayer(mapnik);
I thought the error is here
map.setCenter(new OpenLayers.LonLat(3, 3) // Center of the map
.transform(
new OpenLayers.Projection("EPSG:4326"), // transform from WGS 1984
new OpenLayers.Projection("EPSG:900913") // to Spherical Mercator Projection
), 15 // Zoom level
);
but the use of transform() without parameters was not successful.
any suggestions ?

Related

Android Google Map: Dynamic Map zoom Level vs Static Map Zoom Level

I have to use Google dynamic map to search a location, scroll, zoom, etc and then take a screenshot of the map. Due to license restriction, I cannot take a screenshot (GMap.Snapshot(this)). So it was decided to download an image from google static map
When the user wants to switch from map dynamic mode to static map, he clicks a button and I take center latitude and longitude, zoom level and map size (it's xamarin android)
{
CenterLatLng = new double[] { GMap.CameraPosition.Target.Latitude, GMap.CameraPosition.Target.Longitude },
ZoomLevel = (int)GMap.CameraPosition.Zoom,
Type = GMap.MapType,
MapSize = new int[] { MapFragment.View.MeasuredWidth, MapFragment.View.MeasuredHeight }
};
with this parameters i will try to download a static map
int scale = 2;
var url = $"https://maps.googleapis.com/maps/api/staticmap?center={myobject.CenterLatLng[0]},{myobject.CenterLatLng[1]}&zoom={myobject.ZoomLevel}&size={myobject.MapSize[0] / scale}x{myobject.MapSize[1] / scale}&scale={scale}&maptype=satellite&format=png&key=xxxxxxxx";
but downloaded static map seems to have a different zoom from dynamic Map
Here a screenshot of the Dynamic Map displayed before than switching to Static map
Here a screenshot of the Static Map displayed after
how can I fix that difference between dynamic map zoom and static map zoom?
how can I fix that difference between dynamic map zoom and static map zoom?
I think the issue is caused by the size you set in the url size={myobject.MapSize[0] / scale}x{myobject.MapSize[1] / scale}.
You could create a new variable to divide the MapSize instead of using scale to change the size.

OSMDroid app using custom ARCGis tile server - tiles are shuffled

I am developing an android mapping app using OSMDroid. I am attempting to use free custom aerial imagery, completely independent of google and/or bing api's. Please, do not propose ANY solution that uses their mapping api's.
I have managed to display satellite imagery by including this code:
mapView.setTileSource(TileSourceFactory.MAPQUESTAERIAL);
BUT, tile server does not offer tiling above 11 zoom and i need to get wee closer than that (say 15-16?).
Using ARCGis tile server, I manage to display satellite imagery even to 16 layer zoom level, but tiles are shuffled around.
mapControl = (MapController) mapView.getController();
mapControl.setZoom(11);
String[] urlArray = {"http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/"};
mapView.setTileSource(new XYTileSource("ArcGisOnline", null, 0, 18, 256, ".png",urlArray ));
Basemap tiles are shuffled and do not correspond to lat/lon, but overlay is ok.
The tile server probably uses a different scheme for retrieving tiles. Try flipping the X and Y coordinates. Slippy map servers (osm) use the Z/X/Y.ext format. ArgGis and several others use Z/Y/X.ext format. All other coordinates are the same. This means the solution is simple, override the getTileURLString method and supply the coordinates in whatever format the server wants.
Osmdroid has an example for doing exactly this.
https://github.com/osmdroid/osmdroid/blob/master/OpenStreetMapViewer/src/main/java/org/osmdroid/samplefragments/SampleCustomTileSource.java
The relevant bit a code this
mMapView.setTileSource(new OnlineTileSourceBase("USGS Topo", 0, 18, 256, "",
new String[] { "http://basemap.nationalmap.gov/ArcGIS/rest/services/USGSTopo/MapServer/tile/" }) {
#Override
public String getTileURLString(MapTile aTile) {
return getBaseUrl() + aTile.getZoomLevel() + "/" + aTile.getY() + "/" + aTile.getX()
+ mImageFilenameEnding;
}
});
You'll also want to purge the cache after this change since it has the wrong coordinates

Osmdroid XYTileSource passing X and Y paramaters

I am really new in this routing and maps area. I have a basic, maybe stupid, question. I use osmdroid to show a tile from a URL that looks like this
http://tile01-cdn.maptoolkit.net/terrain/15/17789/11515.png
Where 15 represents the zoom,
17789 the X value and
11515 the Y value
Now when I want to use osmdroid to show this tile in the map I don't know what kind of TileSource should I use. The most obvious is the XYTileSource but the constructor does not have any x y parameters to pass, but I see on the internet a lot of questions/answers where people use the same object but with a different constructor. I am guessing here that the code has changed in the lib. The current constructor:
XYTileSource(String aName, int aZoomMinLevel, int aZoomMaxLevel, int aTileSizePixels, String aImageFilenameEnding, String[] aBaseUrl)
So my question is how can I show this tile map of mine in the osmdroid map, what kind of ITileSource should I use? Should I implement my own custom one?
this is how I tried to do it:
final ITileSource tileSource = new XYTileSource("Maverik", 15, 17789, 11515, ".png", new String[] {"http://tile01-cdn.maptoolkit.net/terrain/"});
tileProvider.setTileSource(tileSource);
and I get an empty MapView.
Purpose of osmdroid is to display world map - with a lot of tiles. And to display the appropriate tiles depending on where the "map view" is centered (this center being defined with: a latitude, a longitude, and a zoom level).
If this is also what you want:
1) As examples, look at default tile sources included in osmdroid, in TileSourceFactory
2) Then you could try something like:
OnlineTileSourceBase tileSource = new XYTileSource("Maverik",
0, 17,
256, ".png",
new String[] {
"http://tile01-cdn.maptoolkit.net/terrain/",
"http://tile02-cdn.maptoolkit.net/terrain/",
"http://tile03-cdn.maptoolkit.net/terrain/"
});
mapView.setTileSource(tileSource);
You may also want ton consult the osmdroid wiki and the source for the sample application. There's tons of examples on how to use just about every tile source that we know of. We're also adding more as they are discovered.
https://github.com/osmdroid/osmdroid/wiki
You don't need to worry about X and Y coordinates. They actually aren't lat/lon coordinates but are grid references. Open Street Maps, and many other tile sources, use the same or similar tile coordinate system. Start with the world in one image. Zoom =1 divide it into 4 parts. That's your X,Y and Zoom coordinates. Zoom =2 level, divid the four tiles we started with into 4 again, and we have 16 tiles.

The google map in my web app appears wrong on tablet

I try to run a google map in my cordova application. It displays well on mobile (Iphone 5s) but not on my tablet (Nexus 7).
Here my map display function :
function onSuccessMap() {
var myLocation = new google.maps.LatLng(LATITUDE, LONGITUDE);
if (map === null)
{
directionsDisplay = new google.maps.DirectionsRenderer({suppressMarkers: true});
map = new google.maps.Map(document.getElementById('directionMap'), {
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: myLocation,
disableDoubleClickZoom: true,
zoom: 8
});
directionsDisplay.setMap(map);
}
}
The map appears at the top left of the screen and doesn't take up all the space.
I hope I have given enough information
I believe you need to set the width and height of the div containing the map (#directionMap).
(the div should take the space independently. The map will not make the div bigger). Nexus 7 runs probably KitKat, and the difference stems from Chromium vs. Webkit.

Create adaptive grid on the map for clusterization

In our application we use google map APIs v1.
I wrote grid-based clusterization for markers (total amount up to few thousands). Everything works fine - good performance, etc...
The only problem is that I calculate grid depending on currently viewed area
private void createCluster2DArray() {
double cwidth = (cachedrightLongitude - cachedleftLongitude) / clustersXnum;
double cheight = (cachedtopLatitude - cachedbottomLatitude) / clustersYnum;
for (int i = 0; i < clustersXnum; i++) {
for (int j = 0; j < clustersYnum; j++) {
Cluster cluster;
if (clusters[i][j] == null) {
cluster = new Cluster();
clusters[i][j] = cluster;
} else {
cluster = clusters[i][j];
cluster.list.clear();
}
//calculate dimensions
cluster.left = cachedleftLongitude + i * cwidth;
cluster.right = cluster.left + cwidth;
cluster.bottom = cachedbottomLatitude + j * cheight;
cluster.top = cluster.bottom + cheight;
cluster.calculateCenter(mMapView);
}
}
}
cachedrightLongitude, cachedrightLongitude, cachedrightLongitude, cachedrightLongitude are borders of device screen area in degrees.
The problem, you can see, is that cluster borders changing every time when user changes visible area (change zoom level, or just slide the screen). This leads to clusters recalculation and markers redistribution over them.
The only solution I see is to create some kind of static screen-independent clusters greed for each zoom level(for example at zoom level 5 size of cluster will be 10milli degrees and at level 6 it will be 2milli degrees, so only border-clusters will dynamicaly change their size and outer borders). Am i right?
Is there any other suggestions?
For android maps API v1 there is a clustering library here: https://github.com/damianflannery/Polaris. This is a fork of Cyril Mottier's Polaris library, but the discussion on pull request suggest it won't be merged back into original. See here. I haven't looked at the source, so I can't tell you if they use grid clustering.
As for your question, I think using static screen-independent cluster grid is the way to go. I'd only suggest changing the values of millidegrees. For zoom level that is different by 1, millidegs should be divided (or multiplied) by 2.
Also note that with latitude you can't use degrees value directly, but you have to push it through a Mercator projection. This is to make grid consist of squares instead of having them look like rectangles with height few times greater than width closer to the north and south poles.
This is basically what I do in Android Maps Extensions for maps API v2.
I assumed 180 degrees grid size on zoom level 0, so 90 degrees on zoom level 1, 45 on 2, etc. and about 85 microdegrees on zoom 21. The value can be changed in the API.
To you the most useful parts of the code from Extensions lib would be: SphericalMercator to convert latitude and some portions from GridClusteringStrategy.

Categories

Resources