loading GeoJSON markers into MapBox - javascript

I'm trying to figure out how to load GeoJSON list on lon/lat coordinates into a MapBox map. I think I'm close, I just can't seem to get it actually working.
I have a demo page set up here: http://sandbox.charliehield.com/mapbox/
Here's the GeoJSON file:
{
"type": "MultiPoint",
"coordinates": [
[
"-105.277803",
"40.006977"
],
[
"-93.304988",
"44.947198"
],
[
"151.206990",
"-33.867487"
]
]
}
The HTML is simply:
<div id="map"></div>
And the JS:
var map = mapbox.map('map');
map.addLayer(mapbox.layer().id('examples.map-zr0njcqy'));
map.ui.zoomer.add();
// example.geojson is a well-formed GeoJSON document. For this
// style, the file must be on the same domain name as the map,
// or loading will not work due to cross-domain request restrictions
var markers = mapbox.markers.layer().url('markers.geojson');
mapbox.markers.interaction(markers);
map.addLayer(markers);
// Zoom and center the map
map.zoom(2).center({ lat: 39.74739, lon: -105 });

Looks like you need to format your geojson a little more explicitly with a geometry object and key value pairings. See http://mapbox.com/mapbox.js/example/custom-marker-tooltip as an example.

I had the same issue loading geojson to my mapbox map. The comments in the JS actually pointed out the reason: there are cross-domain request restrictions.
You could check the same origin policy and you would want to run the application somewhere else.

Related

Mapbox-gl Hosted S3 - addsource

I am working on this project where I want to add relatively dynamic data (updating every 15minutes) to a mapbox-gl via a serverless solution. I followed this excellent guide on creating serverless vector tiles and have the base tiles working.
My question is now how would you achieve adding a geojson point layer to the map (hosted on a simple HTML page), using something like:
var map = new mapboxgl.Map({
container: 'map',
style: style: "https://{domain}/bright.json",
});
var url = 'https://{domain}/geojsonfile.json'
map.addSource('geojsonfile', {
'type': 'geojson',
'data': url
});
map.addLayer({
'id': 'geojsonfile',
'type': 'symbol',
'source': 'geojsonfile',
'layout': {
'icon-image': 'rocket-15'
}
});
In a serverless vector environment without using Tippecanoe to convert the json file into protobuf vector tiles and instead adding the layer direct to the map from the javascript file. The above js for addsource and addlayer come from this Mapbox guide.
I can get the above js working when I pass in a mapboxgl.accessToken instead of self-hosting; however that's as far as I have been able to get. The geojson file is hosted in a CORS enabled s3 bucket.
Is the issue with loading in the source or displaying the layer? I have also tried modifying the bright.json file to handle the source and layer so that I only have to replace the s3 file, however have had no luck.
Any and all help / suggestions are much appreciated.
After quite a lot of blind trial and error, finally figured out a solution. Turns out my original script was trying to load the layer to the map on-load. However, the tile base load is configured via the style and tile files pre-load.
Therefore, the js addSource needs to be added to the map post-load and then style on-load.
this.map.on('style.load', function () {
this.pastInitialLoad = true;
this.map.addSource("geojsonfile", {
"type": "geojson",
"data": url }
);
If anyone else is stuck, these guides / sources were of great help!
https://schwanksta.com/blog/vector-tiles-introduction-pt1
http://fuzzytolerance.info/blog/2016/03/16/Leaflet-to-Mapbox-GL/
https://github.com/mapbox/mapbox-gl-js/issues/2268

Adding a Shapes files as a Layer on Mapbox Map

I have a shapes file from here. I wish to add it on a Map, similar to what is done on the web page. I am not quite sure how to proceed with it. I want to use it on Web and hence use JavaScript.
Someone suggested me to use the shapes file as a Layer on the map. But how to go about it? Anyone experience with Mapbox, Leaflet or OSM please guide.
I was finally able to add the shapes file by uploading it as a tileset to Mapbox Studio.
It provided me with a map Id and source-layer name which I was able to add as a Layer on my Mapbox map as follows:
map.addLayer({
id: '<id>',
type: 'fill',
source: {
type: 'vector',
url: 'mapbox://<map-id>' // Mapbox tileset Map ID
},
'source-layer': '<layer-name>', // name of tilesets
'paint': {
'fill-color': '#088',
'fill-opacity': 0.8,
'fill-outline-color': '#000'
}
});
In order to load a SHP file and display it on a Leaflet / Mapbox.js map, you have several Leaflet plugins that can make the task easy.
For example leaflet.shapefile (online demo where you can drop your zipped SHP and DBF files).
The data source that you mention also provides KML format, which may be easier to use.
For KML, you can use for example leaflet-omnivore:
universal format parser for Leaflet & Mapbox.js
var map = L.mapbox.map('map', 'mapbox.streets')
.setView([38, -102.0], 5);
omnivore.kml('a.kml').addTo(map);
Live example with Leaflet and leaflet-omnivore: https://plnkr.co/edit/KVXqBScBuIrAahg4VsGi?p=preview

How to display ESRI Vector base map in Openlayers 3

I am trying to add the new ESRI Vector Basemaps in OpenLayers 3. I have gotten so far as to display the layer un-styled by modifying the Mapbox Example published by OpenLayers.
Clearly I had to remove the style: createMapboxStreetsV6Style() option to get the esri layer to display. So basically the map does not know the style information to display the layer correctly.
I think it should be possible to do it because ESRI's Leaflet port and example is doing this already. I think information on esri's style IDs is available in here Leaflet code.
OpenLayers should already be able to use all this information as it is able to display Mapbox Layer. What I need help with is, how to make it use ESRI's style information.
Here's what I have so far (codepen here):
var map = new ol.Map({
layers: [
new ol.layer.VectorTile({
source: new ol.source.VectorTile({
format: new ol.format.MVT(),
tileGrid: ol.tilegrid.createXYZ({maxZoom: 22}),
tilePixelRatio: 16,
url: 'https://basemaps.arcgis.com/v1/arcgis/rest/services/World_Basemap/VectorTileServer/tile/{z}/{y}/{x}.pbf'
})
})
],
target: 'map',
view: new ol.View({
center: [0, 0],
zoom: 2
})
});
.map {
background: #f8f4f0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/openlayers/4.1.0/ol.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/openlayers/4.1.0/ol.css" rel="stylesheet"/>
<div id="map" class="map"></div>
There is a separate library, https://npmjs.com/package/ol-mapbox-style, which makes it easy to consume vector tile maps including their styles in OpenLayers. It reads the style doc and builds the whole map from it. For one of the ESRI maps you linked above, the code to get that map in OpenLayers would be
var map = new ol.Map({
target: 'map'
});
olms.apply(map, 'https://www.arcgis.com/sharing/rest/content/items/4f4843d99c34436f82920932317893ae/resources/styles/root.json?f=json');
You can replace 4f4843d99c34436f82920932317893ae with one of the other map ids listed in the Leaflet example to get the other maps.
You can also play with that code - I have created a CodePen: https://codepen.io/ahocevar/pen/xLaBVV.
#ahocevar's suggest is perfect,
esri's root.json, sprite and glyphs are not full URL, the are only last part as see below
In your example, those not full URL works, but, I have test it in mapbox js api, it failed, error is can't parse URL,
I have to change those url to a full URL, to make it works.
root_json = {
"version" : 8,
"name": "test",
//"sprite" : original_rootJson.sprite, // original is not a full URL, not work "../sprites/sprite"
// "sprite" : "https://tiles.arcgis.com/tiles/P3ePLMYs2RVChkJx/arcgis/rest/services/2020_USA_Median_Age/VectorTileServer/resources/sprites/sprite",
"sprite" : _sprite,
// "glyphs" : original_rootJson.glyphs, // original is not a full URL, not work "../fonts/{fontstack}/{range}.pbf"
// "glyphs" : "https://tiles.arcgis.com/tiles/P3ePLMYs2RVChkJx/arcgis/rest/services/2020_USA_Median_Age/VectorTileServer/resources/fonts/{fontstack}/{range}.pbf",
"glyphs" : _glyphs,
// root json specification : https://docs.mapbox.com/mapbox-gl-js/style-spec/sources/
"sources" : {
"esri" : {
"type" : "vector",
// By supplying TileJSON properties such as "tiles", "minzoom", and "maxzoom" directly in the source:
"tiles": [
// "https://tiles.arcgis.com/tiles/P3ePLMYs2RVChkJx/arcgis/rest/services/2020_USA_Median_Age/VectorTileServer/tile/{z}/{y}/{x}.pbf"
_tile_pbf
],
// "maxzoom": 14
// By providing a "url" to a TileJSON resource
// not work,yet
// "url" : "https://tiles.arcgis.com/tiles/P3ePLMYs2RVChkJx/arcgis/rest/services/Esri_Childrens_Map/VectorTileServer/tile/{z}/{y}/{x}.pbf"
// "url": "http://api.example.com/tilejson.json"
}
},
"layers": original_rootJson.layers
} // root_json

Issue with Google Maps api and GeoXML3 trying to use containsLocation

I am trying to set up a system that loads a KMZ file and displays it using google maps and then tests if the user has clicked within the bounds of a polygon created by the KMZ. I have searched all through these forums and the web and haven't found a working solution.
I am having no problem loading and reading the KMZ file and the polygon is displaying perfectly on the map. But when I try to use the polygon data returned by geoXML3 to test if a location is within the bounds then I get a variety of errors depending on how I approach it.
I am loading the geoxml3.js files locally and the parser for the KMZ files, and as I say that works fine so I won't include all that.
The KMZ file is local to the server and reads fine.
This is what I have:
<script>
var zone;
var polzone;
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 11,
center: {lat: 0, lng: 0}
});
zone = new geoXML3.parser({map: map});
zone.parse('test.kmz');
}
function testlimit(){
polzone = zone.docs[0].gpolygons[0];
console.log( google.maps.geometry.poly.containsLocation(new google.maps.LatLng("0", "0"), polzone));
}
</script>
As you can see I'm testing just with hard coded long and lattitude values and it's giving me the error "Uncaught TypeError: b.get is not a function".
The testlimit function is fired when a button is clicked.
I initially had more code but as it wasn't working, this is where I've ended up. Any help would be appreciated.
Alright, never mind then, Apparently the gpolygon variable is an array.
So it should be
polzone = zone.docs[0].gpolygons[0];
One of those days I should have stayed in bed I guess...

OpenLayers Map BoundingBox calculation

I'm using the GeoServer to hold some maps, and just a simple OpenLayers app to load and show the data (for now).
I'm successfully loading the demo data (which is in WGS84), but when it comes to my data (which is in Balkans Zone 7, EPSG:31277), when I look at the request, it seems like the BBOX is completely out of order.
I checked the BBOX from the GeoServer preview page (which is made with openLayers) and it looks like this, and works:
http://127.0.0.1:2113/geoserver/GISHome/wms?LAYERS=GISHome%3ANis11Katastar&STYLES=&FORMAT=image%2Fjpeg&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&SRS=EPSG%3A31277&BBOX=7572000,4796000,7574000,4798000&WIDTH=512&HEIGHT=512
The only thing that's different with my request is the BBOX. When copying the BBOX into my request, it works.
http://127.0.0.1:2113/geoserver/wms?LAYERS=Nis11Katastar&FORMAT=image%2Fpng&WIDTH=256&HEIGHT=256&PROJECTION=EPSG%3A31277&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&SRS=EPSG%3A4326&BBOX=-180,-90,0,90
In the GeoServer source, the bounds are somehow calculated and hardcoded. The question is, how? Is there a way not to hardcode them? How should I calculate them. I've tried adding bounds, maxExtent, resolution, I'm obviously missing something more than that here. The GeoServer works fine, I'm using the layers from QuantumGIS.
Ext.onReady(function() {
var map = new OpenLayers.Map();
var layer = new OpenLayers.Layer.WMS(
"Global Imagery",
"http://127.0.0.1:2113/geoserver/wms",
{
LAYERS:'Nis11Katastar',
format: 'image/png',
width:600,
height:400,
projection: new OpenLayers.Projection("EPSG:31277"),
}
);
Thankyou.
Oh, yes, I'm using GeoExt, but that doesn't change much.
It seems solved. I was setting the right properties, but to the WMS layer object, not to the map object. As for the bounds question, I'm just copying the bounds from the geoserver control panel.

Categories

Resources