how to fix the error:Cannot read property 'mapmatching' of undefined - javascript

I use mapbox-match.js locally without use http request to match the route on map . but I have problem in matching and the error message
"Cannot read property 'mapmatching' of undefined"
shown. how to solve this?
this is for map visualization with local host map. running http server, html and javascript. I use d3-js and mapbox to render set of coords as geojson data on a map to visualize a route
<head>
<meta charset='utf-8' />
<script src='MAPBOX/mapbox-gl.js'></script>
<link href='MAPBOX/mapbox-gl.css' rel='stylesheet' />
<script src='mapbox.js-publisher-production/src/mapbox.js'></script>
<script src='mapbox-match.js-master/src/match.js'></script>
</head>
<body>
<script>
function updateRoute(newCoords) {
// Set the profile
var profile = "driving";
L.mapbox.mapmatching(Coords, profile);
}
L.mapbox.mapmatching(Coords, profile, function(error, layer) {
layer.addTo(map);
layer.setStyle({
color: '#9a0202',
weight: 4,
opacity: 0.8
});
layer.addLayer({
"id": "route",
"type": "line",
"source": {
"type": "geojson",
"data": {
"type": "Feature",
"properties": {},
"geometry": coords
}
},
"layout": {
"line-join": "round",
"line-cap": "round"
},
"paint": {
"line-color": "#33C9EB",
"line-width": 3
}
});
});
}
</script>
</body>
after debugging code the error shown "TypeError: Cannot read property 'mapmatching' of undefined"

Related

Functionally setting Leaflet marker colors by a property for geojson data

Similarly to this question, we want to functionally set our Leaflet map's marker's colors based off a value, except our map is built with geojson data.
We want markers' colors to be functional to color_value (eg. different shade of green), but we don't know how to build that like this answer explains with L.AwesomeMarkers.icon({markerColor: determineColor(rating)});, because the markers for all our entries are built at once with pointToLayer: function (feature, coordinates) {return L.marker(coordinates, { icon: customicon });}. Simplified eg:
<!DOCTYPE html>
<style>
html,
body { margin: 0px; height: 100%; }
body {display: flex;}
</style>
<body>
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.7.1/dist/leaflet.css"
integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
crossorigin="" />
<script src="https://unpkg.com/leaflet#1.7.1/dist/leaflet.js"
integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA=="
crossorigin=""></script>
<div id="mapid" style="flex: 1"></div>
<script>var myMap = L.map("mapid");
L.tileLayer('https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png').addTo(myMap);
myMap.setView([51.5, -0.09], 10);
var geojsonFeatureCollection =
{
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-0.09, 51.5]
},
"properties": {
"color_value": 1
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-0.4, 51.5]
},
"properties": {
"color_value": 10
}
}]
}
const myCustomColor = '#007a83'
const markerHtmlStyles = `
background-color: ${myCustomColor}; width: 1.3rem; height: 1.3rem; display: block;`
const customicon = L.divIcon({html: `<span style="${markerHtmlStyles}" />`})
L.geoJSON(geojsonFeatureCollection, {
pointToLayer: function (feature, coordinates) {
return L.marker(coordinates, { icon: customicon });
}
})
.addTo(myMap);
</script>
</body>
</html>
We've found this tutorial which gets us a little closer by explaining how to choose different markers based off some value, but we want to set the color itself, not choose from existing markers.
How can we make myCustomColor functional to color_value, or otherwise set marker colors programmatically for geojson data?
You are almost there! :-)
You can define the desired color directly as a property on each GeoJSON feature. Leaflet passes each feature of the GeoJSON collection to pointToLayer, allowing you to access its properties.
Check out the snippet below.
var myMap = L.map("mapid");
L.tileLayer('https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png').addTo(myMap);
myMap.setView([51.5, -0.09], 10);
var geojsonFeatureCollection = {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-0.09, 51.5]
},
"properties": {
// You can define a different color for each property
// and access it in pointToLayer().
"color_value": '#007a83'
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-0.4, 51.5]
},
"properties": {
// Here I might use a different color
"color_value": '#003134'
}
}
]
};
L.geoJSON(geojsonFeatureCollection, {
pointToLayer: function(feature, coordinates) {
// Leaflet passes each GeoJSON feature in the collection in here,
// allowing you to access the feature's properties
const color_value = feature.properties.color_value;
// With the color obtained from the properties, you can now create
// the marker icon with the correct color.
const markerHtmlStyles = `background-color: ${color_value}; width: 1.3rem; height: 1.3rem; display: block;`;
const customicon = L.divIcon({
html: `<span style="${markerHtmlStyles}" />`
});
return L.marker(coordinates, {
icon: customicon
});
},
})
.addTo(myMap);
html,
body {
margin: 0px;
height: 100%;
}
body {
display: flex;
}
<!DOCTYPE html>
<body>
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.7.1/dist/leaflet.css" integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==" crossorigin="" />
<script src="https://unpkg.com/leaflet#1.7.1/dist/leaflet.js" integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA==" crossorigin=""></script>
<div id="mapid" style="flex: 1"></div>
</body>
</html>
Alternatively, if you want to calculate the color based off color_value, you can proceed almost the same way: Read color_value property inside pointToLayer, generate the color (e.g., by using an approach like the one outlined here: Programmatically Lighten or Darken a hex color (or rgb, and blend colors)) and pass it to your marker's styling.
Hope this helps!

Making a gogocartojs map work in js project

I created a project and I'm trying to add gogocartoJs in it.
The project works but the map is not showing.
I tried with the guides I found in the site, it looks plain and easy, but there is an step that I'm not understanding (please dont just copy/paste a piece of the site like it was obvious what it is the mistake, because it is not for me)
<html lang="en">
<head>
<link
rel="stylesheet"
href="https://gogocarto.fr/assets/css/gogocarto.min.css"
/>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<script type="text/javascript" src="./jquery.js"></script>
<script src="https://gogocarto.fr/js/gogocarto.min.js"></script>
<title>Hello Webpack</title>
</head>
<body>
<div>
<h1>Hello Webpack</h1>
<div id="gogocarto"></div>
</div>
<script>
$(document).ready(function() {
carto = goGoCarto("#gogocarto", {
data: {
taxonomy: taxonomy,
elements: elements
}
});
});
</script>
<script src="./bundle.js"></script>
</body>
</html>
I expect the map to show, and it doesnt
I added the project to github to show better
https://github.com/Aredros/testGogo/tree/master/dist
elements & taxonomy are js variables containing data you must provide according to the format described in the documentation.
// taxonomy
let taxonomy = {
"options":[
{
"id": "eu1",
"name":"Belgium",
"color":"#9acd32",
"icon":"fa-solid fa-building"
},
{
"id": "eu2",
"name": "Netherland",
"color": "#ffa500",
"icon": "fa-solid fa-fan"
},
{
"id": "eu3",
"name": "Luxembourg",
"color": "#a52a2a",
"icon": "fa-solid fa-money-bill-1"
}
]
}
The only missing info in the documentation is the id key in the taxonomy which must be referenced in your elements source dataset.
// elements
let elements = [
{
"title": "Brussels",
"geo": {
"latitude":50.84,
"longitude":4.34
},
"taxonomy": [ "eu1" ],
},
{
"title": "Namur",
"geo": {
"latitude":50.45,
"longitude":4.88
},
"taxonomy": [ "eu1" ],
},
{
"title": "Liege",
"geo": {
"latitude":50.62,
"longitude":5.60
},
"taxonomy": [ "eu1" ],
},
{
"title": "Rotterdam",
"geo": {
"latitude":51.88,
"longitude":4.51
},
"taxonomy": [ "eu2" ],
},
{
"title": "Amsterdam",
"geo": {
"latitude":52.07,
"longitude":5.12
},
"taxonomy": [ "eu2" ],
},
]
Idealy you should build an API returning taxonomy classification & elements data. Then perform ajax call in your html page.
$.ajax({
type: 'GET',
url: '/ajax/url_to_get_elements',
dataType: 'json',
success: function(elements, status) {
build_map(elements);
}
});
// build map = function with 1 arguments (elements) where you put the call to goGoCarto and options...
You can define more than 1 taxonomy group (Example above is about English countries) with the name you want => Cfr. Advanced Taxonomy with Categories. Your elements can then have multiple taxonomy reference listed [ "eu1", "week22", 14 ]. Items in the list can be Integer or String. The only important thing is the ID key and the taxonomy order! Keep the same order in your taxonomy than in your key "taxonomy": in your elements data sources!
Point of attention
Because the library is highly configurable with options, colors and icons it is important to put all your <scripts> tags inside <head> tags of your html page!

Input data given to 'drone' is not a valid GeoJSON object

I am trying to render a polygon from a webservice to a mapbox map as a proof of concept.
My webservice gives me the following geojson with some mock data:
{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[9.750441312789917,52.350087018909683],[9.7523081302642822,52.34896634765532],[9.7523403167724609,52.350106679555289],[9.750441312789917,52.350087018909683]]]},"properties":{"test1":"value1"}}]}
But mapbox gives me the error I can see in the browser console:
Input data given to 'drone' is not a valid GeoJSON object.
http://geojson.io and http://geojsonlint.com/ understand that geojson my webservice was generating.
It is send as content-type "text/plain; charset=utf-8"
because as application/json it gets a lot of \ characters, which is not working.
Below you can see the html code I am using for this test.
So what am I doing wrong here?
I checked that the geojson is correctly formatted and I added the same geojson directly as a source and it worked. See below.
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title>Add multiple geometries from one GeoJSON source</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v1.2.0/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v1.2.0/mapbox-gl.css' rel='stylesheet' />
<style>
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
mapboxgl.accessToken = 'pk.xxxxxx';
var map = new mapboxgl.Map({
container: "map",
style: "mapbox://styles/mapbox/streets-v11",
center: [9.754206, 52.355394],
zoom: 14
});
var url = 'https://localhost:44337/api/resource';
map.on('load', function () {
map.addSource('drone', { type: 'geojson', data: url });
map.addLayer({
"id": "drone",
"type": "fill",
"source": "drone",
'layout': {},
'paint': {
'fill-color': '#088',
'fill-opacity': 0.8
}
});
});
</script>
</body>
</html>
I expect that there is some polygon on the map, like it is if I put the geojson directly into the code:
map.on('load', function () {
map.addLayer({
'id': 'maine',
'type': 'fill',
'source': {
'type': 'geojson',
'data':
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
9.750441312789917,
52.350087018909683
],
[
9.7523081302642822,
52.34896634765532
],
[
9.7523403167724609,
52.350106679555289
],
[
9.750441312789917,
52.350087018909683
]
]
]
},
"properties": {
"test1": "value1"
}
}
]
}
},
'layout': {},
'paint': {
'fill-color': '#088',
'fill-opacity': 0.8
}
});
});
Maybe you should try to fetch your geoJSON from your API manually and see if that works, passing a URL as a geoJSON object to mapbox seems to work as well, but maybe something is wrong with your API, so I would do a manual fetch and see if anything goes wrong. Furthermore, you should definitely change your content-type header back to application/json, the following snippet assumes you did that!
map.on('load', async function() {
let response = await fetch(url);
let data = await (
response.headers.get('content-type').includes('json')
? response.json() // this will parse your JSON if the proper content-type header is set!
: response.text()
);
map.addSource('drone', { type: 'geojson', data: data });
map.addLayer({
"id": "drone",
"type": "fill",
"source": "drone",
'layout': {},
'paint': {
'fill-color': '#088',
'fill-opacity': 0.8
}
});
});
Ok, I reckon mapboxgl is doing call this, but if it helps, this is the asp.net core backend snippet:
// GET: api/resource
[HttpGet]
public JsonResult GetResources()
{
var poly = _context.Resources.First().Polygon;
AttributesTable attributes = new AttributesTable();
attributes.Add("test1", "value1");
IFeature feature = new Feature(poly, attributes);
FeatureCollection featureCollection = new FeatureCollection(new Collection<IFeature> { feature });
var gjw = new GeoJsonWriter();
gjw.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
string actual = gjw.Write(featureCollection);
return new JsonResult(actual);
}
I am using NetTopologySuite.
And poly is a SQL Server Geography type Polygon.
EDIT: Ok I figured it out myself:
I had to do this:
return Content(actual, "application/json", Encoding.UTF8);
and use ContentResult as a return type.
My Json seemed to get serialized twice, since it got too many characters.
Ah and the fetch and response.json() parsing exside proposed is not needed with the correct geojson response. But it is also working with it. ;)
Thanks though.

How to add new layer to client mapbox map on button click with JS/jQuery?

Problem:
I am working on project where I use node.js server that communicate with my spatial DB in PG and my client uses mapbox to vizualize map on his side. After hitting a button, the request is send to server, server to psql, psql to server as result query and then through socket.io back to client, where I want to put my geoJSON / new geometry as new layer on his map after that client buttonclick occurs. Map on client side in HTML is well working and I can interact with it. I use JS inside of HTML page of my client. From there I need to update mapbox map with new geometry after button click.
Code sample:
But I tried this code, but this do nothing after button click and will show no errors in devTool Chrome console:
<script>
mapboxgl.accessToken = 'secretToken-I-have-just-for-ilustr--this-is-working';
var map = new mapboxgl.Map({
container: 'map', // container id
style: 'mapbox://styles/mapbox/streets-v10',
center: [17.10, 48.14], // starting position on Bratislava
zoom: 11 // starting zoom
});
// Add zoom and rotation controls to the map.
map.addControl(new mapboxgl.NavigationControl());
// later SOCKET PROCESSING
$(document).ready(function(){
$('#buttonRun').click(function(e){
map.on('load', function () {
alert("got HERE") // this is working, alert shows itself
map.addLayer({
"id": "route",
"type": "line",
"source": {
"type": "geojson",
"data": {
"type": "Feature",
"properties": {},
"geometry": {
"type": "LineString",
"coordinates": [
[-122.48369693756104, 37.83381888486939],
[-122.48348236083984, 37.83317489144141],
[-122.48339653015138, 37.83270036637107],
[-122.48356819152832, 37.832056363179625],
[-122.48404026031496, 37.83114119107971],
[-122.48404026031496, 37.83049717427869],
[-122.48348236083984, 37.829920943955045],
[-122.48356819152832, 37.82954808664175],
[-122.48507022857666, 37.82944639795659],
[-122.48610019683838, 37.82880236636284],
[-122.48695850372314, 37.82931081282506],
[-122.48700141906738, 37.83080223556934],
[-122.48751640319824, 37.83168351665737],
[-122.48803138732912, 37.832158048267786],
[-122.48888969421387, 37.83297152392784],
[-122.48987674713133, 37.83263257682617],
[-122.49043464660643, 37.832937629287755],
[-122.49125003814696, 37.832429207817725],
[-122.49163627624512, 37.832564787218985],
[-122.49223709106445, 37.83337825839438],
[-122.49378204345702, 37.83368330777276]
]
}
}
},
"layout": {
"line-join": "round",
"line-cap": "round"
},
"paint": {
"line-color": "#888",
"line-width": 8
}
});
});
});
});
</script>
Even this is not working - even if I set data in click function in a static way, but this data will later change dynamically. If I add that layer out of click event function scope, it is working and layer loads on client map.
Settings / versions:
Windows10 Pro - 64-bit
Google Chrome - Version 69.0.3497.100 (Official Build) (64-bit)
Node.js - v10.11.0
mapbox-gl.js v0.49.0
Q:
Is there any way how to add layer to mapbox map dynamically, please? And later to remove without page refresh? (I still not found answer, even here)
Solution
Okay, I found something I before did not see, concretely this.
I better read documentation, and it is impossible to setup new layers dynamically, but now it is working as follows / you need to:
Out of all scopes define your variables, for example geoJson1, and geoJson2 that you can later edit / fill with function
Setup your layer in advance on map with your ID (as in code below) and fill it for example with goeJson1 or with empty []
In your on click listener function call this: map.getSource('data-update').setData(geojson2);
You just can setup as many layers in advance as you need, and later you can update them.
Code result:
<script>
mapboxgl.accessToken = 'token-from-your-registered-account';
var map = new mapboxgl.Map({
container: 'map', // container id
style: 'mapbox://styles/mapbox/streets-v10',
center: [17.10, 48.14], // starting position on Bratislava
zoom: 11 // starting zoom
});
var geojson = {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[-122.48369693756104, 37.83381888486939],
[-122.48348236083984, 37.83317489144141],
[-122.48339653015138, 37.83270036637107],
[-122.48356819152832, 37.832056363179625],
[-122.48404026031496, 37.83114119107971]
]
}
}]
};
var geojson2 = {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[-122.48369693756104, 37.83381888486939],
[-122.48348236083984, 37.83317489144141],
[-122.48339653015138, 37.83270036637107],
[-122.48356819152832, 37.832056363179625],
[-122.48404026031496, 37.83114119107971],
[-122.48404026031496, 37.83049717427869],
[-122.48348236083984, 37.829920943955045],
[-122.48356819152832, 37.82954808664175],
[-122.48507022857666, 37.82944639795659],
[-122.48610019683838, 37.82880236636284],
[-122.48695850372314, 37.82931081282506],
[-122.48700141906738, 37.83080223556934],
[-122.48751640319824, 37.83168351665737],
[-122.48803138732912, 37.832158048267786],
[-122.48888969421387, 37.83297152392784],
[-122.48987674713133, 37.83263257682617],
[-122.49043464660643, 37.832937629287755],
[-122.49125003814696, 37.832429207817725],
[-122.49163627624512, 37.832564787218985],
[-122.49223709106445, 37.83337825839438],
[-122.49378204345702, 37.83368330777276]
]
}
}]
};
map.on('load', function () {
map.addLayer({
"id": "data-update",
"type": "line",
"source": {
"type": "geojson",
"data": geojson // your previously defined variable
},
"layout": {
"line-join": "round",
"line-cap": "round"
},
"paint": {
"line-color": "#888",
"line-width": 8
}
});
});
$(document).ready(function(){
$('#buttonRun').click(function(e){
map.getSource('data-update').setData(geojson2);
});
});
</script>

uncaught typeerror object object object has no method 'kendoUi' Error in Parsing

This is My JSonSctipt file code:
var data = [
{
"SearchResult": {
"assets": [
{
"agent": "6.1.0",
"id": 1,
"model": "Gateway1",
"modelId": 2,
"name": "Name",
"serialNumber": "Serial01"
},
{
"agent": "M2M",
"id": 2,
"model": "Gateway1",
"modelId": 3,
"name": "Name",
"serialNumber": "Serial02"
}
],
"searchCriteria": {
"paginationEnabled": false,
"rowsPerPage": -1,
"startRow": -1,
"totalAvailableRows": -1,
"alternateId": {
"#xsi.nil": "true"
},
"modelNumber": {
"#xsi.nil": "true"
},
"name": "*",
"serialNumber": {
"#xsi.nil": "true"
}
}
}
}
];
$("#grid").kendoGrid({
dataSource: {
data: data,
schema: {
data: function(rawData) {
return rawData[0].SearchResult.assets;
}
}
}
});
Thsi is My Index.html file
<html>
<head>
<title></title>
<meta charset="utf-8" />
<script src="cordova.js"></script>
<script src="kendo/js/jquery.min.js"></script>
<script src="kendo/js/kendo.mobile.min.js"></script>
<script src="http://maps.google.com/maps/api/js?sensor=true"></script>
<script src="scripts/hello-world.js"></script>
<script src="kendo/js/kendo.dataviz.min.js"></script>
<link href="kendo/styles/kendo.mobile.all.min.css" rel="stylesheet" />
<link href="styles/main.css" rel="stylesheet" />
</head>
<body>
<div id="grid"></div>
</body>
</html>
when i run this code uncaught typeerror object object object has no method 'kendoUi' Error I m getting so am Unable to Display data In Grid please tell me how i will fix it or can any one Please tell me how i will Json parsing In Kendo UI
It looks like you are trying to use Kendo Grid, which is a part of Kendo Web, but only have a reference to Kendo Mobile (i.e. kendo.mobile.min.js). You need to add a script reference to either kendo.web.min.js or kendo.all.min.js. Take a look at this jsfiddle, paying particular attention to the External Resource (i.e. kendo.all.min.js)
P.S. SO won't let me post a link to jsfiddle without some code, so here is part of the code again, to satisfy their requirements:
<html>
<head>
<title></title>
<meta charset="utf-8" />
<script src="http://maps.google.com/maps/api/js?sensor=true"></script>
</head>
<bo
<div id="grid"></div>
</body>

Categories