I am working on an open layers map with different vector layers. I'm trying to show the information of the features in the geojson on the layer via a popup window. I found these two references:
http://jsfiddle.net/zt2tyzqo/2/
https://embed.plnkr.co/plunk/GvdVNE
Thank you for any support. :)
This is the geojson:
{
"type": "FeatureCollection",
"name": "dachnotnull",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [
{ "type": "Feature", "properties": { "OBJECTID": 9, "GEBFLAECHE": 214.0, "GREENAR05": 13.0, "GREENAR20": 0.0, "SHAPE_AREA": 214.42924681599999, "SHAPE_LEN": 0.0, "p_intensiv": 0.060626058212800003, "p_extensiv": 0.0, "p_gesamt": 0.060626058212800003, "flaeche": 214.42924681599999 }, "geometry": { "type": "MultiPolygon", "coordinates":
This is the main.js:
import 'ol/ol.css';
import Map from 'ol/Map';
import View from 'ol/View';
import TileLayer from 'ol/layer/Tile';
import Stamen from 'ol/source/Stamen';
import VectorLayer from 'ol/layer/Vector';
import Vector from 'ol/source/Vector';
import GeoJSON from 'ol/format/GeoJSON';
import Style from 'ol/style/Style';
import Circle from 'ol/style/Circle';
import Fill from 'ol/style/Fill';
import Stroke from 'ol/style/Stroke';
import Overlay from 'ol/Overlay';
import {
fromLonLat,
toLonLat
} from 'ol/proj';
import sync from 'ol-hashed';
import OSM from 'ol/source/OSM';
import Feature from 'ol/Feature';
import {
circular
} from 'ol/geom/Polygon';
import Point from 'ol/geom/Point';
import Control from 'ol/control/Control';
import * as olProj from 'ol/proj';
import XYZ from 'ol/source/XYZ';
// define the map
const map = new Map({
target: 'map',
view: new View({
center: fromLonLat([16.37, 48.2]),
zoom: 13
})
});
sync(map);
//Adresssuche
const searchResultSource = new Vector();
const searchResultLayer = new VectorLayer({
source: searchResultSource
});
searchResultLayer.setStyle(new Style({
image: new Circle({
fill: new Fill({
color: 'rgba(0, 128, 0, 1)'
}),
stroke: new Stroke({
color: '#000000',
width: 1.25
}),
radius: 15
})
}));
var element = document.getElementById('search');
element.addEventListener('keydown', listenerFunction);
function listenerFunction(event) {
console.log(event);
console.log(event.keyCode);
if (event.keyCode === 13) {
const xhr = new XMLHttpRequest;
xhr.open('GET', 'https://photon.komoot.de/api/?q=' + element.value + '&limit=3');
xhr.onload = function () {
const json = JSON.parse(xhr.responseText);
const geoJsonReader = new GeoJSON({
featureProjection: 'EPSG:3857'
});
searchResultSource.clear();
const features = geoJsonReader.readFeatures(json);
console.log(features);
searchResultSource.addFeatures(features);
if (!searchResultSource.isEmpty()) {
map.getView().fit(searchResultSource.getExtent(), {
maxZoom: 18,
duration: 500
});
}
};
xhr.send();
}
}
//OpenStreetMap
const OSMbaseLayer = new TileLayer({
type: 'base',
source: new OSM()
});
// Statellit
const satellitLayer = new TileLayer({
source: new XYZ({
attributions: ['Powered by Esri', 'Source: Esri, DigitalGlobe, GeoEye, Earthstar Geographics, CNES/Airbus DS, USDA, USGS, AeroGRID, IGN, and the GIS User Community'],
attributionsCollapsible: false,
url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
maxZoom: 30
})
});
//shape
const parkLayer = new VectorLayer({
source: new Vector({
name: 'park',
url: 'data/park1.geojson',
format: new GeoJSON()
})
});
parkLayer.setStyle(new Style({
fill: new Fill({
color: 'green'
}),
stroke: new Stroke({
color: 'green',
width: 1.25
}),
}));
const hitzeLayer = new VectorLayer({
source: new Vector({
name: 'hitze',
url: 'data/hitze.geojson',
format: new GeoJSON()
})
});
hitzeLayer.setStyle(new Style({
fill: new Fill({
color: 'red'
}),
stroke: new Stroke({
color: 'yellow',
width: 1.25
}),
}));
hitzeLayer.setStyle(function(feature) {
let fillColor;
const hitzeindex = feature.get('AVG_UHVI_A');
if (hitzeindex < 0.5) {
fillColor = 'rgba(255, 228, 225, 0.7)';
} else if (hitzeindex < 0.75) {
fillColor = 'rgba(240, 128, 128, 0.7)';
} else {
fillColor = 'rgba(128, 0, 0, 0.7)';
}
return new Style({
fill: new Fill({
color: fillColor
}),
stroke: new Stroke({
color: 'rgba(4, 4, 4, 1)',
width: 1
})
});
});
const dachLayer = new VectorLayer({
minZoom: 17.9999,
source: new Vector({
name: 'dach',
url: 'data/dachnotnull.geojson',
format: new GeoJSON()
})
});
dachLayer.setStyle(function(feature) {
let fillColor;
const begruenung = feature.get('p_gesamt');
if (begruenung < 0.2) {
fillColor = 'rgba(143, 188, 143, 1)';
} else if (begruenung < 0.4) {
fillColor = 'rgba(60, 179, 113, 1)';
} else if (begruenung < 0.6) {
fillColor = 'rgba(46, 139, 87, 1)';
} else if (begruenung < 0.8) {
fillColor = 'rgba(34, 139, 34, 1)';
} else {
fillColor = 'rgba(0, 100, 0, 1)';
}
return new Style({
fill: new Fill({
color: fillColor
})
});
});
// Layer hinzufügen
map.addLayer(OSMbaseLayer);
map.addLayer(searchResultLayer);
dachLayer.setZIndex(15);
parkLayer.setZIndex(10);
hitzeLayer.setZIndex(5);
// gruenflaechen layer anzeigen
const park = document.getElementById('park');
park.addEventListener('click', function (event) {
var checkBox = document.getElementById("park");
if (checkBox.checked == true) {
parkLayer.setMap(map);
// parkLayer.setVisible(true);
} else {
parkLayer.setMap(undefined);
//parkLayer.setVisible(false);
}
});
// hitze layer anzeigen
const hitze = document.getElementById('hitze');
hitze.addEventListener('click', function (event) {
var checkBox = document.getElementById("hitze");
if (checkBox.checked == true) {
hitzeLayer.setMap(map);
//hitzeLayer.setVisible(true);
} else {
//hitzeLayer.setVisible(false);
hitzeLayer.setMap(undefined);
}
});
// dach layer anzeigen
const dach = document.getElementById('dach');
dach.addEventListener('click', function (event) {
var checkBox = document.getElementById("dach");
if (checkBox.checked == true) {
dachLayer.setMap(map);
//hitzeLayer.setVisible(true);
} else {
//hitzeLayer.setVisible(false);
dachLayer.setMap(undefined);
}
});
// Get the OSMbase Base-Button
const OSMbase = document.getElementById('OSMbase');
OSMbase.addEventListener('click', function (event) {
//contr.style.color = 'ffffff';
//Andere Layer entfernen
map.removeLayer(satellitLayer);
map.removeLayer(searchResultLayer);
//OSM Layer hinzufügen
map.addLayer(OSMbaseLayer);
map.addLayer(searchResultLayer);
});
// Get the satellit Base-Button
const satellit = document.getElementById('satellit');
satellit.addEventListener('click', function (event) {
//Andere Layer entfernen
map.removeLayer(OSMbaseLayer);
map.removeLayer(searchResultLayer);
//Satelliten Layer hinzufügen
map.addLayer(satellitLayer);
map.addLayer(searchResultLayer);
});
//GPS Location
const GPSsource = new Vector();
const GPSlayer = new VectorLayer({
source: GPSsource
});
map.addLayer(GPSlayer);
navigator.geolocation.watchPosition(function (pos) {
const coords = [pos.coords.longitude, pos.coords.latitude];
const accuracy = circular(coords, pos.coords.accuracy);
GPSsource.clear(true);
GPSsource.addFeatures([
new Feature(accuracy.transform('EPSG:4326', map.getView().getProjection())),
new Feature(new Point(fromLonLat(coords)))
]);
}, function (error) {
alert(`ERROR: ${error.message}`);
}, {
enableHighAccuracy: true
});
const locate = document.createElement('div');
locate.className = 'ol-control ol-unselectable locate';
locate.innerHTML = '<button title="Locate me">◎</button>';
locate.addEventListener('click', function () {
if (!GPSsource.isEmpty()) {
map.getView().fit(GPSsource.getExtent(), {
maxZoom: 18,
duration: 500
});
}
});
map.addControl(new Control({
element: locate
}));
you need to add a overlay to your map object;
use setPosition of your overlay object to snap to a point
example:
https://openlayers.org/en/latest/examples/popup.html
api: https://openlayers.org/en/latest/apidoc/module-ol_Overlay-Overlay.html
Related
Im using the hexagon layer example from deck.gl as my base and trying to find a way to include a control panel similar to their online website https://deck.gl/examples/hexagon-layer/
import React from 'react';
import {render} from 'react-dom';
import {StaticMap} from 'react-map-gl';
import {AmbientLight, PointLight, LightingEffect} from '#deck.gl/core';
import {HexagonLayer} from '#deck.gl/aggregation-layers';
import DeckGL from '#deck.gl/react';
import {Controller} from 'deck.gl';
// Source data CSV
const DATA_URL =
'https://raw.githubusercontent.com/visgl/deck.gl-data/master/examples/3d-heatmap/heatmap-data.csv'; // eslint-disable-line
const ambientLight = new AmbientLight({
color: [255, 255, 255],
intensity: 1.0
});
const pointLight1 = new PointLight({
color: [255, 255, 255],
intensity: 0.8,
position: [-0.144528, 49.739968, 80000]
});
const pointLight2 = new PointLight({
color: [255, 255, 255],
intensity: 0.8,
position: [-3.807751, 54.104682, 8000]
});
const lightingEffect = new LightingEffect({ambientLight, pointLight1, pointLight2});
const OPTIONS = ['radius', 'coverage', 'upperPercentile'];
const material = {
ambient: 0.64,
diffuse: 0.6,
shininess: 32,
specularColor: [51, 51, 51]
};
const INITIAL_VIEW_STATE = {
longitude: -1.415727,
latitude: 52.232395,
zoom: 6.6,
minZoom: 5,
maxZoom: 15,
pitch: 40.5,
bearing: -27
};
const MAP_STYLE = 'https://basemaps.cartocdn.com/gl/dark-matter-nolabels-gl-style/style.json';
export const colorRange = [
[1, 152, 189],
[73, 227, 206],
[216, 254, 181],
[254, 237, 177],
[254, 173, 84],
[209, 55, 78]
];
OPTIONS.forEach(key => {
document.getElementById(key).oninput = renderLayer;
});
renderLayer();
function renderLayer () {
const options = {};
OPTIONS.forEach(key => {
const value = +document.getElementById(key).value;
document.getElementById(key + '-value').innerHTML = value;
options[key] = value;
});
function getTooltip({object}) {
if (!object) {
return null;
}
const lat = object.position[1];
const lng = object.position[0];
const count = object.points.length;
return `\
latitude: ${Number.isFinite(lat) ? lat.toFixed(6) : ''}
longitude: ${Number.isFinite(lng) ? lng.toFixed(6) : ''}
${count} Accidents`;
}
/* eslint-disable react/no-deprecated */
export default function App({
data,
mapStyle = MAP_STYLE,
radius = 1000,
upperPercentile = 100,
coverage = 1
}) {
const layers = [
new HexagonLayer({
id: 'heatmap',
colorRange,
data,
elevationRange: [0, 3000],
elevationScale: data && data.length ? 50 : 0,
extruded: true,
getPosition: d => d,
pickable: true,
material,
coverage,
radius,
upperPercentile,
transitions: {
elevationScale: 3000
}
})
];
return (
<DeckGL
layers={layers}
effects={[lightingEffect]}
initialViewState={INITIAL_VIEW_STATE}
controller={true}
getTooltip={getTooltip}
>
<StaticMap reuseMaps mapStyle={mapStyle} preventStyleDiffing={true}/>
</DeckGL>
);
}
export function renderToDOM(container) {
render(<App />, container);
require('d3-request').csv(DATA_URL, (error, response) => {
if (!error) {
const data = response.map(d => [Number(d.lng), Number(d.lat)]);
render(<App data={data} />, container);
}
});
}
This is what the happens if i run the example code without the control panel
This is the what loads when i run the current code (example with my additions
I am new to javascript,
so any help is much appreciated!
I think you forgot to add mapboxApiAccessToken to your StaticMap component because react-map-gl is a Mapbox map library for React js.
const MAPBOX_TOKEN = '...'
// some code here
return(
// some code here
<StaticMap
reuseMaps
mapStyle={mapStyle}
preventStyleDiffing={true}
mapboxApiAccessToken={MAPBOX_TOKEN}
/>
// some code here
)
You can get the value of Mapbox token from here https://account.mapbox.com/access-tokens/
I created an openlayers map with different vector layers. Now I want to set the style for "hitzeLayer" according to the attributes "AVG_UHVI_A" of the attribute table from the geojson. The attributes in the column "AVG_UHVI_A" have different values ranging from 0 - 1, which describe the heat-index of several locations. I tried it with the following code but it didn't work. I am very happy about any sort of support. :)
import 'ol/ol.css';
import Map from 'ol/Map';
import View from 'ol/View';
import TileLayer from 'ol/layer/Tile';
import Stamen from 'ol/source/Stamen';
import VectorLayer from 'ol/layer/Vector';
import Vector from 'ol/source/Vector';
import GeoJSON from 'ol/format/GeoJSON';
import Style from 'ol/style/Style';
import Circle from 'ol/style/Circle';
import Fill from 'ol/style/Fill';
import Stroke from 'ol/style/Stroke';
import Overlay from 'ol/Overlay';
import {
fromLonLat,
toLonLat
} from 'ol/proj';
import sync from 'ol-hashed';
import OSM from 'ol/source/OSM';
import Feature from 'ol/Feature';
import {
circular
} from 'ol/geom/Polygon';
import Point from 'ol/geom/Point';
import Control from 'ol/control/Control';
import * as olProj from 'ol/proj';
import XYZ from 'ol/source/XYZ';
// define the map
const map = new Map({
target: 'map',
view: new View({
center: fromLonLat([16.37, 48.2]),
zoom: 13
})
});
sync(map);
//Adresssuche
const searchResultSource = new Vector();
const searchResultLayer = new VectorLayer({
source: searchResultSource
});
searchResultLayer.setStyle(new Style({
image: new Circle({
fill: new Fill({
color: 'rgba(0, 128, 0, 1)'
}),
stroke: new Stroke({
color: '#000000',
width: 1.25
}),
radius: 15
})
}));
var element = document.getElementById('search');
element.addEventListener('keydown', listenerFunction);
function listenerFunction(event) {
console.log(event);
console.log(event.keyCode);
if (event.keyCode === 13) {
const xhr = new XMLHttpRequest;
xhr.open('GET', 'https://photon.komoot.de/api/?q=' + element.value + '&limit=3');
xhr.onload = function () {
const json = JSON.parse(xhr.responseText);
const geoJsonReader = new GeoJSON({
featureProjection: 'EPSG:3857'
});
searchResultSource.clear();
const features = geoJsonReader.readFeatures(json);
console.log(features);
searchResultSource.addFeatures(features);
if (!searchResultSource.isEmpty()) {
map.getView().fit(searchResultSource.getExtent(), {
maxZoom: 18,
duration: 500
});
}
};
xhr.send();
}
}
//OpenStreetMap
const OSMbaseLayer = new TileLayer({
type: 'base',
source: new OSM()
});
// Statellit
const satellitLayer = new TileLayer({
source: new XYZ({
attributions: ['Powered by Esri', 'Source: Esri, DigitalGlobe, GeoEye, Earthstar Geographics, CNES/Airbus DS, USDA, USGS, AeroGRID, IGN, and the GIS User Community'],
attributionsCollapsible: false,
url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
maxZoom: 30
})
});
//shape
const parkLayer = new VectorLayer({
source: new Vector({
name: 'park',
url: 'data/park1.geojson',
format: new GeoJSON()
})
});
parkLayer.setStyle(new Style({
fill: new Fill({
color: 'green'
}),
stroke: new Stroke({
color: 'green',
width: 1.25
}),
}));
const hitzeLayer = new VectorLayer({
source: new Vector({
name: 'hitze',
url: 'data/hitze.geojson',
format: new GeoJSON()
})
});
hitzeLayer.setStyle(function(feature) {
let fillColor;
const hitzeindex = feature.get('AVG_UHVI_A');
if (hitzeindex <= 1) {
fillColor = 'rgba(238, 233, 233, 0.7';
} else if (hitzeindex < 0.75) {
fillColor = 'rgba(205, 201, 201, 0.7)';
} else {
fillColor = 'rgba(139, 137, 137, 0.7)';
}
return new Style({
fill: new Fill({
color: fillColor
}),
stroke: new Stroke({
color: 'rgba(4, 4, 4, 1)',
width: 1
})
});
});
You say the data is between 0 and 1.
The 1st if statement in the styling function is if value <= 1, so all your features will be styled with the 1st style.
You will want the other way around:
if value < 0.5 then ..., else if value < 0.75 then ... else ... (the else being >=0.75 and <=1 since it is the max possible value)
How can I enable animation of TripsLayer without react? TripsLayer example uses React and I really don't know, how to convert it to pure js. Please look at "animate" function in the code below. I tried to update state of layer but it doesn't work (there is no animation of TripsLayer). I don't know, where should I assign "time" variable.
Demo of TripsLayer: https://deck.gl/#/examples/custom-layers/trip-routes
React version my code: https://github.com/uber/deck.gl/blob/master/examples/website/trips/app.js
Docs for TripsLayer: https://github.com/uber/deck.gl/tree/master/modules/experimental-layers/src/trips-layer
My code:
import {MapboxLayer} from '#deck.gl/mapbox';
import {TripsLayer} from '#deck.gl/experimental-layers';
import mapboxgl from 'mapbox-gl';
class App
{
constructor()
{
this.stateInfo = { time: 600 };
}
get state()
{
return this.stateInfo;
}
animate() {
var loopLength = 18000; // unit corresponds to the timestamp in source data
var animationSpeed = 30; // unit time per second
const timestamp = Date.now() / 1000;
const loopTime = loopLength / animationSpeed;
var time = Math.round(((timestamp % loopTime) / loopTime) * loopLength);
// HOW SHOULD I USE time VARIABLE???
window.requestAnimationFrame(this.animate.bind(this));
}
}
var obido = new App();
var tripsLayerObido = new TripsLayer({
id: 'trips',
data: 'trips/tripsKR.json',
getPath: d => d.segments,
getColor: d => (d.vendor === 0 ? [253, 128, 93] : [23, 184, 190]),
opacity: 0.6,
strokeWidth: 30,
trailLength: 180,
currentTime: obido.state.time
});
const LIGHT_SETTINGS = {
lightsPosition: [-74.05, 40.7, 8000, -73.5, 41, 5000],
ambientRatio: 0.05,
diffuseRatio: 0.6,
specularRatio: 0.8,
lightsStrength: [2.0, 0.0, 0.0, 0.0],
numberOfLights: 2
};
export const INITIAL_VIEW_STATE = {
longitude: 19.93,
latitude: 50.03,
zoom: 12.8,
maxZoom: 19,
pitch: 60,
bearing: 0
};
mapboxgl.accessToken = "XXX";
const map = new mapboxgl.Map({
container: 'app',
style: 'mapbox://styles/elninopl/cjnlge6rl094w2so70l1cf8y5',
center: [INITIAL_VIEW_STATE.longitude, INITIAL_VIEW_STATE.latitude],
zoom: INITIAL_VIEW_STATE.zoom,
pitch: INITIAL_VIEW_STATE.pitch,
layers: [tripsLayerObido]
});
map.on('load', () => {
obido.animate(0);
});
Please try setProps, which makes my trips layer updates:
this.tripsLayer.setProps({ currentTime: this.currentTime });
yes,it works.
function animate(timestamp) {
var timestamp = Date.now() / 1000;
var loopTime = loopLength / animationSpeed;
curtime= ((timestamp % loopTime) / loopTime) * loopLength;
requestAnimationFrame(animate);
tripLayer.setProps({ currentTime: curtime });
}
I'm a bit late here, but here there is an example of using deck.gl TripsLayer with the Scripting API (without React).
<script src="https://unpkg.com/deck.gl#^8.4.0/dist.min.js"></script>
<script src="https://unpkg.com/#deck.gl/carto#^8.4.0/dist.min.js"></script>
<script src="https://libs.cartocdn.com/mapbox-gl/v1.13.0/mapbox-gl.js"></script>
<link href="https://libs.cartocdn.com/mapbox-gl/v1.13.0/mapbox-gl.css" rel="stylesheet" />
<div id="map" style="width: 100vw; height: 100vh"></div>
const ambientLight = new deck.AmbientLight({
color: [255, 255, 255],
intensity: 1.0
});
const pointLight = new deck.PointLight({
color: [255, 255, 255],
intensity: 2.0,
position: [-74.05, 40.7, 8000]
});
const lightingEffect = new deck.LightingEffect({ ambientLight, pointLight });
const material = {
ambient: 0.1,
diffuse: 0.6,
shininess: 32,
specularColor: [60, 64, 70]
};
const theme = {
buildingColor: [74, 80, 87],
trailColor0: [253, 128, 93],
trailColor1: [23, 184, 190],
material,
effects: [lightingEffect]
};
const LOOP_LENGTH = 1800;
const ANIMATION_SPEED = 0.4;
async function initialize() {
deck.carto.setDefaultCredentials({
username: 'public',
apiKey: 'default_public',
});
// Fetch Data from CARTO
// Notice that you can use any Deck.gl layer with CARTO datasets getting GeoJSON data from CARTO's API. This method is recommended for complex layers with datasets below 50Mb
const tripsUrl = 'https://public.carto.com/api/v2/sql?q=SELECT the_geom, vendor, timestamps FROM sf_trips_v7&format=geojson';
const geojsonTripsData = await fetch(tripsUrl).then(response => response.json());
// TripsLayer needs data in the following format
const layerData = geojsonTripsData.features.map(f => ({
vendor: f.properties.vendor,
timestamps: f.properties.timestamps,
path: f.geometry.coordinates[0]
}));
const staticLayers = [
// This is only needed when using shadow effects
new deck.PolygonLayer({
id: 'ground-layer',
data: [[[-74.0, 40.7], [-74.02, 40.7], [-74.02, 40.72], [-74.0, 40.72]]],
getPolygon: f => f,
stroked: false,
getFillColor: [0, 0, 0, 0]
}),
new deck.carto.CartoSQLLayer({
id: 'buildings-layer',
data: 'SELECT the_geom_webmercator, height FROM sf_buildings',
extruded: true,
wireframe: true,
opacity: 0.5,
getElevation: f => f.properties.height,
getFillColor: [74, 80, 87],
material: theme.material
})
];
// Create Deck.GL map
const deckgl = new deck.DeckGL({
container: 'map',
mapStyle: 'https://basemaps.cartocdn.com/gl/dark-matter-nolabels-gl-style/style.json',
initialViewState: {
longitude: -74,
latitude: 40.73,
zoom: 12,
pitch: 45,
bearing: 0
},
controller: true,
layers: staticLayers,
effects: theme.effects
});
let time = 0;
function animate() {
time = (time + ANIMATION_SPEED) % LOOP_LENGTH;
window.requestAnimationFrame(animate);
}
setInterval(() => {
deckgl.setProps({
layers: [
...staticLayers,
new deck.TripsLayer({
id: 'trips-layer',
data: layerData,
getPath: d => d.path,
getTimestamps: d => d.timestamps,
getColor: d => (d.vendor === 0 ? theme.trailColor0 : theme.trailColor1),
opacity: 0.3,
widthMinPixels: 2,
rounded: true,
trailLength: 180,
currentTime: time,
shadowEnabled: false
})
]
});
}, 50);
window.requestAnimationFrame(animate);
}
initialize();
I used angular-openlayers-directive from this link: https://github.com/tombatossals/angular-openlayers-directive
I want to achieve this effect: http://tombatossals.github.io/angular-openlayers-directive/examples/059-layer-clustering.html
Unfortunately, only a map with no round points is displayed in my application. My code is the same as in the github example.
My code:
function createPointStyle(color, text) {
var options = {
image: new ol.style.Circle({
radius: 10,
fill: new ol.style.Fill({
color: color,
opacity: 0.6
}),
stroke: new ol.style.Stroke({
color: 'white',
opacity: 0.4
})
})
};
if (text) {
options.text = new ol.style.Text({
text: text,
fill: new ol.style.Fill({
color: 'white'
})
});
}
return new ol.style.Style(options);
}
function createIconStyle() {
return new ol.style.Style({
image: new ol.style.Icon({
anchor: [0.5, 1],
anchorXUnits: 'fraction',
anchorYUnits: 'fraction',
opacity: 0.90,
src: 'resource/img/mapin.png'
})
});
}
function getStyle(feature) {
// Take car we use clustering, thus possibly have multiple features in one
var features = feature.get('features');
var style = null;
// Icon base style ?
if ($scope.icon) {
style = createIconStyle();
}
// Circle + txt base style
// Add number of clustered item in this case
else if (features && features.length > 1) {
style = createPointStyle('blue', features.length.toFixed());
} else {
style = createPointStyle('blue');
}
return [style];
}
angular.extend($scope, {
center: {
lat: 43.88,
lon: 7.57,
zoom: 2
},
clusters: {
clustering: true,
clusteringDistance: 40,
source: {
type: 'KML',
projection: 'EPSG:3857',
url: 'resource/kml/earthquakes.kml'
},
style: getStyle
},
// Default to circles
icon: false
});
Someone knows why it does not work?
I'm trying to pull some json data from Geoserver utilizing ESRI's Arcgis Javascript 4.4 API. All of the components log to the console, but the view.graphics.add() throws this error:
Uncaught TypeError: b.spatialReference.equals is not a function
at e._projectGeometry (MapView.js:505)
at e.doRender (MapView.js:503)
at e.b.processRender (MapView.js:293)
at b.renderChild (MapView.js:500)
at b.e.renderChildren (MapView.js:290)
at b.e.doRender (MapView.js:286)
at b.processRender (MapView.js:293)
at n.renderChild (MapView.js:427)
at n.e.renderChildren (MapView.js:290)
at n.e.doRender (MapView.js:286)
I'm trying to understand why what I am attempting is not working as expected, and any help would be appreciated. Code is below:
function fetchJson(url) {
return xhr.get({
url: url,
handleAs:"json",
})
}
var map = new Map({
basemap: "dark-gray"
});
var view = new MapView({
container: "view",
map: map,
zoom: 11,
center: [-84.34, 33.93],
padding: {
left: 320
}
});
view.then(function () {
fetchJson(samplejsonlink)
.then(function (data) {
console.log(data.features[0].geometry.coordinates)
var polyline = {
type: "polyline",
paths: data.features[0].geometry.coordinates,
spatialReference: {wkid : 4326}
}
console.log(polyline);
var polylineSymbol = {
type: "simple-line",
color: [226, 119, 40],
width: 4
};
console.log(polylineSymbol);
var polylineAtt = {
Name: "ExampleName",
};
console.log(polylineAtt)
var polylineGraphic = new Graphic({
geometry: polyline,
symbol: polylineSymbol,
attributes: polylineAtt
})
console.log(polylineGraphic);
view.graphics.add(polylineGraphic);
})
})
Your codes are working when I use this coordinates as paths. Maybe your coordinates from data.features[0].geometry.coordinates is not match the Polyline coordinates format.
view.then(function () {
var polyline = {
type: "polyline",
paths: [
[-111.30, 52.68],
[-98, 49.5],
[-93.94, 29.89]
],
spatialReference: { wkid: 4326 }
}
console.log(polyline);
var polylineSymbol = {
type: "simple-line",
color: [226, 119, 40],
width: 4
};
console.log(polylineSymbol);
var polylineAtt = {
Name: "ExampleName",
};
console.log(polylineAtt)
var polylineGraphic = new Graphic({
geometry: polyline,
symbol: polylineSymbol,
attributes: polylineAtt
})
console.log(polylineGraphic);
view.graphics.add(polylineGraphic);
});