How to add GeoJSON(MultiLineString) layer to a Google Map - javascript

I need to create maps that will use GeoJSON data(MultiLineString format) as a data layer over a Google Map. I have created a Google Maps JavaScript API project, and have an API key.
I have tried the following examples:
Example I:
https://developers.google.com/maps/documentation/javascript/examples/layer-data-simple
(This renders a polygon but does not seem to support the styling of a MultiLineString).
Example II:
https://developers.google.com/maps/documentation/javascript/examples/layer-data-dragndrop
(This example allows for addition of GeoJSON via Drag and Drop but I do not see how to save the map and data layer.)
Sample GeoJSON MultiLineString from http://geojsonlint.com :
{
"type": "MultiLineString",
"coordinates": [
[
[
-105.0214433670044,
39.57805759162015
],
[
-105.02150774002075,
39.57780951131517
],
[
-105.02157211303711,
39.57749527498758
],
[
-105.02157211303711,
39.57716449836683
],
[
-105.02157211303711,
39.57703218727656
],
[
-105.02152919769287,
39.57678410330158
]
],
[
[
-105.01989841461182,
39.574997872470774
],
[
-105.01959800720215,
39.57489863607502
],
[
-105.01906156539916,
39.57478286010041
]
],
[
[
-105.01717329025269,
39.5744024519653
],
[
-105.01698017120361,
39.574385912433804
],
[
-105.0166368484497,
39.574385912433804
],
[
-105.01650810241699,
39.5744024519653
],
[
-105.0159502029419,
39.574270135602866
]
],
[
[
-105.0142765045166,
39.57397242286402
],
[
-105.01412630081175,
39.57403858136094
],
[
-105.0138258934021,
39.57417089816531
],
[
-105.01331090927124,
39.57445207053608
]
]
]
}

Following the example in the documentation
Data class
google.maps.Data class
A layer for displaying geospatial data. Points, line-strings and polygons can be displayed.
Every Map has a Data object by default, so most of the time there is no need to construct one. For example:
var myMap = new google.maps.Map(...);
myMap.data.addGeoJson(...);
myMap.data.setStyle(...);
proof of concept fiddle
code snippet:
function initialize() {
var map = new google.maps.Map(
document.getElementById("map_canvas"), {
center: new google.maps.LatLng(37.4419, 70.1419),
zoom: 3,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
map.data.addGeoJson(jsonData);
map.data.setStyle({
strokeColor: "blue"
})
}
google.maps.event.addDomListener(window, "load", initialize);
var jsonData = {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"properties": {
"stroke": "#555555",
"stroke-width": 2,
"stroke-opacity": 1
},
"geometry": {
"type": "LineString",
"coordinates": [
[
79.8046875,
45.583289756006316
],
[
73.828125,
48.922499263758255
],
[
72.421875,
46.07323062540838
],
[
72.0703125,
42.553080288955826
],
[
79.453125,
41.77131167976407
],
[
78.046875,
37.71859032558816
],
[
72.7734375,
34.016241889667015
],
[
66.796875,
39.63953756436671
],
[
66.4453125,
48.45835188280866
],
[
74.1796875,
53.74871079689897
],
[
55.1953125,
55.7765730186677
],
[
49.92187499999999,
48.69096039092549
],
[
50.625,
40.17887331434696
]
]
}
}]
};
html,
body,
#map_canvas {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="map_canvas"></div>

You can add the GeoJSON like
function loadGeoJsonString(geoString) {
var geojson = JSON.parse(geoString);
map.data.addGeoJson(geojson);
}
With
map.data.setStyle({
//Put styling here
});
you can style your added GeoJSON. So the styling is not applied when you load the GeoJSON but you can add it afterwards.

Related

ECharts make the XAxis proportional to its values

I need to update the xAxis of this chart to make it be proportional to its values:
Here is my chart
As you can see the A Section is as wide as the B section even if the difference in X values from start to finish is roughfully ten fold (0.01 in A, 0.1 in B).
I need the A section to be 1/10 of the B section. Is there an Echart a settings to achieve this?
Here's a codepen of my current situation:
https://codepen.io/dariooo512/pen/vYawBMb
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Smoothed Line Chart - Apache ECharts Demo</title>
</head>
<body>
<div id="chart-container"></div>
<script src="https://fastly.jsdelivr.net/npm/echarts#5.4.1/dist/echarts.min.js"></script>
</body>
</html>
* {
margin: 0;
padding: 0;
}
#chart-container {
position: relative;
height: 100vh;
overflow: hidden;
}
var dom = document.getElementById('chart-container');
var myChart = echarts.init(dom, null, {
renderer: 'canvas',
useDirtyRect: false
});
var app = {};
var option;
const xData = [
0.0100000000000000,
0.0107977516232770,
0.0116591440117983,
0.0125892541179416,
0.0135935639087852,
0.0146779926762206,
0.0158489319246111,
0.0171132830416178,
0.0184784979742229,
0.0199526231496887,
0.0215443469003188,
0.0232630506715362,
0.0251188643150957,
0.0271227257933202,
0.0292864456462523,
0.0316227766016837,
0.0341454887383359,
0.0368694506451957,
0.0398107170553497,
0.0429866234708227,
0.0464158883361277,
0.0501187233627272,
0.0541169526546463,
0.0584341413373517,
0.0630957344480192,
0.0681292069057960,
0.0735642254459640,
0.0794328234724280,
0.0857695898590893,
0.0926118728128792,
0.0999999999999999,
0.1079775162327708,
0.1165914401179830,
0.1258925411794166,
0.1359356390878524,
0.1467799267622068,
0.1584893192461112,
0.1711328304161779,
0.1847849797422289,
0.1995262314968877,
0.2154434690031881,
0.2326305067153623,
0.2511886431509577,
0.2712272579332025,
0.2928644564625232,
0.3162277660168375,
0.3414548873833597,
]
const yData = [
0.163994337909158,
0.164355359005510,
0.164781529248110,
0.165290711360058,
0.165888614999721,
0.166599912595426,
0.167449496368629,
0.168470163071883,
0.169710786849251,
0.171197399817278,
0.172712533758993,
0.174671841558769,
0.176975558012239,
0.180294513617511,
0.184327422956864,
0.191100453431249,
0.200522213979933,
0.211754773758690,
0.216565431261549,
0.2505493351851847,
0.326466853585988,
0.347298734251199,
0.3523985766254678,
0.373650615601135,
0.311629700205303,
0.280092084112155,
0.250131726901599,
0.273316888213822,
0.266613651947510,
0.317070017440979,
0.400477619240458,
0.3590975138843978,
0.4310041008366142,
0.5090963720150549,
0.4907638864448018,
0.5406581161637817,
0.56051067203831806,
0.5071383683330877,
0.5355916724605659,
0.5355408618682007,
0.3839169258278131,
0.2773418659785273,
0.2949077335148602,
0.2394754641244239,
0.2036052621075644,
0.2106189314544600,
0.2395847208235534,
]
option = {
xAxis: {
type: 'category',
data: xData
},
yAxis: {
type: 'value'
},
series: [
{
data: yData,
type: 'line',
smooth: true
}
]
};
if (option && typeof option === 'object') {
myChart.setOption(option);
}
window.addEventListener('resize', myChart.resize);
Your xAxis is a category axis, which is not a good choice for what you have to do...
You should use a value axis instead:
const data = [
[ 0.0100000000000000, 0.163994337909158 ],
[ 0.0107977516232770, 0.164355359005510 ],
[ 0.0116591440117983, 0.164781529248110 ],
[ 0.0125892541179416, 0.165290711360058 ],
[ 0.0135935639087852, 0.165888614999721 ],
[ 0.0146779926762206, 0.166599912595426 ],
[ 0.0158489319246111, 0.167449496368629 ],
[ 0.0171132830416178, 0.168470163071883 ],
[ 0.0184784979742229, 0.169710786849251 ],
[ 0.0199526231496887, 0.171197399817278 ],
[ 0.0215443469003188, 0.172712533758993 ],
[ 0.0232630506715362, 0.174671841558769 ],
[ 0.0251188643150957, 0.176975558012239 ],
[ 0.0271227257933202, 0.180294513617511 ],
[ 0.0292864456462523, 0.184327422956864 ],
[ 0.0316227766016837, 0.191100453431249 ],
[ 0.0341454887383359, 0.200522213979933 ],
[ 0.0368694506451957, 0.211754773758690 ],
[ 0.0398107170553497, 0.216565431261549 ],
[ 0.0429866234708227, 0.2505493351851847 ],
[ 0.0464158883361277, 0.326466853585988 ],
[ 0.0501187233627272, 0.347298734251199 ],
[ 0.0541169526546463, 0.3523985766254678 ],
[ 0.0584341413373517, 0.373650615601135 ],
[ 0.0630957344480192, 0.311629700205303 ],
[ 0.0681292069057960, 0.280092084112155 ],
[ 0.0735642254459640, 0.250131726901599 ],
[ 0.0794328234724280, 0.273316888213822 ],
[ 0.0857695898590893, 0.266613651947510 ],
[ 0.0926118728128792, 0.317070017440979 ],
[ 0.0999999999999999, 0.400477619240458 ],
[ 0.1079775162327708, 0.3590975138843978 ],
[ 0.1165914401179830, 0.4310041008366142 ],
[ 0.1258925411794166, 0.5090963720150549 ],
[ 0.1359356390878524, 0.4907638864448018 ],
[ 0.1467799267622068, 0.5406581161637817 ],
[ 0.1584893192461112, 0.56051067203831806 ],
[ 0.1711328304161779, 0.5071383683330877 ],
[ 0.1847849797422289, 0.5355916724605659 ],
[ 0.1995262314968877, 0.5355408618682007 ],
[ 0.2154434690031881, 0.3839169258278131 ],
[ 0.2326305067153623, 0.2773418659785273 ],
[ 0.2511886431509577, 0.2949077335148602 ],
[ 0.2712272579332025, 0.2394754641244239 ],
[ 0.2928644564625232, 0.2036052621075644 ],
[ 0.3162277660168375, 0.2106189314544600 ],
[ 0.3414548873833597, 0.2395847208235534 ]
];
let option = {
xAxis: {
type: 'value'
},
yAxis: {
type: 'value'
},
series: [
{
data,
type: 'line',
smooth: true
}
]
};
let myChart = echarts.init(document.getElementById('chart-container'));
myChart.setOption(option);
#chart-container {
width 100vw;
height: 100vh;
}
<script src="https://fastly.jsdelivr.net/npm/echarts#5.4.1/dist/echarts.min.js"></script>
<div id="chart-container"></div>
Is it the expected result?
Take a look at the documentation: xAxis.type

Openlayer - filter layer from another layer using "in-like" clause

I have two Layer :
POLYGON
-Feature Id:1 Territory: A
-Feature Id:2 Territory: B
POINT
-Feature Id:1 Color:blue Territory: A
-Feature Id:2 Color:orange Territory: A,B
When hovering a point the polygon feature associated with (by the territory attribute get colorized in green)
When you hover the blue point (territory A) the polygon territory A gets colorized in green
I would like, on hovering the orange point, both polygon to be colorized in green (since the orange point hold A and B as territory attribute)
I tried by switching "==" in the json filter by a in clause, but it doesn't work.
An,y ideas?
Here is a working example
<html>
<head>
<link rel="stylesheet" href="https://openlayers.org/en/latest/css/ol.css">
<script type="text/javascript" src="https://openlayers.org/en/latest/build/ol.js"></script>
<script type="text/javascript" src="https://cdn.rawgit.com/Viglino/ol-ext/master/dist/ol-ext.min.js"></script>
</head>
<div id="map" style="width:600px; height:400px;">
</html>
<script type="text/javascript">
var osm = new ol.layer.Tile({ source: new ol.source.OSM() });
// The map
var map = new ol.Map({
target: 'map',
view: new ol.View({
zoom: 12,
center: [258348.20298867254,6251660.567134761]
}),
layers:[
osm
]
});
var myGeoJSON_polygon =
{
"type": "FeatureCollection",
"totalFeatures": 2,
"features": [
{
"type": "Feature",
"id": "1",
"geometry": {
"type": "GeometryCollection",
"geometries": [
{
"type": "Polygon",
"coordinates": [
[
[
260367.02192332118,
6250556.546642702
],
[
260995.1341454634,
6250123.266520023
],
[
261610.65442527525,
6251470.486675286
],
[
261693.70008903166,
6251705.530616308
],
[
261182.61728993867,
6251926.157505688
],
[
260061.0334155549,
6252410.348833421
]
]
]
}
]
},
"geometry_name": "GEOMETRY",
"properties": {
"ID": 1,
"TERRITORY": "A"
}
},
{
"type": "Feature",
"id": "2",
"geometry": {
"type": "GeometryCollection",
"geometries": [
{
"type": "Polygon",
"coordinates": [
[
[
259138.1286811567,
6252808.7905083215
],
[
260061.0334155549,
6252410.348833421
],
[
261182.61728993867,
6251926.157505688
],
[
261693.70008903166,
6251705.530616308
],
[
262058.7899222064,
6252709.954330505
],
[
261358.82144623742,
6252938.575515379
],
[
259138.1286811567,
6252808.7905083215
]
]
]
}
]
},
"geometry_name": "GEOMETRY",
"properties": {
"ID": 2,
"TERRITORY": "B"
}
}
],
"crs": {
"type": "name",
"properties": {
"name": "urn:ogc:def:crs:EPSG::3857"
}
}
};
var myGeoJSON_point = {
"type": "FeatureCollection",
"totalFeatures": 2,
"features": [
{
"type": "Feature",
"id": "1",
"geometry": {
"type": "GeometryCollection",
"geometries": [
{
"type": "Point",
"coordinates": [
260828.02345910599,
6247410.0048086485
]
}
]
},
"geometry_name": "GEOMETRY",
"properties": {
"ID": 1,
"COLOR":'blue',
"TERRITORY": "A"
}
},
{
"type": "Feature",
"id": "2",
"geometry": {
"type": "GeometryCollection",
"geometries": [
{
"type": "Point",
"coordinates": [
266849.73999407736,
6251709.352439402
]
}
]
},
"geometry_name": "GEOMETRY",
"properties": {
"ID": 2,
"COLOR":'orange',
"TERRITORY": "A, B"
}
}
],
"crs": {
"type": "name",
"properties": {
"name": "urn:ogc:def:crs:EPSG::3857"
}
}
}
var polygonLayer = new ol.layer.Vector({
source: new ol.source.Vector({
features: (new ol.format.GeoJSON()).readFeatures(myGeoJSON_polygon, { featureProjection: 'EPSG:3857' })
}),
style: new ol.style.Style({
fill: new ol.style.Fill({
color : 'red'
}),
stroke: new ol.style.Stroke({
color: 'white',
width: 2
})
})
});
function getStyle(feature){
return new ol.style.Style({
image: new ol.style.Circle({
radius: 6,
fill: new ol.style.Fill({
color: feature.get('COLOR')
}),
stroke: new ol.style.Stroke({
color: 'white',
width: 2
})
})
})
}
var pointLayer = new ol.layer.Vector({
source: new ol.source.Vector({
features: (new ol.format.GeoJSON()).readFeatures(myGeoJSON_point, { featureProjection: 'EPSG:3857' })
}),
style: getStyle
});
map.addLayer(polygonLayer);
map.addLayer(pointLayer)
const selectStyle = new ol.style.Style({
fill: new ol.style.Fill({
color: 'green'
}),
stroke: new ol.style.Stroke({
color: 'green',
width: 4
})
});
let selectedTerr = null;
map.on('pointermove', function (evt) {
if (selectedTerr !== null) {
selectedTerr[0].setStyle(undefined);
selectedTerr = null;
}
map.forEachFeatureAtPixel(evt.pixel, function(feature, layer) {
if(layer === pointLayer){
selectedTerr = polygonLayer
.getSource()
.getFeatures()
.filter(l => l.getProperties().TERRITORY == feature.A.TERRITORY)
selectedTerr[0].setStyle(selectStyle)
}
return true;
});
});
</script>
In your example, it looks like you have mixed up the calls to selectedTerr as if sometimes it was an array (when you index it with [0]) and sometimes an openlayers feature (when you call selectedTerr.setStyle(...)).
The logic to implement to solve your problem should be as follows:
(0) reset the polygon style
(1) when hovering over a point, retrieve the territory or territories to which it refers
(2) traverses the polygons list to retrieve the corresponding territory or territories
(3) apply the style to these polygons
The part of your code that I have modified is the following and includes the numbering of these 4 steps:
let selectedTerr = null;
map.on("pointermove", function (evt) {
// (0) reset the polygons style
if (selectedTerr !== null) {
selectedTerr.forEach((territory) => { territory.setStyle(undefined); });
selectedTerr = null;
}
map.forEachFeatureAtPixel(evt.pixel, function (feature, layer) {
if (layer === pointLayer) {
// (1) retrieve the territory or territories to which it refers
// and store it / them in an array
const targetTerritories = feature.get('TERRITORY').split(', ');
// (2) retrieve the feature(s) of corresponding territory or territories
selectedTerr = polygonLayer
.getSource()
.getFeatures()
.filter((l) => targetTerritories.includes(l.get('TERRITORY')));
// (3) apply the style to each of them
selectedTerr.forEach((territory) => { territory.setStyle(selectStyle); });
}
return true;
});
});
So in my code, selectedTerr is always an array (or null) even if sometimes this array contains only one element.
Below is the complete modified code :
<html>
<head>
<link rel="stylesheet" href="https://openlayers.org/en/latest/css/ol.css" />
<script type="text/javascript" src="https://openlayers.org/en/latest/build/ol.js"></script>
<script type="text/javascript" src="https://cdn.rawgit.com/Viglino/ol-ext/master/dist/ol-ext.min.js"></script>
</head>
<body>
<div id="map" style="width: 600px; height: 400px;"></div>
</body>
<script type="text/javascript">
var osm = new ol.layer.Tile({ source: new ol.source.OSM() });
var map = new ol.Map({
target: "map",
view: new ol.View({
zoom: 12,
center: [258348.20298867254, 6251660.567134761],
}),
layers: [osm],
});
var myGeoJSON_polygon = {
type: "FeatureCollection",
totalFeatures: 2,
features: [
{
type: "Feature",
id: "1",
geometry: {
type: "GeometryCollection",
geometries: [
{
type: "Polygon",
coordinates: [
[
[260367.02192332118, 6250556.546642702],
[260995.1341454634, 6250123.266520023],
[261610.65442527525, 6251470.486675286],
[261693.70008903166, 6251705.530616308],
[261182.61728993867, 6251926.157505688],
[260061.0334155549, 6252410.348833421],
],
],
},
],
},
geometry_name: "GEOMETRY",
properties: {
ID: 1,
TERRITORY: "A",
},
},
{
type: "Feature",
id: "2",
geometry: {
type: "GeometryCollection",
geometries: [
{
type: "Polygon",
coordinates: [
[
[259138.1286811567, 6252808.7905083215],
[260061.0334155549, 6252410.348833421],
[261182.61728993867, 6251926.157505688],
[261693.70008903166, 6251705.530616308],
[262058.7899222064, 6252709.954330505],
[261358.82144623742, 6252938.575515379],
[259138.1286811567, 6252808.7905083215],
],
],
},
],
},
geometry_name: "GEOMETRY",
properties: {
ID: 2,
TERRITORY: "B",
},
},
],
crs: {
type: "name",
properties: {
name: "urn:ogc:def:crs:EPSG::3857",
},
},
};
var myGeoJSON_point = {
type: "FeatureCollection",
totalFeatures: 2,
features: [
{
type: "Feature",
id: "1",
geometry: {
type: "GeometryCollection",
geometries: [
{
type: "Point",
coordinates: [260828.02345910599, 6247410.0048086485],
},
],
},
geometry_name: "GEOMETRY",
properties: {
ID: 1,
COLOR: "blue",
TERRITORY: "A",
},
},
{
type: "Feature",
id: "2",
geometry: {
type: "GeometryCollection",
geometries: [
{
type: "Point",
coordinates: [266849.73999407736, 6251709.352439402],
},
],
},
geometry_name: "GEOMETRY",
properties: {
ID: 2,
COLOR: "orange",
TERRITORY: "A, B",
},
},
],
crs: {
type: "name",
properties: {
name: "urn:ogc:def:crs:EPSG::3857",
},
},
};
var polygonLayer = new ol.layer.Vector({
source: new ol.source.Vector({
features: new ol.format.GeoJSON().readFeatures(myGeoJSON_polygon, { featureProjection: "EPSG:3857" }),
}),
style: new ol.style.Style({
fill: new ol.style.Fill({
color: "red",
}),
stroke: new ol.style.Stroke({
color: "white",
width: 2,
}),
}),
});
function getStyle(feature) {
return new ol.style.Style({
image: new ol.style.Circle({
radius: 6,
fill: new ol.style.Fill({
color: feature.get("COLOR"),
}),
stroke: new ol.style.Stroke({
color: "white",
width: 2,
}),
}),
});
}
var pointLayer = new ol.layer.Vector({
source: new ol.source.Vector({
features: new ol.format.GeoJSON().readFeatures(myGeoJSON_point, { featureProjection: "EPSG:3857" }),
}),
style: getStyle,
});
map.addLayer(polygonLayer);
map.addLayer(pointLayer);
const selectStyle = new ol.style.Style({
fill: new ol.style.Fill({
color: "green",
}),
stroke: new ol.style.Stroke({
color: "green",
width: 4,
}),
});
let selectedTerr = null;
map.on("pointermove", function (evt) {
if (selectedTerr !== null) {
selectedTerr.forEach((territory) => { territory.setStyle(undefined); });
selectedTerr = null;
}
map.forEachFeatureAtPixel(evt.pixel, function (feature, layer) {
if (layer === pointLayer) {
const targetTerritories = feature.get('TERRITORY').split(', ');
selectedTerr = polygonLayer
.getSource()
.getFeatures()
.filter((l) => targetTerritories.includes(l.get('TERRITORY')));
selectedTerr.forEach((territory) => { territory.setStyle(selectStyle); });
}
return true;
});
});
</script>
</html>

Google Maps GeoJSON feature trigger click event

I have a featurecollection of features with their corresponding IDs like this:
"type"=>"Feature",
"id"=>"test_1",
"properties"=>array("desc"=>...
and want to trigger a click event from a button on the document so that the infowindow opens.
var featId = 'test_1';
map.event.trigger(featId, 'click');
but I'm getting
Uncaught TypeError: Cannot read property 'trigger' of undefined
The infowindow opens when I click on the polygon on the map.
Here's a JS fiddle.
I've also added a code snippet using stackoverflow's editor.
var mygeojson={
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
'id':'test_2',
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
0.5767822265625,
46.437856895024204
],
[
0.560302734375,
46.160809861457125
],
[
0.9118652343749999,
46.10370875598026
],
[
1.42822265625,
46.22545288226939
],
[
0.9118652343749999,
46.581518465658014
],
[
0.5767822265625,
46.437856895024204
]
]
]
}
},
{
"type": "Feature",
'id':'test_1',
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
1.9335937499999998,
46.98774725646568
],
[
1.8841552734374998,
46.73233101286786
],
[
2.581787109375,
46.53619267489863
],
[
2.8784179687499996,
46.71350244599995
],
[
3.065185546875,
47.00647991252098
],
[
2.3785400390625,
47.18597932702905
],
[
2.1917724609375,
47.60986653003798
],
[
1.9335937499999998,
46.98774725646568
]
]
]
}
}
]
};
function openinfo(target_featId)
{
//map.event.trigger(featId, 'click');
google.maps.event.trigger(map, 'click');
}
initpage = function()
{
var selected_id = 0;
console.log('html loaded');
//center lat/lon
var latlng = new google.maps.LatLng(46.315,0.467);
//map configutations
var myOptions = {
zoom: 8,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP,
scrollwheel: true,
};
map = new google.maps.Map(document.getElementById("themap"), myOptions);
map.data.addGeoJson(mygeojson);
map.data.setStyle(function(feature) {
//var SD_NAME = feature.getProperty('SD_NAME');
//var color = feature.getProperty('boja');
var featId = feature.getId();
var color = 'gray';
if(selected_id == featId)
{
color='#009900';
console.log('setting green for '+featId)
} else
{
color = 'gray';
console.log('setting gray for '+featId)
}
return {
fillColor: color,
strokeColor: color,
strokeWeight: 1
}
});
var infowindow = new google.maps.InfoWindow();
map.data.addListener('click', function(event) {
//var feat_desc = event.feature.getProperty("desc");
var featId = event.feature.getId();
map.data.forEach(function(feature2) {
if(featId == selected_id) feature2.setProperty('color','gray');
});
selected_id = featId;
var color = '#009900';
infowindow.setContent("<div style='width:150px; color: #000;'> litttle test "+featId+"</div>");
// position the infowindow on the marker
infowindow.setPosition(event.feature.getGeometry().getAt(0).getAt(0));
infowindow.open(map);
});
}
html { height: 100% }
body { height: 100%; margin: 0px; padding: 0px; background: #fff; color: #bbb; font-size: 13px; font-family: Arial;}
#themap { height:100%; }
<html>
<head>
<script type="text/javascript" src="https://maps.google.com/maps/api/js"></script>
</head>
<body onload="initpage()">
Open poly 1
Open poly 2<br /><br />
<div id="themap">
</div>
</body>
</html>
I've successfully fixed this by using:
function openinfo(target_featId)
{
google.maps.event.trigger(map.data,'click',target_featId);
}
and then had a new issue with the addListener function. the event.feature was undefined, so I fixed it with:if(!event.feature) event.feature=event; inside map.data.addListener('click', function(event) {

Data layer not responding in event listener (Google Maps API)

I have a function where I load a geoJSON into a map, then replace it when I hit specific zoom levels. The following works when the window.map.data.setMap(null); is commented out, but only to pile on all maps as the zoom level changes. Uncommenting out the setMap(null) lines removes the map once the zoom level changes, but does not allow a new file to replace it; I'm consistently getting undefined when binding the data layer to a variable (see image at end):
if($('#map').length) {
var styledMapType = new google.maps.StyledMapType(
//this is all styling
}
], {name: 'Styled Map'});
var toronto = {lat: 43.687508, lng: -79.304293};
if ($('#map').length) {
window.map = new google.maps.Map(document.getElementById('map'), {
zoom: 12,
center: toronto,
disableDefaultUI: false,
scrollwheel: false,
streetViewControl: false,
fullscreenControl: false,
mapTypeControl: false,
zoomControl: true,
});
zoom: 16,
center: listing_address,
disableDefaultUI: false,
scrollwheel: false,
streetViewControl: false,
fullscreenControl: false,
mapTypeControl: false,
});
.var county = {
"type": "FeatureCollection",
"features": [
{ "type": "Feature", "properties": { "AREA_NAME": "Toronto Region", "Name": "", "Description": "" }, "geometry": { "type": "Polygon", "coordinates": [ [
[ -79.331290752373903, 43.6257878530946 ],
[ -79.331317617252296, 43.6256985447421 ],
[ -79.331512561913399, 43.625640321883701 ],
[ -79.331752709965201, 43.625618170498399 ],
[ -79.331959376709506, 43.625519457784897 ],
[ -79.332109811020601, 43.625312645786401 ],
[ -79.333209007789605, 43.644149630451302 ],
[ -79.333365435394498, 43.644032839820198 ],
[ -79.431165436417103, 43.630306805590003 ],
[ -79.431488362803094, 43.630361005759099 ],
[ -79.431821347539696, 43.630419711640798 ],
[ -79.432139201596499, 43.630500911132103 ],
[ -79.432442343991099, 43.630573099758003 ],
[ -79.475947295799898, 43.623398134852998 ],
[ -79.280866209706105, 43.671017401276799 ],
[ -79.307699740463903, 43.656122040811901 ],
[ -79.307771442967393, 43.655987140776503 ],
[ -79.331356425413802, 43.625806618446397 ],
[ -79.331290752373903, 43.6257878530946 ] ] ] } }
]
}
var district = {
"type": "FeatureCollection",
"features": [
{ "type": "Feature", "properties": { "AREA_ID": "108", "CITY_NAME": "", "CITY_NAME": "", "AREA_NAME": "Briar Hill-Belgravia" }, "geometry": { "type": "Polygon", "coordinates": [ [
[ -79.464620647999908, 43.692155605999957 ],
[ -79.46522206099992, 43.693230269999958 ],
[ -79.465251297999913, 43.693298486999957 ],
[ -79.465279791999919, 43.693366811999958 ],
[ -79.46530741699992, 43.693435416999954 ],
[ -79.465719907999926, 43.694757514999957 ],
[ -79.44101562199991, 43.705410816999958 ],
[ -79.440110285999921, 43.705585372999955 ],
[ -79.447685296999921, 43.696258794999956 ],
[ -79.449336555999921, 43.695897948999956 ],
[ -79.450278980999911, 43.695691998999955 ],
[ -79.451201995999909, 43.695476191999958 ],
[ -79.462902461999917, 43.69287652099996 ],
[ -79.463998089999919, 43.692404465999957 ],
[ -79.464620647999908, 43.692155605999957 ] ] ] } }
]
}
var cities ={
"type":"FeatureCollection", "features": [
{"type":"Feature","properties":
{"AREA_ID":49884,"AREA_NAME":"YORK","OBJECTID":11093905},"geometry":{"type":"Polygon","coordinates":[[[-79.49262446,43.64744493],
[-79.49249144,43.64772528],
[-79.49149894,43.65163426],
[-79.50094749,43.65228262],
[-79.503085,43.66113086],
[-79.5123581,43.67258877],
[-79.5126394,43.68922995],
[-79.50556991,43.70925399],
[-79.42776901,43.70053559],
[-79.42848543,43.68173363],
[-79.42909608,43.68160367],
[-79.48394351,43.66992188],
[-79.48405475,43.66989696],
[-79.48367372999999,43.66897745],
[-79.49262446,43.64744493]]]}},
]
}
window.map.mapTypes.set('styled_map', styledMapType);
window.map.setMapTypeId('styled_map');
// issue in question below:
if ($('#map').length) {
window.map.data.loadGeoJson( cities );
window.map.addListener('zoom_changed', function() {
var zoomLevel = map.getZoom();
if (zoomLevel <= 12 && zoomLevel >= 9) {
window.map.data.addGeoJson( cities );
} else if (zoomLevel < 9) {
window.map.data.addGeoJson( county );
} else if (zoomLevel > 12) {
window.map.data.addGeoJson( district );
};
})
window.map.data.setStyle({
fillOpacity: 0.2,
strokeWeight: 1,
strokeColor: '#1e1d1d',
fillColor: '#1e1d1d'
});
window.map.data.addListener('mouseover', function(event) {
window.map.data.overrideStyle(event.feature, {
strokeColor: '#0076c0',
fillColor: '#0076c0',
strokeWeight: 2.5,
});
});
window.map.data.addListener('mouseout', function(event) {
window.map.data.revertStyle();
});
window.map.data.addListener('click', function(event) {
window.map.data.overrideStyle(event.feature, {
strokeColor: '#0076c0',
fillColor: '#0076c0',
fillOpacity: 0.2
});
});
};
};
});
I tried the following already as per How to remove data from gmap? . Adding those variables wither above the first line of my code, or as the first section of the function before the if statement gave me unexpected identifier problems (I removed the actual code, this was my reference):
// load data - do the same for data2, data3 or whatever
data1 = new google.maps.Data();
data1.loadGeoJson(url1);
// create some layer control logic for turning on data1
data1.setMap(map) // or restyle or whatever
// turn off data1 and turn on data2
data1.setMap(null) // hides it
data2.setMap(map) // displays data2
And this is the result I'm currently getting when I set breakpoints:
What is the linkage I'm missing? The docs (https://developers.google.com/maps/documentation/javascript/reference/3.exp/#Data) suggest that loadGeoJSON and zoomchange aren't compatible methods, which seems really unlikely.
Seems to me what you want to do is create a DataLayer for each of the data sets. Then manage those based on the zoom level. Create them when they are first visible, set their map property to null when they are hidden, to your map variable when you want them visible.
var districtLayer, cityLayer, countyLayer;
window.map.addListener('zoom_changed', function() {
var zoomLevel = map.getZoom();
if (zoomLevel < 12 && zoomLevel > 9) {
// city level, hide district and county layers
if (districtLayer && districtLayer.setMap)
districtLayer.setMap(null);
if (countyLayer && countyLayer.setMap)
countyLayer.setMap(null);
if (countyLayer && countyLayer.setMap)
countyLayer.setMap(null);
if (!cityLayer) {
cityLayer = new google.maps.Data();
cityLayer.addGeoJson(cities);
}
cityLayer.setMap(map);
} else if (zoomLevel <= 9) {
// county level, hide city and county layers
if (cityLayer && cityLayer.setMap)
cityLayer.setMap(null);
if (districtLayer && districtLayer.setMap)
districtLayer.setMap(null);
if (!countyLayer) {
countyLayer = new google.maps.Data();
countyLayer.addGeoJson(county);
}
countyLayer.setMap(map);
} else if (zoomLevel >= 12) {
// city level, hide district and county layers
if (cityLayer && cityLayer.setMap)
cityLayer.setMap(null);
if (countyLayer && countyLayer.setMap)
countyLayer.setMap(null);
if (!districtLayer) {
districtLayer = new google.maps.Data();
districtLayer.addGeoJson(district);
}
districtLayer.setMap(map);
}
});
proof of concept fiddle
code snippet:
function initialize() {
var districtLayer, cityLayer, countyLayer;
if ($('#map').length) {
var toronto = {
lat: 43.689577,
lng: -79.453715
};
window.map = new google.maps.Map(document.getElementById('map'), {
zoom: 12,
center: toronto,
disableDefaultUI: false,
scrollwheel: false,
streetViewControl: false,
fullscreenControl: false,
mapTypeControl: false,
});
window.map.addListener('zoom_changed', function() {
var zoomLevel = map.getZoom();
if (districtLayer && districtLayer.setMap)
districtLayer.setMap(null);
if (countyLayer && countyLayer.setMap)
countyLayer.setMap(null);
document.getElementById('zoom').innerHTML = zoomLevel;
if (zoomLevel < 12 && zoomLevel > 9) {
document.getElementById('zoom').innerHTML += ":city";
if (countyLayer && countyLayer.setMap)
countyLayer.setMap(null);
if (!cityLayer) {
cityLayer = new google.maps.Data();
cityLayer.addGeoJson(cities);
}
cityLayer.setMap(map);
} else if (zoomLevel <= 9) {
document.getElementById('zoom').innerHTML += ":county";
if (cityLayer && cityLayer.setMap)
cityLayer.setMap(null);
if (districtLayer && districtLayer.setMap)
districtLayer.setMap(null);
if (!countyLayer) {
countyLayer = new google.maps.Data();
countyLayer.addGeoJson(county);
}
countyLayer.setMap(map);
} else if (zoomLevel >= 12) {
document.getElementById('zoom').innerHTML += ":district";
if (cityLayer && cityLayer.setMap)
cityLayer.setMap(null);
if (countyLayer && countyLayer.setMap)
countyLayer.setMap(null);
if (!districtLayer) {
districtLayer = new google.maps.Data();
districtLayer.addGeoJson(district);
}
districtLayer.setMap(map);
}
});
google.maps.event.trigger(map, 'zoom_changed');
}
}
google.maps.event.addDomListener(window, "load", initialize);
var county = {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"properties": {
"AREA_NAME": "Toronto Region",
"Name": "",
"Description": ""
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[-79.486178, 43.59873],
[-79.514712, 43.719608],
[-79.260958, 43.755659],
[-79.230746, 43.634522],
[-79.486178, 43.59873]
]
]
}
}]
};
var district = {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"properties": {
"AREA_ID": "108",
"CITY_NAME": "",
"CITY_NAME": "",
"AREA_NAME": "Briar Hill-Belgravia"
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[-79.464620647999908, 43.692155605999957],
[-79.46522206099992, 43.693230269999958],
[-79.465251297999913, 43.693298486999957],
[-79.465279791999919, 43.693366811999958],
[-79.46530741699992, 43.693435416999954],
[-79.465719907999926, 43.694757514999957],
[-79.44101562199991, 43.705410816999958],
[-79.440110285999921, 43.705585372999955],
[-79.447685296999921, 43.696258794999956],
[-79.449336555999921, 43.695897948999956],
[-79.450278980999911, 43.695691998999955],
[-79.451201995999909, 43.695476191999958],
[-79.462902461999917, 43.69287652099996],
[-79.463998089999919, 43.692404465999957],
[-79.464620647999908, 43.692155605999957]
]
]
}
}]
}
var cities = {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"properties":
{
"AREA_ID": 49884,
"AREA_NAME": "YORK",
"OBJECTID": 11093905
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[-79.49262446, 43.64744493],
[-79.49249144, 43.64772528],
[-79.49149894, 43.65163426],
[-79.50094749, 43.65228262],
[-79.503085, 43.66113086],
[-79.5123581, 43.67258877],
[-79.5126394, 43.68922995],
[-79.50556991, 43.70925399],
[-79.42776901, 43.70053559],
[-79.42848543, 43.68173363],
[-79.42909608, 43.68160367],
[-79.48394351, 43.66992188],
[-79.48405475, 43.66989696],
[-79.48367372999999, 43.66897745],
[-79.49262446, 43.64744493]
]
]
}
}, ]
};
html,
body,
#map {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="zoom"></div>
<div id="map"></div>

Google Maps API: getFeatureById for feature collection not working

I try to change the style of a specific feature of a feature collection data overlay. This is a snippet of my json:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"id": 1,
"properties": {
"name": "1 CBD - Bankenviertel",
"color": "transparent",
"isHovered": false,
"isActive": false
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
8.67279430349,
50.1143807311
],
[
8.67280054398,
50.1143975981
]
]
]
}
}
and this is the relevant snippet from my map.js
map.data.loadGeoJson('some.json');
console.log(map.data.getFeatureById(1));
And I am always getting "undefined" in the console.
What am I doing wrong here?
Thanks,
Robert
You need to call map.data.getFeatureById(1) inside the callback function (so it doesn't execute before the GeoJson has loaded).
from the documentation:
loadGeoJson(url:string, options?:Data.GeoJsonOptions, callback?:function(Array<Data.Feature>))
Return Value: None
Loads GeoJS
proof of concept fiddle
code snippet:
var geocoder;
var map;
function initialize() {
var map = new google.maps.Map(
document.getElementById("map_canvas"), {
zoom: 4,
center: {
lat: -28,
lng: 137
},
mapTypeId: google.maps.MapTypeId.ROADMAP
});
// map.data.addGeoJson(geoJson);
map.data.loadGeoJson(
'https://api.myjson.com/bins/1teyu', {},
function(features) {
console.log(map.data.getFeatureById(1));
console.log(map.data.getFeatureById(1).getProperty("letter"));
});
}
google.maps.event.addDomListener(window, "load", initialize);
html,
body,
#map_canvas {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="map_canvas"></div>

Categories

Resources