dc.js and dc.leaflet.js; wrong type of map returned - leaflet

I'm trying to make a dashboard using dc.js. It has a few charts and a choroplethChart. It all worked fine, but I needed to add leaflet to the map. I've followed this sample and used dc.leaflet.js library, but instead of choroplethChart it returns Markers (see picture)
(this is how it looked before using leaflet)
The code is below and this is where geojson resides:
var usChart = dc_leaflet.choroplethChart("#us-chart");
usChart.width(1000)
.height(450)
.dimension(stateDim)
.group(totalDemandByStation)
.center([ 51.4963, -0.143 ])
.zoom(11)
.geojson(statesJson)
.colors(["#E2F2FF", "#C4E4FF", "#9ED2FF", "#81C5FF", "#6BBAFF", "#51AEFF", "#36A2FF", "#1E96FF", "#0089FF", "#0061B5"])
.colorDomain([0, max_state])
.colors(['#fff7ec','#fee8c8','#fdd49e','#fdbb84','#fc8d59','#ef6548','#d7301f','#b30000','#7f0000'])
.colorAccessor(function(d,i) {
return d.value;
})
.featureKeyAccessor(function(feature) {
return feature.properties.name;
})
.renderPopup(true)
.popup(function(d,feature) {
return feature.properties.name+" : "+d.value;
})
.legend(dc_leaflet.legend().position('bottomright'));
//https://github.com/dc-js/dc.js/issues/419
usChart.on("preRender", function(chart) {
chart.colorDomain(d3.extent(chart.data(), chart.valueAccessor()));
})
usChart.on("preRedraw", function(chart) {
chart.colorDomain(d3.extent(chart.data(), chart.valueAccessor()));
})

I'm not an expert here, but the choropleth is expecting map data rather than point data. The features in your geojson are points:
{
"crs": {
"properties": {
"name": "urn:ogc:def:crs:OGC:1.3:CRS84"
},
"type": "name"
},
"features": [
{
"geometry": {
"coordinates": [
-0.013071299999987,
51.510716
],
"type": "Point"
},
"properties": {
"id": "940GZZDLALL",
"labelX": 30,
"lines": [
{
"name": "DLR"
}
],
"name": "All Saints",
"tfl_intid": 850
},
"type": "Feature"
},
{
"geometry": {
"coordinates": [
0.061052699999989,
51.51427850000001
],
"type": "Point"
},
"properties": {
"id": "940GZZDLBEC",
"labelX": -30,
"lines": [
{
"name": "DLR"
}
],
"name": "Beckton",
"tfl_intid": 895
},
"type": "Feature"
},
...
To draw a choropleth, Leaflet will need features whose types are Polygon.
So my guess is that Leaflet is punting and drawing markers

Related

Mapbox GL style line color based on property text value

I'm trying to style a single GeoJSON source with different line colors based on a feature property using react-map-gl, and I can't find a way to get set the color of lines in a smart way.
Most of all, I would love to apply a function on the dataset to return the color of my own choosing based on a feature property value, but so far I haven't fount anything about it. If you know about it, please point in my direction:)
If I have the following GeoJSON:
{
"type": "FeatureCollection",
"name": "lineData",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [
{ "type": "Feature", "properties": { "Need": "Urgent" }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ 10.653823175868171, 59.676506860589157 ], [ 10.652881996887283, 59.675443989456632 ] ] ] } },
{ "type": "Feature", "properties": { "Need": "Starting" }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ 10.658536710768077, 59.680279341285896 ], [ 10.65787427600862, 59.680222775937636 ] ] ] } },
{ "type": "Feature", "properties": { "Need": "Medium" }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ 10.653224904719789, 59.67859470385492 ], [ 10.653201052045171, 59.678557551379008 ] ] ] } },
]
}
I would like to be able to style this source data with different line colors based on the property "Need". Say, urgent becomes red, medium becomes yellow, and starting becomes green.
I've read about styling expressions at mapbox, and I believe the "feature-state" is key to solving this, but I cant wrap my head around how to get the color converted from a feature.
If this in the rendering:
<Source id="my-data" type="geojson" data={TheDataFileWithSomeData}>
<Layer {...layerStyleTheLines } />
</Source>
Then I want a layer styling something like this (not working):
const layerStyleTheLines = {
id: 'style_it_to_red',
type: 'line',
paint: {
'line-color': [
[["==", ["feature-state", "Need"], "Urgent"],"red"],
[["==", ["feature-state", "Need"], "Medium"],"yellow"],
[["==", ["feature-state", "Need"], "Starting"],"green"]
],
'line-width': 3,
}
};
Thanks for all your help!
I've read about styling expressions at mapbox, and I believe the "feature-state" is key to solving this, but I cant wrap my head around how to get the color converted from a feature.
You only want feature-state if you're intending to manipulate the feature attributes dynamically, which I don't think you are.
You probably just want regular data-driven styling:
const layerStyleTheLines = {
id: 'style_it_to_red',
type: 'line',
paint: {
'line-color': [
'match', ['get','Need'],
'Urgent', 'red',
'Medium', 'yellow',
'Starting','green',
'black'
],
'line-width': 3,
}
};

Alexa Presentation Language Document rendering while speaking

I am trying to render an Alexa Presentation Language document while Alexa is speaking her speech. I tried with a pager with several pages and the AutoPager command. The problem I am trying to solve is that the document is rendered when Alexa starts speaking but the command is started when the speech is finished, and I would like to see the three pages moving while speaking.
I am using the RenderDocumet and the executeCommand and the speak directives of responseBuilder.
The Document Template:
PagerDoc —>
{
"type": "APL",
"version": "1.0",
"theme": "dark",
"import": [],
"resources": [],
"styles": {},
"layouts": {},
"mainTemplate": {
"parameters": [
"datasource"
],
"item": [{
"type": "Container",
"items": [
{
"type": "Sequence",
"id": "pagerComponentId",
"scrollDirection": "vertical",
"numbered": true,
"width": "100vw",
"height": "100vh",
"alignItems": "center",
"justifyContent": "center",
"direction": "column",
"items": [
{
"type": "Image",
"source": "${datasource.app.properties.images.robot1}",
"position": "relative",
"width": "100vw",
"height": "100vh"
},
{
"type": "Image",
"source": "${datasource.app.properties.images.robot2}",
"position": "relative",
"width": "100vw",
"height": "100vh"
}
]
}
]
}
]
}
}
And the Directives:
var response = handlerInput.responseBuilder;
return response
.addDirective({
type : 'Alexa.Presentation.APL.RenderDocument',
token: 'pagerToken',
document : pagerDoc,
datasources : {
"app": {
"properties": {
"images": {
"robot1": "https://xxx/robot1.png",
"robot2": "https://xxx/robot2.png"
}
}
}
}
})
.addDirective({
type: 'Alexa.Presentation.APL.ExecuteCommands',
token: 'pagerToken',
commands: [
{
"type": "Parallel",
"commands": [
{
"type": "Scroll",
"componentId": "pagerComponentId",
"distance": 1
}
]
})
.speak(speechOutput)
.reprompt(repromptOutput)
.getResponse();
Could somebody tell me what should I do? If this is possible with Alexa?
Thanks a lot in advance and best regards,
Fernando
It's not posible yet. If you wait until the release of APL 1.1 (coming soon)
APL 1.1 will add onMount to the APL document which should allow for the execution of commands as soon as a document is loaded (eg. before alexa speaks)

How to set map.loadImage visibility by zoom level in Mapbox GL JS?

I'm loading an image with the following code:
map.on('load', function () {
map.loadImage('....png', function(error, image) {
if (error) throw error;
map.addImage('b7', image);
map.addLayer({
"id": "b7",
"type": "symbol",
"source": {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [0, 0]
}
}]
}
},
"layout": {
"icon-image": "b7",
"icon-size": 0.2
}
});
});
How can i set the visibility to none, at a certain zoom level?
It looks like that you cant use map.setLayoutProperty on an loadImage. In the console, it says: Error: The layer 'b7' does not exist in the map's style and cannot be styled.
Whey i try something like:
map.setLayoutProperty( 'b7', 'visibility', 'none' );
Any ideas?
Two suggestions on how to solve this:
First, make sure your image name and layer name are different. It could be that the function is looking for b7 layer but it finds an image named b7 first (or vice versa). Either way this should be changed as it creates conflicting variables.
Second, if that doesn't work try adding your source separately instead of inside the layer.
map.addSource("mySource", {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-74.981906, 41.742503]
},
"properties": {
"title": "title ",
"icon": "myImage",
}
}]
}
});
And then add the layer with the source.
map.addLayer({
"id": "b7",
"type": "symbol",
"source": "mySource",
"layout": {
"icon-image": "myImage",
"icon-size": 0.2
}
});
You can now call the setLayoutProperty on a zoomstart listener. Add a conditional if you want it only at a specific zoom level using map.getZoom(); You need to be setting the visibility for the layer here, not the image.
map.on('zoomstart', 'b7', function(e) {
if (map.getZoom() > 12) {
map.setLayoutProperty('b7', 'visibility', 'none');
}
})
Snippet is below, let me know if you encounter any problems.
map.on('load', function() {
map.loadImage('myImage.png', function(error, image) {
if (error) throw error;
map.addImage('myImage', image);
map.addSource("mySource", {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-73.981906, 40.742503]
},
"properties": {
"title": "title ",
"icon": "myImage",
}
}]
}
});
map.addLayer({
"id": "b7",
"type": "symbol",
"source": "mySource",
"layout": {
"icon-image": "myImage",
"icon-size": 0.2
}
});
});
});
map.on('zoomstart', 'b7', function(e) {
if (map.getZoom() > 12) {
map.setLayoutProperty('b7', 'visibility', 'none');
}
})

plugin leaflet does not search on the map by layer ( leaflet-fusesearch)

I want to customize the search on the layer "Muzei" (the field 'iconCaption'), but nothing happens... Please tell me how to correct the code...
the plugin is located at this address: https://github.com/naomap/leaflet-fusesearch
data/Muzei.js
var Muzei = {
"type": "FeatureCollection",
"metadata": {
"name": "Музеи и галереи ",
"creator": "Yandex Map Constructor"
},
"features": [{
"type": "Feature",
"id": 0,
"geometry": {
"type": "Point",
"coordinates": [104.66424966564485, 51.99642708991676]
},
"properties": {
"description": "Адрес: Тальцы, 47-й км Байкальского тракта\nКонтакты: тел.: 7 950 145‑40-75, 7 3952 24‑32-51\ne-mail: talci#irk.ru, talzimark#mail.ru\nсайт: http://www.talci.ru",
"iconCaption": "Архитектурно-этнографический музей «Тальцы»",
"marker-color": "#1e98ff"
}
}, {
"type": "Feature",
"id": 1,
"geometry": {
"type": "Point",
"coordinates": [104.28481982936044, 52.235150415839485]
},
"properties": {
"description": "Адрес: Иркутск, ул. Академическая, д. 1\nКонтакты: тел.: 73952453146;\ne-mail: bm#isc.irc.ru; \nсайт: http://www.bm.isc.irk.ru",
"iconCaption": "Байкальский музей Иркутского научного центра",
"marker-color": "#1e98ff"
}
}, {
"type": "Feature",
"id": 2,
"geometry": {
"type": "Point",
"coordinates": [104.28314107738336, 52.288654185599434]
},
"properties": {
"description": "Адрес: Иркутск, ул. Сухэ-Батора, д. 5\nКонтакты: тел.: 73952241855; \ne-mail: irkinsect#yandex.ru;\nсайт: http://biosoil.isu.ru",
"iconCaption": "Восточно-Сибирский музей микробиологии ИГУ",
"marker-color": "#1e98ff"
}
}, {
"type": "Feature",
"id": 3,
"geometry": {
"type": "Point",
"coordinates": [104.28242998112661, 52.28897985492063]
},
"properties": {
"description": "Адрес: Иркутск, ул. Сухэ-Батора, д. 5\nКонтакты: тел.: 73952241855; \ne-mail: irkinsect#yandex.ru;\nсайт: http://biosoil.isu.ru",
"iconCaption": "Восточно-Сибирский музей почвоведения им. И.В.Николаева ИГУ",
"marker-color": "#1e98ff"
}
}, {
"type": "Feature",
"id": 4,
"geometry": {
"type": "Point",
"coordinates": [104.28149027976227, 52.29116663064888]
},
"properties": {
"description": "Адрес: Иркутск, ул. Сухэ-Батора, д. 2\nКонтакты: тел.: 73952345041; \ne-mail: krek#museum.irkutsk.ru",
"iconCaption": "Выставочный зал «Спасская церковь»",
"marker-color": "#1e98ff"
}
}, {
"type": "Feature",
"id": 5,
"geometry": {
"type": "Point",
"coordinates": [104.28411953372908, 52.281967955879544]
},
"properties": {
"description": "Адрес: Иркутск, ул. Карла Маркса, д. 13\nКонтакты: 7 3952 20‑03-68, 7 3952 33‑62-30\nсайт: museum-irkutsk.com\n",
"iconCaption": "Выставочный отдел «Музейная студия» Иркутского областного краеведческого музея",
"marker-color": "#1e98ff"
}
},
}
}]
}
// serach...
var searchCtrl = L.control.fuseSearch({
position: 'topright',
title: 'Chercher',
placeholder: 'found objects',
showInvisibleFeatures: false,
showResultFct: function(feature, container) {
props = feature.properties;
var name = L.DomUtil.create('b', null, container);
name.innerHTML = props.name;
container.appendChild(L.DomUtil.create('br', null, container));
container.appendChild(document.createTextNode(props.details));
}
});
searchCtrl.addTo(map);
var streetsLayer = L.geoJson(Muzei.features, {
onEachFeature: function(feature, layer) {
feature.layer = layer;
}
});
searchCtrl.indexFeatures(streetsLayer, ['iconCaption']);
streetsLayer.addTo(map);
// or serach version 2, as in instructions
//var searchCtrl = L.control.fuseSearch()
//searchCtrl.indexFeatures(streetsLayer, ['iconCaption']);
//L.geoJson(Muzei, {
//onEachFeature: function (feature, layer) {
//feature.layer = layer;
//}
//});
//searchCtrl.addTo(map);
code earned, it is needed to download and install fuse.js, but started another problem - the objects are on the list, but click on them with mouse is not implemented.
code is shown below. unfortunately I'm not a programmer and try to deal with the issue in the course of business...therefore, I have such difficulties with functions, etc.
var searchCtrl = L.control.fuseSearch()
searchCtrl.addTo(map);
searchCtrl.indexFeatures(Muzei, ['iconCaption']);
var spots = L.geoJson(Muzei, {
onEachFeature: function (feature, layer) {
feature.layer = layer;
}
});
map.addLayer(spots)

Color Each Polygon Dynamically using mapbox?

I am trying to colour each polygon dynamically based on a computation. Is there a way possible using mapbox?
The computation is triggered when a value is selected from the dropdown, then each polygon's colour needs to be updated.
Below is the geojson source that I am adding to the map.
{
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": [
{
"id": 1,
"type": "Feature",
"properties": {
"title": "Candolim"
},
"geometry": {
"type": "Polygon",
"coordinates": [[[73.68255615234375, 15.72088240269937], [73.707275390625, 15.670643235196232], [73.97232055664062, 15.640229310707543], [73.97232055664062, 15.685187424880764], [73.95721435546875, 15.698408515946419], [73.94760131835938, 15.74071024249738], [73.8885498046875, 15.753927728167556], [73.88717651367188, 15.769787575567598], [73.86245727539062, 15.798860741939269], [73.82675170898438, 15.742032029750966], [73.68255615234375, 15.72088240269937]]]
}
},
{
"id": 2,
"type": "Feature",
"properties": {
"title": "Morjim"
},
"geometry": {
"type": "Polygon",
"coordinates": [[[73.970947265625, 15.640229310707543], [73.70864868164062, 15.666676458207187], [73.73062133789062, 15.60584290961007], [73.76907348632812, 15.496032414238634], [73.79791259765625, 15.45765111021037], [74.17556762695312, 15.653453312049928], [74.11239624023438, 15.650808580175482], [74.08355712890625, 15.627004454829198], [74.03823852539062, 15.620391706641964], [74.02313232421875, 15.60584290961007], [73.99566650390625, 15.609810865724066], [73.98056030273438, 15.623036831528264], [73.970947265625, 15.640229310707543]]]
}
},
{
"id": 3,
"type": "Feature",
"properties": {
"title": "Panaji"
},
"geometry": {
"type": "Polygon",
"coordinates": [[[73.79928588867188, 15.458974721921672], [73.78280639648438, 15.411319377980993], [74.256591796875, 15.257689080778698], [74.29229736328125, 15.277561419418248], [74.33486938476562, 15.292133271452533], [74.31838989257811, 15.326571801420842], [74.32113647460938, 15.37027407332405], [74.2840576171875, 15.391459757417053], [74.27444458007812, 15.420586551727165], [74.27993774414062, 15.441767110328934], [74.24835205078124, 15.485445179478607], [74.27993774414062, 15.534406591252042], [74.25384521484375, 15.566159129772904], [74.26071166992188, 15.613778745064309], [74.24972534179688, 15.625681922266882], [74.24423217773438, 15.665354182093287], [74.2236328125, 15.65609800971696], [74.2071533203125, 15.658742673171389], [74.1961669921875, 15.669320984759295], [74.190673828125, 15.681220930466825], [74.17144775390625, 15.675932151334584], [74.17694091796875, 15.654775665159686], [73.79928588867188, 15.458974721921672]]]
}
}
]
}
}
You can achieve this using setPaintProperty and a "match" expression after the value is selected:
map.setPaintProperty('myLayer', 'fill-color', [
'match',
['get', 'title'],
layer.value, '#fbb03b',
/* other */ '#ccc'
]);
See this jsfiddle.