Using Open Layers and leaflet-sidebar-v2, I've added the sidebar to my map, this works. However, I also need to add another layer to my map, this layer will outline each country. I have the coordinates stored in a 'borders.json' file. I'm attempting to use D3.json to to import the border coordinates and then L.geoJson to add the new layer to my map.
I'm currently getting the following error message:
Uncaught TypeError: t.getLayerStatesArray is not a function
Here is the relevant part of my code..
var map = new ol.Map({
target: "map",
layers: [
new ol.layer.Tile({
source: new ol.source.OSM(),
}),
],
view: new ol.View({
center: ol.proj.transform([7, 51.2], "EPSG:4326", "EPSG:3857"),
zoom: 3,
}),
});
var sidebar = new ol.control.Sidebar({
element: "sidebar",
position: "left",
});
map.addControl(sidebar);
d3.json(("borders.json"), function (json){
function style(feature) {
return {
fillColor: "transparent",
weight: 1,
opacity: 0.4,
color: 'grey',
fillOpacity: 0.3
}
}
geojson = L.geoJson(json, {
style: style,
}).addTo(map);
})
I think I might be adding the geojson layer to my map incorrectly, but I can't figure out what is wrong. I've spent quite a bit of time playing with it, but no luck.
Any helps is appreciated.
Cheers,
Beat
It might be hard to tell what the problem is without knowing other possible relevant parts of your code. I'd start by checking that the contents of borders.json follows valid GeoJSON format.
This is likely unrelated to your question, but is there a reason that you've declared style as a function like function style(feature) { ... }?
It looks like the style attribute of L.geoJson accepts an object rather than a function.
Related
I'm new to Openlayers. While I was using Node.js, my codes were working fine. But I ran into some problems when I switched to Asp.Net Core.
I learned that when calling modules to use them in Asp.Net Core I need to add some prefixes to their heads.
For example to be able to use the "Map" module:
const map = new ol.Map({ });
But I don't know what prefix I should add before "defaultInteractions()" in this line
interactions: defaultInteractions().extend([select, translate]),
Here is my Map code snippet
const map = new ol.Map({
interactions: defaultInteractions().extend([select, translate]),
layers: [
new ol.layer.Image({
source: new ol.source.ImageStatic({
url: 'https://imgs.xkcd.com/comics/online_communities.png',
projection: projection,
imageExtent: extent,
}),
}),
rasterLayer, vectorLayer
],
target: 'map',
view: new ol.View({
projection: projection,
center: ol.extent.getCenter(extent),
zoom: 2,
maxZoom: 8,
}),
});
When I ctrl + left click on defaultInteraction(), the ol.interaction.js page opens,
When I ctrl + left click on extend([select, translate]) the ol.Collection.js page opens.
But both are not working.
Here is the error i got
Thanks in advance and have a good day <(^.^)>
[solved]
I changed the line to:
interactions: ol.interaction.defaults().extend([select, translate]),
I started working on a Vector Layer to render SQL Spatial Data in OpenLayers. When rendering this example (see Json) everything works perfectly fine. See code below:
//creates source to get json data from
let vSource = new VectorSource({
url: '/assets/germany.json',
format: new GeoJSON()
});
//set focus of the camera on this source
vSource.on('addfeature', () => {
this.map.getView().fit(vSource.getExtent());
console.log(this.map.getView().getCenter());
});
//add source to layer and afterwards load it into map
let vLayer = new VectorLayer({
source: vSource,
visible: true
});
//layer styling
vLayer.setStyle(new Style({
stroke: new Stroke({
color: '#FF5733',
width: 8
})
}));
this.map.addLayer(vLayer);
Map instantiation looks as following:
this.map = new Map({
view: new View({
center: [10, 10],
zoom: 3,
}),
layers: [],
target: 'ol-map'
});
But when i want to render this json file I am facing a blank map. Focus wont get set and not even errors appear. I am assuming its all about the boundaries?
How can Polygon coordinates get rendered which are our outside default boundaries, if there is such thing as "default"?
For example:
[12058.4521484375, 5345.98388671875],
[11408.95703125, 5345.98388671875]
Reading through the API I can deduce that the option extent may be key to solving this issue?
Best regards
A newbie at OpenLayers
Openlayers default projection is EPSG:3857. I think your geojson and center of map is EPSG:4326.
this.map = new Map({
view: new View({
projection: 'EPSG:4326',
center: [10, 10],
zoom: 3,
}),
layers: [],
target: 'ol-map'
});
let vSource = new VectorSource({
url: '/assets/germany.json',
format: new GeoJSON({ featureProjection: 'EPSG:3857' })
});
I am trying to add a custom marker in React Google Maps and have each marker rotate based on the direction that the item is heading on the road.
I am able to make the rotation work when I use path for an svg instead of a url referencing an image. The problem with path is that I cannot get fillColor to work, only strokeColor. It would also be nice to have a complex shape and path is somewhat restricting in the type of shape that you can add to it, because cannot pass multiple paths into the string.
Please note that heading is getting the proper direction via my api and I have verified that it works.
Here is my current code, any help is appreciated. Thanks!
const createIcon = (heading) => ({
width: '15px',
url:
'my image path',
rotation: heading || 0, // set the rotation prop to indicate direction
});
Do you have a <\Marker> component being rendered? This is what I was able to get working for rotating a Marker. No issues with fillColor either.
render() {
return <Marker
position={{ lat: this.state.longitude, lng: this.state.latitude }}
icon={
{
path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW,
scale: 3,
strokeColor: "#FFFFFF",
fillColor: "#0000FF",
fillOpacity: 1,
rotation: 215
}
}
/>
}
I have little Leaflet application where the app get geoJson objects from server, and display it, specially LineString. The JSON parser that i use on server side works properly. And the client side script was ok too.
But some reasons I would like to draw arrow on the routes, and I can't figure out how to do it when using L.geoJson().
Code with L.geoJson():
getJsonFrom(routeQueryURL, params, function(data) {
var a = L.geoJson(data, {
onEachFeature: bindRouteDirection,
}).addTo(map);
});
Because I don't want to change anything on server side, I tried this:
getJsonFrom(routeQueryURL, param, function(data) {
$.each(data, function(index, feature) {
var polyline = new L.Polyline(feature.geometry.coordinates, {
color: feature.properties.color,
opacity: 0.8
}).addTo(routeMapLayer);
var decorator = L.polylineDecorator(polyline, {
patterns: [{
offset: 25,
repeat: 50,
symbol: L.Symbol.arrowHead({
pixelSize: 15,
pathOptions: {
stroke: true,
color: feature.properties.color,
fillOpacity: 0.8,
polygon: false,
weight: 3
}
})
}]
}).addTo(routeMapLayer);
map.addLayer(routeMapLayer);
});
});
So i access the array of coordinates from the geoJson object, and some other data, and draw the polyline directly on to map.The problem is that it's put my route into the middle of middle east instead of Hungary, so it's actually swap the coordinates. Why does L.Polyline handle the different form L.geoJson()?
Use L.GeoJSON.coordsToLatLng() and read why sometimes coordinates are lat-lng and sometimes lng-lat.
I am using the MarkerCluster.js to create clustering in my google maps api. The clusters work how I want them however I want to style differently than yellow, blue and red circles. I was trying to use the MarkerStyleOptions and it says you have an array of styles with the smallest cluster icon first and the biggest last. I tried to create this below but I am getting really confused about what syntax to use and can't find any good examples.
var clusterStyles = [
[opt_textColor: 'white'],
[opt_textColor: 'white'],
[opt_textColor: 'white']
];
var mcOptions = {
gridSize: 50,
styles: clusterStyles,
maxZoom: 15
};
var markerclusterer = new MarkerClusterer(map, cluster, mcOptions);
What you need to do is use the url to specify which images to use instead of the blue/yellow/red images currently being used. And probably a good idea to include the height and width options too.
var clusterStyles = [
{
textColor: 'white',
url: 'path/to/smallclusterimage.png',
height: 50,
width: 50
},
{
textColor: 'white',
url: 'path/to/mediumclusterimage.png',
height: 50,
width: 50
},
{
textColor: 'white',
url: 'path/to/largeclusterimage.png',
height: 50,
width: 50
}
];
It's never too late to post a rather helpful answer, so additionally you can look through the whole MarkerClusterer Documentation for IconStyle
UPDATE
There's also google maps v3 utility on github as stated by ehcanadian
According to latest docs, renderer does the trick. It allows you to use a Marker w/all its styling options - see Marker documentation:
new MarkerClusterer({
renderer: {
render: ({ markers, _position: position }) => {
//here is where you return a Marker
//and style it w/custom label/icon props
return new google.maps.Marker({
position: {
lat: position.lat(),
lng: position.lng(),
},
label: String(markers.length),
});
},
},
...etc
});
You can now pass your own renderer to your MarkerClusterer Object which returns a google.maps.Marker like this:
const renderer = {
render({ count, position }) {
return new google.maps.Marker({
label: { text: String(count), color: "white", fontSize: "10px" },
position,
// adjust zIndex to be above other markers
zIndex: Number(google.maps.Marker.MAX_ZINDEX) + count,
});
}
}
// use this if you use NPM version
const markerCluster = new MarkerClusterer({ map, markers, renderer });
// Use this if you use the CDN version
// const markerCluster = new markerClusterer.MarkerClusterer({ markers, map , renderer});
Inside the render method, you can customize the cluster maker the same way you would customize normal marker. See https://developers.google.com/maps/documentation/javascript/custom-markers for more details. For example, if you just want to add a specific icon.png you could do it like this:
const icon = {
url: '/path/to/your/icon.png',
scaledSize: new google.maps.Size(50, 50),
};
const renderer = {
render({ count, position }) {
return new google.maps.Marker({
label: { text: String(count), color: "white", fontSize: "10px" },
position,
icon,
// adjust zIndex to be above other markers
zIndex: Number(google.maps.Marker.MAX_ZINDEX) + count,
});
}
}
You can also find some clustor marker render example at https://googlemaps.github.io/js-markerclusterer/public/renderers/
See https://developers.google.com/maps/documentation/javascript/marker-clustering for a full example how to setup MarkerCluster.
History Details:
The MarkerCluster library has been rewritten in 2021. One goal was to change the render process. The cluster icon itself is now a google.maps.Marker and can thus be styled just as normal marker. The mcOptions in the constructor is gone.
The proposed design is to encapsulate the logic for clustering and rendering into interfaces that the developer can extend specifically algorithm and renderer. The algorithm computes the clusters and the renderer generates a google.maps.Marker to represent clusters instead of using a google.maps.OverlayView.
https://github.com/googlemaps/js-markerclustererplus/issues/300
https://github.com/googlemaps/js-markerclustererplus/issues/293
https://docs.google.com/document/d/1X8hQaHdVvpB-12bOQ_qbgfGFet8gPRTtHyO_EihcpsA/edit