My intention is to load GeoJSON data and display it on the map. Coordinates of the features specified in GeoJSON are normal lon/lat. For some reason openlayers is rendering them using the projection used by the map and without converting them.
// Underlying sat layer.
var world = new ol.layer.Tile({
source: new ol.source.MapQuest({layer: 'sat'})
});
// GeoJSON data.
var geojsonObject = {
'type': 'FeatureCollection',
'features': [
{
'type': 'Feature',
'geometry': {
'coordinates': [ 50.07539747, 19.76809501 ],
'type': 'Point'
},
}
]
};
var vectorSource = new ol.source.Vector({
features: (new ol.format.GeoJSON()).readFeatures(geojsonObject)
});
var vectorLayer = new ol.layer.Vector({
source: vectorSource
});
// Map.
map = new ol.Map({
target: 'map',
layers: [world, vectorLayer],
view: new ol.View({
center: ol.proj.transform([37.41, 8.82], 'EPSG:4326', 'EPSG:3857'),
zoom: 2
})
});
The point is being rendered in the middle of the map. By placing multiple points I determined that they are in fact moved relative to each other but by a small amount which leads me to believe the for some reason the map uses a different coordinate system for them.
What I tried:
Setting crs in GeoJSON, providing defaultDataProjection option to format. I use openlayers v3.8.2 and all solutions I found online are very outdated (and as far as I can see the API used to be way better, maybe I should just switch to an old version).
Just use a featureProjection to read features like:
var vectorSource = new ol.source.Vector({
features: new ol.format.GeoJSON().readFeatures(geojsonObject,{
featureProjection: 'EPSG:3857'
})
});
UPDATE:
When reading features from url is even easier, OL makes the conversion internally for you:
var geojson_layer = new ol.layer.Vector({
source: new ol.source.Vector({
url: 'file.geojson',
format: new ol.format.GeoJSON()
})
});
Demo - http://plnkr.co/edit/GvdVNE?p=preview
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' })
});
After reading a very good tutorial on how to edit WFS with OpenLayers, I've tried replicating it but with my own WFS layer from Geoserver. Need some Javascript help finding what's wrong with it.
I managed to load the WFS and my basemap successfully and managed to get the buttons to show up. The buttons appear correctly like in the working example from that page but, for some reason the geometry data isn't being saved. Every time a user draws something, a new id is created on the table but its associated geometry column is left empty
The bit for posting is:
var formatWFS = new ol.format.WFS();
var formatGML = new ol.format.GML({
featureNS: 'http://geoserver.org/bftchamber',
featureType: 'bft',
srsName: 'EPSG:27700'
});
var transactWFS = function(p,f) {
switch(p) {
case 'insert':
node = formatWFS.writeTransaction([f],null,null,formatGML);
break;
case 'update':
node = formatWFS.writeTransaction(null,[f],null,formatGML);
break;
case 'delete':
node = formatWFS.writeTransaction(null,null,[f],formatGML);
break;
}
s = new XMLSerializer();
str = s.serializeToString(node);
$.ajax('http://localhost:8080/geoserver/wfs',{
type: 'POST',
dataType: 'xml',
processData: false,
contentType: 'text/xml',
data: str
}).done();
}
Fiddle with the whole code (apologies if it looks messy, most of it comes from the working example 2 )
https://jsfiddle.net/Luffydude/ex06jr1e/6/
The app looks like this:
Also even though my WFS appears correctly along the river Thames when I load it in QGIS, in my app it appears somewhere else in the ocean even though I specified EPSG 27700 (though this is just a minor annoyance at the moment).
My main problem now is how to make the edit buttons save user edits to the WFS layer?
I haven't really looked at OpenLayers in anger for a while and I kind of let slip updating my working examples. I just put together a new JSFiddle with simple WFS-T insert for polygons.
I use Geoserver 2.8 in production (2.9 in dev and testing).
Database backend is PostGIS 2.1 in production (2.2 dev).
The fiddle uses OpenLayers 3.16.
A few notes to my setup. I tend to have all geometries in EPSG:3857 and I do not specify the SRS in PostGIS. Haters gonna hate but I simply set my geometry column to geometry. This way I can get lines, points and polygons in the same table. I cannot see the mixed geometry in QGIS but this is a simple test setup. It's important that the geometry field is called geometry. It's probably possible but I could not make this work with the field being called the_geom or geom. In that case a record is inserted but the geometry field is empty as described in the post. I believe this is the problem.
CREATE TABLE wfs_geom
(
id bigint NOT NULL,
geometry geometry,
CONSTRAINT wfs_geom_pkey PRIMARY KEY (id)
)
WITH (
OIDS=FALSE
);
ALTER TABLE wfs_geom
OWNER TO geoserver;
Here is the code bit from the jsfiddle.
var formatWFS = new ol.format.WFS();
var formatGML = new ol.format.GML({
featureNS: 'https://geolytix.net/wfs',
featureType: 'wfs_geom',
srsName: 'EPSG:3857'
});
var s = new XMLSerializer();
var sourceWFS = new ol.source.Vector({
loader: function (extent) {
$.ajax('https://maps.geolytix.net/geoserver/geolytix.wfs/wfs', {
type: 'GET',
data: {
service: 'WFS',
version: '1.1.0',
request: 'GetFeature',
typename: 'wfs_geom',
srsname: 'EPSG:3857',
bbox: extent.join(',') + ',EPSG:3857'
}
}).done(function (response) {
sourceWFS.addFeatures(formatWFS.readFeatures(response));
});
},
strategy: ol.loadingstrategy.bbox,
projection: 'EPSG:3857'
});
var layerWFS = new ol.layer.Vector({
source: sourceWFS
});
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM({
url: 'https://cartodb-basemaps-{a-d}.global.ssl.fastly.net/light_nolabels/{z}/{x}/{y}.png',
opaque: false,
attributions: []
})
}),
layerWFS
],
view: new ol.View({
center: ol.proj.fromLonLat([-0.1, 51.50]),
zoom: 13
})
});
var interaction = new ol.interaction.Draw({
type: 'Polygon',
source: layerWFS.getSource()
});
map.addInteraction(interaction);
interaction.on('drawend', function (e) {
$.ajax('https://maps.geolytix.net/geoserver/geolytix.wfs/wfs', {
type: 'POST',
dataType: 'xml',
contentType: 'text/xml',
data: s.serializeToString(formatWFS.writeTransaction([e.feature], null, null, formatGML))
}).done();
});
I have a set of places saved from GoogleEarth as a KML file. I am trying to get the same locations to display on a simple OpenLayer2 map using the following Js code :
var map;
function init() {
var bounds = new OpenLayers.Bounds();
bounds.extend( new OpenLayers.LonLat(0.2, 52.3).transform('EPSG:4326', 'EPSG:3857'));
bounds.extend( new OpenLayers.LonLat(1.9, 51.5).transform('EPSG:4326', 'EPSG:3857'));
map = new OpenLayers.Map('map', {
projection: 'EPSG:3857',
layers: [
new OpenLayers.Layer.Google(
"Google Streets", // the default
{ numZoomLevels: null, minZoomLevel: 1, maxZoomLevel: 16 }
),
],
controls: [ new OpenLayers.Control.Navigation(),
new OpenLayers.Control.PanZoomBar(),
],
center: new OpenLayers.LonLat( 1.0, 52.1)
// Google.v3 uses web mercator as projection, so we have to
// transform our coordinates
.transform('EPSG:4326', 'EPSG:3857'),
restrictedExtent: bounds,
zoom: 9,
});
var layer = new OpenLayers.Layer.Vector("KML", {
animationEnabled: true,
projection: map.displayProjection,
strategies: [new OpenLayers.Strategy.Fixed()],
protocol: new OpenLayers.Protocol.HTTP({
url: "/static/OL3Example/kml/locations.kml",
format: new OpenLayers.Format.KML({
extractStyles: true,
extractAttributes: true
})
})
}) ;
map.addLayer(layer);
map.addControl(new OpenLayers.Control.LayerSwitcher());
}
The Restricted Extends make the map display just SUffolk, Uk, and all but 4 of the locations are in Suffolk (so should be on the map). Looking at the KML data I can confirm that the locations in the KML are correct Decimal Lon/Lat.
When I remove the Restricted Extent from the map - I can pan around the world, and I can then see a cluster of Icons at 0 Lon, 0 Lat.
I have looked at the documentation - and a number of stackoverflow related questions : for instance OpenLayers not displaying kml layer, but none have answered the question.
I have used Firebug to investigate the map object and it's layers - and I can confirm that the layer is visible - and is drawn, and there are no unrenderedFeatures on the layer - suggesting that the layer is loading fine - and it is a projection thing - though what is confusing.
I tried to use the example from openlayers 3 xyz example to create a webmap from this service http://maps.gov.bc.ca/arcgis/rest/services/Province/web_mercator_cache/MapServer but the map rendered is not complete. It is better with the wrapX: false but the issue is not resolved. It also fails to display correctly using Leaflet.
Here is JS fiddle with the OL3 code.
http://jsfiddle.net/7ettuy1c/
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.XYZ({
url: "http://maps.gov.bc.ca/arcgis/rest/services/Province/web_mercator_cache/MapServer" +
'/tile/{z}/{y}/{x}'
})
})
],
view: new ol.View({
center: ol.proj.fromLonLat([-118, 51.5]),
zoom: 1
})
});