Mapbox center and set appropriate zoom level for a country - javascript

I'm trying to find a way to center and zoom to a country using Mapbox. I am able to get a country its coordinates using the geocoder, however, the zoom levels differ per country. (E.g. the zoom level for Spain is not the same level for the U.S.A.)
function showMap(err, data) {
console.log(data);
console.log(err);
if (err == true) {
console.log("Couldn't find this place!");
} else {
map.fitBounds(data.lbounds);
}
}
var geocoder = L.mapbox.geocoder('x',map);
geocoder.query("Spain", showMap);
Would I need an additional layer with fusion tables to achieve this?
Thanks for any help!

Can you be much more specific with this question, and provide an example, preferably something you can link to, with full code?
I am able to get a country its coordinates using the geocoder, however, the zoom levels differ per country.
The usage of 'however' is confusing: large countries will have different zoom levels than small. Is this what you see happening? Or not? Is this something you desire, or not?

Related

leaflet js centre popup issue (only on a few countries)

Disclaimer: I'm new to Stackoverflow so if I'm not following protocols just let me know!
Over the last couple of days I've started to learn Leaflet JS, its really cool. I've put together an interactive map, following the tutorials, and its not to bad. However, I'm having an issue with centring the popups for a select few countries.
In the highlightFeature function I've stored the centre point using centrePoint = e.target.getCenter(); This seems to work for all countries except Russia, China, Australia, Canada and the USA. If anyone can point me in the right direction and shed some light as to why this might be happening I would be very grateful.
You can find the project here http://codepen.io/CucumberCoolie/pen/yMyrWq?editors=0010
// highlight interaction on mouseover
function highlightFeature(e) {
var layer = e.target,
popup = L.popup(),
name = layer.feature.properties.name,
centrePoint = e.target.getCenter();
layer.setStyle({
weight: 1,
color: '#666',
fillColor: '#fff7bc',
dashArray: '',
fillOpacity: 0.7
});
if (!L.Browser.ie && !L.Browser.opera && !L.Browser.edge) {
layer.bringToFront();
}
countryName.textContent = name;
facts.update(layer.feature.properties);
// Add popup on mouseover
popup.setLatLng(centrePoint)
.setContent(name)
.openOn(map);
}
Thanks in advance!
Unfortunately the countries that you mention (you forgot UK, but there are also many other small countries for which this effect is not obvious) are made of several distinct polygons (i.e. multipolygon).
L.Polygon.getCenter() computes a rough centroid using only 1 of these polygons. E.g. in the case of USA, it is one of the Hawaii islands.
A simple, but not error-free, workaround would be first to get the polygon (country) bounds, then to get the center of those bounds:
centrePoint = e.target.getBounds().getCenter();
It works for countries with several polygons that are close enough (e.g. Canada, China, Australia, UK) or for which the "main land" is much bigger than the other parts (e.g. USA).
Updated Pen: http://codepen.io/anon/pen/dvPxqy?editors=0010
But it gives a totally off position for countries with many parts all over the world (e.g. France), or which are spread apart because of the antimeridian (e.g. Russia).
You could try to refine the polygon centroid computation, in particular taking into account the multipolygon case.
You might also be interested in that post: Get center of geojson Continent/Country/State with leaflet

How to get Leaflet GeoJSON feature containing a given latitude/longitude point

I have a LeafletJS map with a GeoJSON layer that contains multiple polygons. If a user enters a latitude/longitude coordinate that falls within the GeoJSON layer, the script should retrieve the feature that contains that point and log some information about it to the console.
I can't simply use Leaflet's built-in event handling because the latitude and longitude coordinates are generated by a separate input field, not by direct interaction with the map. So my question is not a duplicate of this.
I'm looking for something similar to getFeatureContainingLatLng() in the example below:
var map = L.map('map');
var geojson = L.geoJson(myGeojson);
geojson.addTo(map);
$.on('address input changed event', function(lat, lng) {
var myFeature = geojson.getFeatureContainingLatLng(lat, lng);
console.log(myFeature.properties);
});
The plugins Leaflet.CheapLayerAt or Leaflet-pip should help. Both approaches will solve your problem, albeit they have different advantages and disadvantages specially in terms of algorithmic complexity.

US Metro regions on google chart geo map

I want to create a geo map with a specific state region, and individual metro area regions colored by intensity of the value. I have looked at the documentation but haven't been able to achieve this. Here is an example of what I am targeting for.
Does anyone has any idea what options to use for just showing e.g., CA state, and then marking the regions by zip code.
The map is showing metro regions which is not the same as zip code. If you want the metro regions for California you would call chart.draw() with the following:
var options = {
displayMode:'regions',
region:'US-CA',
resolution:'metros'
};
But you will need to map your data to the appropriate IDs from here: https://developers.google.com/adwords/api/docs/appendix/cities-DMAregions
Here is a fiddle: http://jsfiddle.net/5he4p5k9/1/ [Change region to just 'US' to zoom out]

Displaying Antarctica using GeoJSON in heremaps

I'm trying to render Antarctica geojson shape on a map using the HERE maps api.
The geojson is found here: https://github.com/johan/world.geo.json/blob/master/countries/ATA.geo.json
You can see github renders it nicely.
Using the same geojson on geojson.io also renders it nicely.
But somehow it seems to render the 'inverse' of Antarctica when using it in HERE maps.
It colors everything except antarctica.
see: http://imagebin.ca/v/1dZIn5vsEuFx
(I've tried making an expample using jsfiddle, but it's not able to load external json. And the HERE maps api doesn't allow you to load geoJSON from a string)
Is there an issue with the geoJSON? Is there an issue with the HERE maps api?
The API doesn't quite understand what to do with the open polygon. Because the polygon is basically just a line around the globe the API doesn't know if you shape closes over the north pole or the south pole. By default it assumes that open polygons close over the north pole. You can change this by using this flag (setNorthPoleCovering):
http://developer.here.com/javascript-apis/documentation/v3/maps/topics_api_nlp/h-map-polygon.html#h-map-polygon__setnorthpolecovering
However, actually getting to that point in the code where this can be done is a bit complicated:
// When you instantiate the geojson.Reader you can specify a function that
// receives all objects the reader parsed. It is called when objects are
// being rendered on the map. At that point we can look into the object and
// check whether it is Antarctica
var reader = new H.data.geojson.Reader('...ATA.geo.json', {
style: function(obj) {
if (obj.getData().properties.name === "Antarctica") {
//AHA! We found Antarctica!
// Since this is a multi-polygon we have a group here which contains
// all polygons. We apply the north-pole-covering flag to each of the
// polygons
obj.forEach(function(polygon) {
polygon.setNorthPoleCovering(false);
});
}
}
});
reader.parse();
map.addLayer(reader.getLayer());
Depending on what you want to accomplish in terms of dynamic behavior, if you are just looking to display or share a map with cards and other metadata about a country with some basic styling -- HERE XYZ can be used to render GeoJSON on a HERE map.
If you want to do it with JavaScript rather than an embedded iframe, the other answer may be what you are looking for.
There is an there an issue with the GeoJSON, and other mapping APIs would have the same problem. It needs to be closed at the 180th meridian, so
[178.277212,-84.472518],[180,-84.71338],[-179.942499,-84.721443]
becomes
[178.277212,-84.472518],[180,-84.71338],[180,-90],[-180,-90],[-180,-84.71338],[-179.942499,-84.721443]

How do i determine the Max Zoom Level integer for Google Maps?

Is there a way of generating the actual integer that represents the max zoom level of Google Maps? In either the Static or Java API?
Yes you can generate the maximum zoom level possible for the place you are looking at as:
getMaxZoomAtLatLng(latlng:LatLng, callback:function(MaxZoomResult))
Returns the maximum zoom level available at a particular LatLng for the Satellite map type. As this request is asynchronous, you must pass a callback function which will be executed upon completion of the request, being passed a MaxZoomResult.
You can also set the maximum allowed zoom level (to prevent users from fully zooming in for instance) by using the maxZoom property of your MapOptions
The maximum zoom level which will be displayed on the map. If omitted, or set to null, the maximum zoom from the current map type is used instead.
Read everything about it here. (CTRL+F and look for "maximum zoom")
http://code.google.com/apis/maps/documentation/javascript/v2/introduction.html
Each map also contains a zoom level, which defines the resolution of the current view. Zoom levels between 0 (the lowest zoom level, in which the entire world can be seen on one map) to 19 (the highest zoom level, down to individual buildings) are possible within the normal maps view. Zoom levels vary depending on where in the world you're looking, as data in some parts of the globe is more defined than in others. Zoom levels up to 20 are possible within satellite view.
Seems like it's relatively safe to just hard code 19, but if you need the exact max for the places where 19 zoom is disallowed (military bases and whatnot) or places where 20 is allowed (not sure), I'm not sure how to determine that. Perhaps you can detect this by setZoom and then immediately calling getZoom and if the number returned from getZoom is not the one you just set, then you're in one of the non-standard locations.
Here's actual code, if it's helpful.
The accepted answer points in the right direction. The documentation you want is [right here][1].
And here's working modern ES6 code for 2019:
/* Determine max zoom at location */
const location = { lat: _LATITUDE_, lng: _LONGITUDE_ }
const getMaxZoom = new google.maps.MaxZoomService()
getMaxZoom.getMaxZoomAtLatLng(location, (response) => {
console.log('Max zoom at this location:', response.zoom)
})
[1]: https://developers.google.com/maps/documentation/javascript/maxzoom

Categories

Resources