Mapbox 3D building mapping dynamically - javascript

I am trying to achieve dynamic 3D model of a building which i choose during search criteria, so far the code i have done is below.
map.on('load', function () {
// Listen for the `geocoder.input` event that is triggered when a user
// makes a selection
geocoder.on('result', function (ev) {
debugger;
var layers = map.getStyle().layers;
var styleSpec = ev.result;
var styleSpecBox = document.getElementById('json-response');
var styleSpecText = JSON.stringify(styleSpec, null, 2);
var syntaxStyleSpecText = syntaxHighlight(styleSpecText);
styleSpecBox.innerHTML = syntaxStyleSpecText;
map.addSource('floorplan', {
// GeoJSON Data source used in vector tiles, documented at
// https://gist.github.com/ryanbaumann/a7d970386ce59d11c16278b90dde094d
'type': 'geojson',
'data': 'https://docs.mapbox.com/mapbox-gl-js/assets/indoor-3d-map.geojson'
});
map.addLayer({
'id': 'room-extrusion',
'type': 'fill-extrusion',
'source': 'floorplan',
'paint': {
// See the Mapbox Style Specification for details on data expressions.
// https://docs.mapbox.com/mapbox-gl-js/style-spec/#expressions
// Get the fill-extrusion-color from the source 'color' property.
'fill-extrusion-color': ['get', 'color'],
// Get fill-extrusion-height from the source 'height' property.
'fill-extrusion-height': ['get', 'height'],
// Get fill-extrusion-base from the source 'base_height' property.
'fill-extrusion-base': ['get', 'base_height'],
// Make extrusions slightly opaque for see through indoor walls.
'fill-extrusion-opacity': 0.5
}
});
});
});
As i have tried to add this json URL (https://docs.mapbox.com/mapbox-gl-js/assets/indoor-3d-map.geojson) which i have found on this link: https://docs.mapbox.com/mapbox-gl-js/example/3d-extrusion-floorplan/
It only shows a fixed location in 3D of a building which is given on the second URL.
Now actually I want to achieve a specific 3D building on the map as only dynamic when i use search criteria.

The GeoJSON data at this file which you are using contains polygon features along with coordinates representing where in the geographic space these polygons are located. The extrude polygons for 3D indoor mapping example which you are referencing creates the "3D model" being display by taking the two-dimensional geometries specified by the polygon features in the GeoJSON used as a source, and then adding a corresponding layer which makes use of fill extrusions to visually extrude these two-dimensional polygons into three dimensions.
So, unless you change the contents of the GeoJSON file used as the source, it is expected behavior that the "3D model" of the building will continue to display at the same geographic location. If the geocoder returns the location of a particular building based on the input search criteria, you will still need to specify which GeoJSON polygons should be extruded to create the extruded model of the building. The Geocoding API response body for an address search itself likely won't be enough for this, since only a coordinate will be returned representing the location of this POI. As such, you would need to integrate some custom building data or another custom workflow to generate the polygons needed to extrude a variety of building polygon geometries.

Related

How to use the viewParams option of a GeoServer layer defined as a SQL View in a Leaflet?

I set up a PostGIS database that I added in GeoServer via a parameterized SQL view. The parameter I set is 'year' : it permits to select only the polygons of my database that have this year as a property.
I know this worked because I can successfully use the layer preview of GeoServer on my layer with the local link : http://localhost:9999/geoserver/cite/wms?service=WMS&version=1.1.0&request=GetMap&viewParams=year:0&layers=cite%3Achoix_annee&bbox=-56.6015625%2C25.16517336866393%2C-16.875%2C47.040182144806664&width=768&height=422&srs=EPSG%3A404000&styles=&format=application/openlayers
The interesting option there is 'viewParams=year:0'.
In Leaflet, I used the following code to import my layer via wms:
<script>
// Find our map id
var map = L.map('map');
var wmsLayer = L.tileLayer.wms('/geoserver/gwc/service/wms', {
layers: 'cartowiki:choix',
format: 'image/png',
transparent: true,
viewparams: 'year:1000'
}).addTo(map);
// Set the map view
map.setView([46.988332, 2.605527], 2);
</script>
It works the first time but then GeoWebCache intervenes and prevents me from getting results fitted to the year I'm asking, it always gives me the results for the first year I asked. I tried to specify the year parameter with a regular expression in the tile caching module of my layer but it doesn't work and I cannot figure out why.
This is a view of my settings in geoserver: geoserver settings
Thanks,
you have to dynamically set viewparams value then refresh wms layer

How can I get the shape of a Road Element using the Javascript API?

I want to highlight a specific section of a road on my map. The user should be able to click on a map and using the Location of the click, I want to highlight the closest road element.
In the Here Android SDK, the RoadElement can do exactly what I want: I can pass some coordinates and use getGeometry() to obtain the exact shape of the road element.
However, I couldn't find something similar to this in the javascript SDK. I tried using Reverse Geocoding:
var geocodingParams = {
lat: road.lat,
lng: road.lng,
mode: 'retrieveAddresses',
maxresults: '1',
additionaldata: ['IncludeShapeLevel', 'postalCode'],
prox: road.lat + ',' + road.lng
};
this.geoCodingService.reverseGeocode(geocodingParams, onResult, null);
This way, I can find the closest road, but I don't get accurate shape data. In the Results View, there is only the Bounding Box (Location.MapView.BottomRight and Location.MapView.TopLeft).
How can I achieve something similar to the RoadElements, using the Javascript API?
Our routing APIs return the shape points along a route. So given a set of start and stop waypoints the JavaScript SDK routing API will give the route shape.
Example code is included on this page:
https://developer.here.com/documentation/maps/dev_guide/topics/routing.html
Another alternative will be to use the Advanced fleet telematics API and look into the datasets yourself.

Adding onclick call for mapbox icons

I'm struggling with adding a click event to points on my mapbox map. I'm having to add the source from a backend sql query into a hbs template. I've tried just adding business1 as the source without the for loop but i get an invalid geojson object warning. If i add just 'locations' as the id obviously it gives me a warning that the id already exists on the map.
So how i can add an onclick call for dynamics id's?
How i load the points
business1 = {{{businesses}}}
for(i=0;i<business1.length;i++){
// Add the data to your map as a lyer
map.addLayer({
id: 'locations'+[i],
type: 'symbol',
minzoom: zoomThreshold,
// Add a GeoJSON source containing place coordinates and information.
source: {
type: 'geojson',
data: business1[i]
},
layout: {
'icon-image': 'circle-stroked-15',
'icon-allow-overlap': true,
}
});
}
How the map click is called-with the added [i] just to show what i'm thinking
map.on('click', function(e) {
var features = map.queryRenderedFeatures(e.point, {
layers: ['locations'+[i]] // replace this with the name of the layer
});
if (!features.length) {
return;
}
What else i've tried-but always returns the same location regardless of what is clicked
for(i=0; i<business1.length;i++){
var features = []
var feature = [i]
feature.dataPosition = i;
var clickedNameClicked = names[this.dataPosition]
console.log(clickedNameClicked)
features.push(business1[i]);
}
I definitely don't recommend adding a new source / layer for each business. That will not be performant if you have a bunch of layers, and I think it's adding too much complexity to your on click logic.
I've tried just adding business1 as the source without the for loop but i get an invalid geojson object warning.
This is a strong indication that there's something awry with your business data that you should address before adding it to your map and worrying about click events. I would recommend using a tool like http://geojsonlint.com/ to see what is going on there.
Once you have valid geojson, it will be much easier to add click events to your icons. https://docs.mapbox.com/mapbox-gl-js/example/queryrenderedfeatures-around-point/
⚠️ Disclaimer: I currently work at Mapbox ⚠️

Get coordinates from title in Mapbox GL JS

Is it possible to get a marker/point's coordinates, based on it's title?
I'm, loading in several points, which all have specific IDs as their title.
What i need now, is the ability to flyTo one of these markers when i enter the view and one is highlighted.
I'm highlighting with the below function, and would like to implement the flyTo in it.
$scope.$on('$ionicView.afterEnter', function(){
if(ShowOnMap.story()){
var storyId = ShowOnMap.story();
map.setFilter("highlight", ["==", "title", storyId]);
map.flyTo({
center: [---->storyId<-----],
zoom: 18
});
ShowOnMap.setStory(false);
}
});
So all i need, is a way to get the position(coordinates) of the point, based on the ID/Title i receive.
Bonus info: The storyID is sent from another view, and i am currently not able to send the coordinates and would like to avoid requesting the coordinates from server, based on ID.

Drawing lines with geoJSON data in D3.js

I'm trying to draw US state outlines with the D3 framework (http://mbostock.github.com/d3/) but am having issues generating the actual SVG data. I've written my code to follow the Chloropleth example (as it most closely resembles what this project needs), made sure the supplied data is in geoJSON format, and AFAIK have the backend half of this working fine.
The problem is that when I view the DOM, the <svg> object contains only one <g> element (which I created manually, per the example), and none of the child <path> elements that should under it. My code seems fairly identical to the example, and my data appears to look correct, though I am outputting MultiPolygons instead of the Polygon object that the example uses.
Our app is a RoR project with jQuery (we're only using D3 for the SVG and geography features). The test page tries to create an <svg> element under a div called theArea, based upon the selection from a dropdown select of U.S. states:
$(document).ready( function() {
$("#chooser_state").change( function() {
var status = "#status";
var statebox = "#chooser_state";
var theArea = "#theArea"
var url = "/test/get_state_geom";
var data = { state: $(statebox).val() };
$(status).text("Request sent...");
$.post(url, jQuery.param(data), function(resp) {
$(status).text("Received response: " + resp["message"]);
$(theArea).empty();
var path = d3.geo.path();
var svg = d3.select(theArea).append("svg");
var state = svg.append("g").attr("id", "state_view");
var features = resp.payload.features;
$(status).text("Created SVG object");
state.selectAll("path")
.data(features)
.enter()
.append("path")
.attr("d", path );
});
});
});
The data we're feeding D3 looks like this:
{
'type' => 'Feature',
'id' => '01',
'properties' => {
'name' => 'Colorado'
},
'geometry' => {
'type' => 'MultiPolygon',
'coordinates' => [
[
[
[
-106.190553863626,
40.9976070173843
],
[
-106.061181,
40.996998999999995
],
< -- and so on -- >
]
]
]
}
}
Can someone clue me in to what we're doing wrong? I am new to geo and GIS stuff. I suspect the problem lies with the data() function, as it looks like it should be creating the blank <path> objects for each Feature (though we have only one, at the moment), but the D3 documentation seems unclear (and difficult to understand).
EDIT: Just wanted to add that the geoJSON we generate was created by the geoJSON extension for the GeoRuby gem. The actual map lines were sourced from the consolidated data that US Census Bureau's cartographic boundary files, which were converted to SQL and saved with postGIS. Part of me suspects the geoJSON extension is doing something wrong, so that is my next avenue of attack.
After giving up on this and then coming back, I noticed that my FeaturesCollection was not, in fact, a collection. There's a small detail that is easy to overlook when examining geoJSON samples: the contents of the FeaturesCollection is an array of hashes, not a single hash.

Categories

Resources