I have this geojson
{
"type":"FeatureCollection",
"features":[
{
"type":"Feature",
"geometry":{
"type":"Point",
"coordinates":[
-75.70439994335175,
4.72285137053331
]
},
"properties":{
"category":"pajaros",
"icon":{
"iconUrl":"http:\/\/tupale.co\/milfs\/images\/secure\/?file=150\/b93a3b673df42a1eb5ca85ffcfa21389.jpg\u002674",
"iconSize":[
60
]
},
"563":"",
"564":"b93a3b673df42a1eb5ca85ffcfa21389.jpg",
"567":"-75.70439994335175 4.72285137053331 18",
"title":"Semillero andino ( hembra )",
"566":"Semillero andino ( hembra )",
"localizacion":"-75.70439994335175 4.72285137053331 18 ",
"description":"Contenido del json",
"control":"024a69ad3b495e5c323402211bc7aa97",
"latLng":[
-75.70439994335175,
4.72285137053331
],
"time":1467590201,
"name":1480263964
}
}
]
}
And this function
/**
* This is where your '.addLayer()' used to be, instead
* add only the source without styling a layer
*/
map.addSource('places', {
'type': 'geojson',
// 'data': stores
'data': 'http://localhost/tupali/cache/45.json'
});
map.addLayer({
'id': 'points',
'type': 'symbol',
'source': 'places',
'layout': {
// get the icon name from the source's "icon" property
// concatenate the name to get an icon from the style's sprite sheet
'icon-image': ['concat', ['get', 'iconUrl'], '-15'],
// get the title name from the source's "title" property
'text-field': ['get', 'title'],
'text-font': ['Open Sans Semibold', 'Arial Unicode MS Bold'],
'text-offset': [0, 0.6],
'text-anchor': 'top'
}
});
});
How i can get the iconUrl and icon size from geojson ?
i try " 'icon-image': ['concat', ['get', 'icon'], '-15'],"
but get any array and I don't how explode it.
" Image "{"iconUrl":"http://localhost//tupali/milfs/images/secure/?file=150/e1b0013409d0ed4a67c292999928c295.jpg&74","iconSize":[60]}" could not be loaded. "
Mapbox-GL-JS can't load images by URL in this way. You need to first add the images you need, using map.loadImage() and map.addImage().
https://docs.mapbox.com/mapbox-gl-js/api/#map#loadimage
Related
I am having difficulty wrapping my head around MapBox GL. I am coming from a Leaflet background, and am finding some of the abstractions hard to understand.
I work with a lot of GPS trip log data, and need to do things like display a fragment of a trip, hilight a section of it in a color, put markers on it with custom pins. Another common function is to mark all units on a map with pins that differ by some status. eg: Last Reported, Fuel Level, etc.
To create markers, I currently have a helper objectthat spits out some js.
public string EmitJs()
{
Debug.WriteLine("Emit Marker");
StringBuilder sb = new StringBuilder();
sb.AppendFormat("var container{0} = document.createElement('div');", UniqueId).AppendLine();
sb.AppendFormat("container{0}.className = '{1}';", UniqueId, ContainerCss).AppendLine();
sb.AppendFormat("var popup{0} = new mapboxgl.Popup({{ offset: 25 }}).setHTML(", UniqueId).AppendLine(); // escape { } with {{ }} in String.Format
sb.AppendFormat(" \'{0}\'", Point.Label).AppendLine();
sb.AppendLine(");");
sb.AppendFormat("var marker{0} = new mapboxgl.Marker(container{1}, {{", UniqueId, UniqueId).AppendLine();
sb.AppendLine(" anchor: 'bottom'");
sb.AppendLine("})");
sb.AppendFormat(" .setLngLat({0})", Point.EmitForMapBox()).AppendLine();
sb.AppendFormat(" .setPopup(popup{0})", UniqueId).AppendLine();
sb.AppendLine(" .addTo(map);");
sb.AppendLine();
return sb.ToString();
}
this returns:
var container5 = document.createElement('div');
container5.className = 'marker marker-pu-green';
var popup5 = new mapboxgl.Popup({ offset: 25 }).setHTML(
'<p><b>Name:</b> 1310 PU2003<br /><b>Last Reported:</b> 25/03/2020 11:16:35<br /><b>Last Status:</b> Operating</p>'
);
var marker5 = new mapboxgl.Marker(container5, {
anchor: 'bottom'
})
.setLngLat([151.047211,-32.537003])
.setPopup(popup5)
.addTo(map);
This lets me display images overlaid on a map, governed by CSS. This is fairly straightforward.
The GeoJson FeatureCollection, contains Feature's that represent individual markers. I can see that the icon properties in the Layer object are meant to represent named values in some spritesheet, but damned If I can figure where this is, and how to upload to it. I've been all thru Studio, and its documentation. It seems to refer to to a 'sprites': 'path to file' json property that you can't actually set or upload.
In addition, it wants the sprites to be in SVG format., despite casting them back to raster as PNG. Thats a different question, but I need to convert a bunch of PNG's to SVG format as a result, if I ever get this working.
The Question
How do I add custom sprites to my MapBox style so I can reference them in GeoJson icon properties.
** Edit 27 Mar 202 **
The following is cut from the page. The polylines are not included (they work well), just the lines to try an make a symbol layer work. The image paths are local to my dev environment and are valid. They would be rewritten when moved to prod.
<script id="mapScript" type="text/javascript">
var baseUrl = '/';
mapboxgl.accessToken = '[snip]';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/fleetlogixmaps/ck6r4knm10smq1irxvnvfmq1b',
center: [148.381332397461,-21.4777641296387],
setMinZoom: 13,
setMaxZoom: 18,
zoom: 15,
});
map.loadImage('http://localhost:7933/Images/pin_path_start_128x128.png', function(error, image) {
if (error) throw error;
map.addImage('pathStart', image);
});
map.loadImage('http://localhost:7933/Images/pin_path_end_128x128.png', function(error, image) {
if (error) throw error;
map.addImage('pathEnd', image);
});
map.loadImage('http://localhost:7933/Images/pin_event_start_128x128.png', function(error, image) {
if (error) throw error;
map.addImage('eventStart', image);
});
map.loadImage('http://localhost:7933/Images/pin_event_end_128x128.png', function(error, image) {
if (error) throw error;
map.addImage('eventEnd', image);
});
var markers = {
'type': 'FeatureCollection',
'features': [
{
'type': 'Feature',
'geometry': {
'type': 'Point',
'coordinates':
[148.370483398438,-21.4804000854492],
'properties': {
'title': 'Path Start',
'icon': 'pathStart'
}
}
},
{
'type': 'Feature',
'geometry': {
'type': 'Point',
'coordinates':
[148.381332397461,-21.4777641296387],
'properties': {
'title': 'Event Start',
'icon': 'eventStart'
}
}
},
{
'type': 'Feature',
'geometry': {
'type': 'Point',
'coordinates':
[148.385375976563,-21.4819965362549],
'properties': {
'title': 'Event End',
'icon': 'eventEnd'
}
}
},
{
'type': 'Feature',
'geometry': {
'type': 'Point',
'coordinates':
[148.393402099609,-21.4885864257813],
'properties': {
'title': 'Path End',
'icon': 'pathEnd'
}
}
}
]
};
map.on('load', function() {
map.addLayer({
'id': 'markers',
'source': 'markerSrc',
'type': 'symbol',
'layout': {
'icon-image': ['get', 'icon'],
'icon-size': 0.25,
},
});
});
</script>
You're confusing Markers (HTML elements that sit over the map) with Symbol layers (images that exist within the map, tied to a source like a GeoJSON).
Markers don't have anything to do with Sprites: you style them with CSS. See this example.
If you do want to use a Symbol layer, the easiest way to use custom images is to upload them to Mapbox Studio, which will generate the Sprite file for you.
Alternatively, you can use loadImage to load images dynamically.
I try to fill a treelist with remote data via a ajax proxy but the treelist shows only the first level and try to reload the sub levels even though the json response contain a complete tree structure. Fiddle link: https://fiddle.sencha.com/#view/editor&fiddle/33u9
When i try to expand the node 'SUB a' (or set the expanded property to true) the store trys to reload the node.
Why is the tree structure from the json response not honored?
Thanks in Advance.
The backend response looks like:
{
"data": {
"root": [
{
"leaf": true,
"text": "Server"
},
{
"leaf": true,
"text": "Storage"
},
{
"text": "SUB a"
"children": [
{
"leaf": true,
"text": "Modul A - 1"
},
{
"leaf": true,
"text": "Modul A - 2"
}
],
},
{
"leaf": true,
"text": "Modul B"
}
]
},
"success": true
}
The used reader config is
reader: {
type: 'json',
rootProperty: 'data.root',
successProperty: 'data.success',
},
After playing around i use the following workaround:
getNavigation: function() {
var me = this,
tree = me.getView().down('navigationtree'),
store = tree.getStore(),
node = store.getRoot();
Ext.Ajax.request({
url: '/getnav',
method: 'POST',
success: function(response) {
var obj = Ext.decode(response.responseText),
childs = obj.data.root;
tree.suspendEvents();
node.removeAll();
childs.forEach(function(item) {
node.appendChild(item);
});
tree.resumeEvents();
},
failure: function(response) {
//debugger;
console.log('server-side failure with status code ' + response.status);
}
}).then(function() {
//debugger;
}
);
}
The funny things is that only the first level of the tree has to be added all following sub-levels are added automaticaly.
I am using webix to show some tree table data.
webix.ready(function () {
grida = webix.ui({
container: "testB",
view: "treetable",
columns: [
{ id: "id", header: "", css: { "text-align": "right" } },
{
id: "SerialNo", header: "Serial No", width: 250,
template: "{common.treetable()} #SerialNo#"
}
],
url: "/Test/GetTreeItem",
autoheight: true,
});
});
This loads the items perfectly.
Parents;
[{"id":11583,"Id":11583,"SerialNo":"12476127654","webix_kids":1},{"id":11584,"Id":11584,"SerialNo":"125235463","webix_kids":1},{"id":11585,"Id":11585,"SerialNo":"21385423348956","webix_kids":1},{"id":11586,"Id":11586,"SerialNo":"253346346346","webix_kids":1},{"id":11587,"Id":11587,"SerialNo":"123123","webix_kids":1},{"id":11588,"Id":11588,"SerialNo":"52354263","webix_kids":1},{"id":11589,"Id":11589,"SerialNo":"12344444","webix_kids":1},{"id":11590,"Id":11590,"SerialNo":"12344444","webix_kids":1},{"id":11591,"Id":11591,"SerialNo":"12344444","webix_kids":1},{"id":11592,"Id":11592,"SerialNo":"151515","webix_kids":1}]
However when I click the plus button, server returns (I can see the json string when I debug the code) the json but webix not appending the data underneath the parent.
Kids of parent "id":11587;
[{"id":11583,"Id":11583,"SerialNo":"12476127654","webix_kids":1},{"id":11592,"Id":11592,"SerialNo":"151515","webix_kids":1}]
id of data object must be unique per component.
Currently, you have for top level
{
"id": 11583,
"Id": 11583,
"SerialNo": "12476127654",
"webix_kids": 1
},
and in kids data you have
{
"id": 11583,
"Id": 11583,
"SerialNo": "12476127654",
"webix_kids": 1
},
both items share the same id, so treetable doesn't add a new item.
Correcting the JSON output solved my problem.
For the parents;
{
"parent":"0",
"data":[
{
"Id":11584,
"id":11584,
"SerialNo":"125235463",
"webix_kids":1
},
{
"Id":11599,
"id":11599,
"SerialNo":"3444",
"webix_kids":1
}
]
}
For the kids;
{
"parent":11599,
"data":[
{
"id":11583,
"Id":11583,
"SerialNo":"12476127654",
"webix_kids":1
},
{
"id":11592,
"Id":11592,
"SerialNo":"151515",
"webix_kids":1
}
]
}
I send data inside an array of objects:
[{name: "x1" , data: [ ... ]}, {name: "x2" , data: [ ... ]} ... ]
Is it possible to show series name in the data point tooltip?
Yes, you can pass a tooltip formatter in the configuration, and the data object contains the series name:
new Contour({
el: '.chart',
tooltip: {
formatter: function (d) {
return d.series + ': ' + d.x + ', ' d.y;
}
}
})
.cartesian()
.line([1,2,3,3,5,6])
.tooltip()
.render();
I have items endpoint which contains a list of embedded images. The scheme looks like:
_schema = {
'name': required_string, # group name
'description': {
'type': 'string',
'maxlength': 140,
},
'images': {
'type': 'list',
'scheme': {
'type': 'objectid',
'data_relation': {
'resource': 'images',
'embeddable': True,
'field': '_id',
}
},
}
}
So I'm trying to make a request to the items endpoint to get embedded objects
/items/549ae47f4fb9041305403292?embedded={"images":1}
But instead of embedded images I receive just the regular object with the list of images _ids.
Here is an example of object:
{
"_updated": "Wed, 24 Dec 2014 16:06:23 GMT",
"name": "New Item",
"images": [
"549ae47f4fb904130540328b",
"549ae47f4fb904130540328e",
"549ae47f4fb9041305403291"
],
"_created": "Wed, 24 Dec 2014 16:06:23 GMT",
"_id": "549ae47f4fb9041305403292",
"_etag": "949e3b731823bb2c08682ba4b6696b86856ef941",
"description": "The best item ever"
}
I tried to convert images ids in list to objectids, but it doesn't help. Any ideas why it doesn't work? Thanks
You have an incorrect schema definition. Replace scheme with schema when defining the images list:
_schema = {
'name': required_string, # group name
'description': {
'type': 'string',
'maxlength': 140,
},
'images': {
'type': 'list',
'schema': { # this was 'scheme' in your def
'type': 'objectid',
'data_relation': {
'resource': 'images',
'embeddable': True,
'field': '_id',
}
},
}
}
It will then properly embed your list of images.