mapbox fit bounds to country - javascript

i just want fit my map to my country. I saw some example from https://www.mapbox.com/mapbox-gl-js/example/fitbounds/ and it's fit to whole Kenya. It's a simple code but i don't know why this function takes two lat and longs. I just google it for what is Keyna lat and long? it's 1.2667° S, 36.8000° E. Why this is different than google's result.
function fit() {
map.fitBounds([[
32.958984,
-5.353521
], [
43.50585,
5.615985
]]);
}
How to fit to my specific area just like this.

If i search for the bounding box of Kenya, i find the following:
http://isithackday.com/geoplanet-explorer/index.php?woeid=23424863
Using those coordinates, it's looks ok:
map.fitBounds([
[-4.71712, 33.90884], // Northeast
[4.62933, 41.899059] // Southwest
]);
Example using Leaflet on Plunker: http://plnkr.co/edit/yRuTxjmQxcoqkVyFbE4q?p=preview

.fitBounds takes two latlng arguments, one for the upper-left corner of the mapview and one for the lower-right corner.
If you would like to just center the map on Kenya, you could use:
map.flyTo({center: [Lat, Lng]})

I also was looking for the answer on this question. Leaflet, for example, has a property of a layer to get its bounds (e.g.,map.fitBounds(layer.getBounds());). Mapbox GL doesn't have anything like that. At least not that I know. To handle this you may access the first and the last coordinates of the currently selected feature: map.fitBounds([feature.geometry.coordinates[0], feature.geometry.coordinates[feature.geometry.coordinates.length-1]]).
Here is the whole piece of code in case you want to have a popup with a Zoom button on it:
map.on('click', function (e) {
map.featuresAt(e.point, {layer: 'route-lines', radius: 10, includeGeometry: true}, function (err, features) {
if (err || !features.length)
return;
var feature=features[0];
new mapboxgl.Popup()
.setLngLat(e.lngLat)
.setHTML(popupTemplate)
.addTo(map);
var buttonZoomFeature = document.getElementById('button-zoom');
buttonZoomFeature.addEventListener('click', function (e) {
map.fitBounds([feature.geometry.coordinates[0], feature.geometry.coordinates[feature.geometry.coordinates.length-1]]);
});
});
});
var popupTemplate = '<div id="popup-div">\
<button id="button-zoom" class="button-zoom" type="button">Zoom to</button>\
</br>\
</div>';
PS. This approach works fine when the layer is a number of lines (roads, for example). If you want to fit the bounds to a country, which is a polygon, you may try taking the first longitude-latitude point as the one that has min latitude and for the second point the one that has max longitude. Or something like that. Just try to play around with this approach. I am sure it will work out.

Related

Setting a Max Boundary is not working Leaflet

I seem to be unable to set a Max Boundary, so that the map bounces back after the user has reached a certain point. Also every time I've tired to change the fitbounds() code the map disappears from my Website.
I've looked at the Leaflet documentation over and over again, with very little luck and been looking through Google for any answers and all the code I have tried has not work. I believe I'm missing or not seeing something really simple.
Any ideas?
If all you want is to restrict the view to a given geographical boundary, the simplest solution is to set the maxBounds option. Unless you want to do it dynamically, in which case the option to use is setMaxBounds. The fitBounds method seems redundant and may actually be the reason why you aren't getting the desired outcome.
var southWest = L.latLng(52.456009,-10.685582);
var northEast = L.latLng(51.699800,5.215615);
var maxBoundArea = L.latLngBounds(southWest, northEast);
var map = L.map('map', {
zoomControl:true,
maxNativeZoom:28,
minZoom:8,
maxBounds: maxBoundArea
});
I would suggest writing a constrain function
function constrain(n,low,high){
return Math.max(Math.min(n, high), low);
}
* Note: I did not think of this myself, it is a function in p5 and thought it might work*
Documentation:
https://github.com/processing/p5.js/blob/0.7.3/src/math/calculation.js#L76

ArcGIS JavaScript API (3.8) centerAndZoom does not appear to be working

I'm new to ESRI's JavaSCript API and am very impressed by its ease of use and speed. As part of a interactive data portal I have users enter latitude and longitude as decimal degrees as part of a spatial query to return State, County and FIPs. That part works just fine, but as an added feature I want to draw a dot graphic on an existing map showing the entered coordinates location (DONE) then Center and Zoom to said point at some reasonable scale.
The centerAndZoom method is the logical choice here, but it doesn't seem to be working. My sense is that the Map needs to be refreshed but I can't seem to figure this one out.
I'm sure I'm missing something fundamental here; Thanks in advance for your time!
function DrawPointAndZoom() {
// Get currently entered lat/long.
var lat = $('#SiteLatitude').attr('value');
var long = $('#SiteLongitude').attr('value');
var latLongPoint = new esri.geometry.Point(long, lat, new esri.SpatialReference({ wkid: 4326 }));
//Draw point
var symbol = new esri.symbol.SimpleMarkerSymbol().setSize(8).setColor(new dojo.Color([255, 0, 0]));
var graphic = new esri.Graphic(latLongPoint, symbol);
var infoTemplate1 = new esri.InfoTemplate();
infoTemplate1.setTitle("point1");
infoTemplate1.setContent("test point 1");
graphic.setInfoTemplate(infoTemplate1);
map.graphics.add(graphic);
map.centerAndZoom(latLongPoint, 15);
}
95% of the time, anything that doesn't work with a Point in the JS API is due to the spatialreference being wrong. :)
Check that your map's SR (map.spatialreference.wkid) is the same as the point's (4326, as you've defined it here.) You may need to use everyone's favourite function, geographicToWebMercator if the map is using one of its usual Web Mercator coordinate systems.
Edited with details from Tony's comment/answer:
var webMercPoint = esri.geometry.geographicToWebMercator(latLongPoint)
{Missing code here}
map.centerAndZoom(webMercPoint, 15);
Yes! thanks for taking the time to respond. I went down that hole yesterday and tried it with a webMercatorPoint... and viola it worked!
var webMercPoint = esri.geometry.geographicToWebMercator(latLongPoint)
{Missing code here}
map.centerAndZoom(webMercPoint, 15);
Much Appreciated!

ZoomTo boundingBox in SearchBox.onSelect with HERE maps and place

I am using nokia.places.widget.SearchBox together with nokia.maps.map.Display.
You can use onSelect function of the SearchBox to perform operations when a user picks an items from the results list.
What I need to do is center and zoom the map to the picked place. My problem is concerning zooming because I don't know what level to use.
I noticed that some places have boundingBox (to use with the zoomTo function of the Display component) property but other doesn't. I could use category ('administrative-region', 'street-square', etc.) but it is other than precise and moreover I can't find a list of possible category codes.
Any suggestion?
To get the map to move/zoom to a location when a suggestion is chosen, you will need to implement an onResults handler:
var fromSearchBox = new nokia.places.widgets.SearchBox({
targetNode: "fromSearchBox",
template: "fromSearchBox",
map: map,
onResults: function (data) {
// Your code goes here //
}
});
As you noticed the data field may or may not hold a bounding box. This is because only a few locations cover a defined area, most are point addresses.
For the subset which have a boundingbox you can do the following:
if (data.results.items[0].boundingBox){
map.zoomTo(data.results.items[0].getBoundingBox());
}
For the remainder the answer will depend upon what you are trying to achieve, but you could try any of the following:
Move to the location on the map without altering the zoom. (i.e. let the user decide)
map.set("center", data.results.items[0].position);
Move to the specified bounding box for a point object at the
specified location.
var obj = new nokia.maps.map.StandardMarker(startPoint);
map.zoomTo(obj.getBoundingBox());
Or alternatively: map.zoomTo(nokia.maps.geo.BoundingBox.coverAll([startPoint]));
Define a bounding box surrounding the point location and zoom to that instead
startPoint =data.results.items[0].position;
bottomLeft = new nokia.maps.geo.Coordinate(startPoint.latitude - 0.1,
startPoint.longitude + 0.1);
topRight = new nokia.maps.geo.Coordinate(startPoint.latitude + 0.1,
startPoint.longitude - 0.1);
map.zoomTo(nokia.maps.geo.BoundingBox.coverAll([topRight, bottomLeft]));
Additionally, Display.zoomTo() can also take an additional parameter, so if you use map.zoomTo(BoundingBox, true) you will also keep the current center for the map on screen, and this may give more context to a user.

Erratic overlay behavior with custom projection, Google Maps API v3

I want to browse a single image with the Google Maps API, for which I've defined my own projection. I wanted to use a GroundOverlay instead of several image tiles, because I only have one small-resolution image, but I wanted it to still be zoomable. However, I get some erratic behavior when trying to work with this projection:
No overlays show up at all at zoom level 0.
At zoom level 1 and higher, Markers show up, but GroundOverlays still don't.
However, I can get GroundOverlays to show up very briefly, if I zoom out from any level. It will only show while it's zooming out and disappear again immediately. Also, while it does show up shortly, it does not show up at the right coordinates, but the Markers do.
I'm rather new to the API, so I would not be surprised if it was a simple oversight on my part, but I just can't see what could cause this. Here is the code for my projection, which just maps the lat/lng linearly to map coordinates:
function EvenMapProjection() {
var xPerLng = 512/360;
var yPerLat = 512/180;
this.fromLatLngToPoint = function(latlng) {
var x = (latlng.lng()+180)*xPerLng;
var y = (latlng.lat()+90)*yPerLat;
console.log('Lng', latlng.lng(), 'Lat', latlng.lat(), '-> Point', x, y);
return new google.maps.Point(x, y);
};
this.fromPointToLatLng = function(point) {
var lat = point.y/yPerLat-90;
var lng = point.x/xPerLng-180;
console.log('Point', point.x, point.y, '-> Lng', lng, lat);
return new google.maps.LatLng(lat, lng);
};
}
An example of what I'm trying to do without the projection (using the default Mercator projection):
http://95.156.209.71/tmp/a.html
The same example with the projection as defined above:
http://95.156.209.71/tmp/b.html
And finally an example using the projection but without the GroundOverlay, and instead just using tiled images (always the same image):
http://95.156.209.71/tmp/c.html
The last link also shows the Marker at LatLng(0, 0) appear at zoom level 1 (or higher), but not at level 0.
Is there something I'm just missing, or some buggy code, or is this actually a problem in the API?
I just found out that my mistake was in the definition of the ground overlay. I was at zoom level 0, which meant that I set the bounds for the overlay from (-90,-180) to (90,180), but the API seems to have issues with these levels, because they wrap longitude, hence I got weird errors. I adjusted it to be at level 1 for minimum zoom, and set the overlay from (-45,-90) to (45,90), and now it all works fine.

Wrapping latitude and longitude points with a 20m by 20m box (Google Maps API V3)

I am having a hard time trying to figure out how to wrap a Lat/Lng point with a rectangle that is 20meters by 20meters.
Use-case:
> Click on a marker on the Google map
< Infowindow opens
> Click a button called 'Wrap' on the Infowindow
< Automatically create a 20x20m box with the marker dead center
I have no issue creating the rectangle (square rather) on the map I just need to know how to compute the border of the square in Lat/Lng.
On a normal grid I would get the NW and SE points by:
marker_nw_y = marker_y + 10 (meters)
marker_nw_x = marker_x - 10
marker_se_y = marker_y - 10
marker_se_x = marker_x + 10
From there I could create the graphic square etc.. But with Lat/Lng it gets more complicated because changing the degree between two points is different depending on where you are.
How could I do this? Manipulating the Haversine formula? Instead of solving for 'distance' I would need to rearrange and solve for one of the coordinates, but rearranging that formula is difficult and im not sure whether my results are even right.
I believe this question includes code that should let you accomplish what you're looking for.
I would use Mike Williams' eshapes library which I ported to the Google Maps API v3 to make squares with a "radius" of 20*sqrt(2)/2 meters.
example using my port of Mike Williams' eshapes library
The click listener would be:
google.maps.event.addListener(map, "click", function(evt) {
var marker = new google.maps.Marker({ position: evt.latLng, map: map});
var square = google.maps.Polyline.RegularPoly(evt.latLng,20*Math.sqrt(2)/2,4,0,"#ff0000",1,1);
square.setMap(map);
});
working example
Simpler working example based off alternate answer in link from Kelvin Mackay

Categories