feature convert to geoJSON string failed - openlayers-3

I got a geometry from FeatureOverlay,and create a feature from this geometry, when I setId and setGeometryName to the feature ,I will be failed to writeFeature , is this a bug ?
var poly = featureOverlay.getFeatures().item(0);
if (poly != null) {
var feature = new ol.Feature({
geometry: poly
});
feature.setId('bd355df3fd916d30');
feature.setGeometryName('test');
var extent = [0, 0, 749, 638];
var projection = new ol.proj.Projection({
code: 'xkcd-image',
units: 'pixels',
extent: extent
});
var geoJSON = new ol.format.GeoJSON({
defaultDataProjection: projection
});
//this will be success
var geoJSONText = geoJSON.writeFeature(poly, {
featureProjection: projection,
dataProjection: projection
});
//this will be failed
var geoJSONText = geoJSON.writeFeature(feature, {
featureProjection: projection,
dataProjection: projection
});
}
Uncaught TypeError: Converting circular structure to JSON
l.qd # openlayers?v=YGwTOEaGf-vdYCn0EwOqEIY8JyARvCDFTRAySewZwRI1:501
stopInteraction # testedit?id=8b0d3745a6c1b46b:447
onclick # testedit?id=8b0d3745a6c1b46b:230

It's my problem.
feature.setId('bd355df3fd916d30');
feature.setGeometryName('test');
modified to this will be fixed :
feature.setId('bd355df3fd916d30');
feature.setProperties(['test']);

Related

Draw a circle again after vector export

After draw a circle in my map, I exported it with:
getAsJson : function() {
var geojson = new ol.format.GeoJSON();
var features = this.vectorSource.getFeatures();
var jsonData = geojson.writeFeatures( features,{
featureProjection: ol.proj.get('EPSG:3857'),
dataProjection: ol.proj.get('EPSG:4326')
});
return jsonData;
}
and the result was:
{"type":"FeatureCollection","features":[
{"type":"Feature","geometry":{
"type":"GeometryCollection","geometries":[]
},"properties":{
"circleCenter":[-4805776.093508227,-2600749.7153150304],"circleRadius":6658.801529937424
}
}]}
This is how I take the circle center and radius:
var draw = new ol.interaction.Draw({
source: vectorSource,
type: value, // Can be Circle,Point,Line,Polygon
// No Geometry Function when type is 'Circle' (omited code to simplify)
geometryFunction: geometryFunction,
maxPoints: maxPoints
});
draw.on('drawend', function( evt ){
var geometry = evt.feature.getGeometry();
// Check the type before try to get this! (omited code to simplify)
var center = geometry.getCenter();
var radius = geometry.getRadius();
evt.feature.set('circleCenter', center );
evt.feature.set('circleRadius', radius );
});
map.addInteraction( draw );
Now I'm trying to use this JSON to draw the same circle again, but it have no geometry and this is not working (work for all other geometries like point, polygong and line so the problem is it not the code):
var features = new ol.format.GeoJSON().readFeatures( jsonData, {
featureProjection: 'EPSG:3857'
});
var vectorSource = new ol.source.Vector({
});
var vectorLayer = new ol.layer.Vector({
source: vectorSource,
style : customStyleFunction
});
map.addLayer( vectorLayer );
Just a note: I can see now the projection of center and radius was not changed. Must work on this too...
GeoJSON does not support Circle Geometry. So ol.format.GeoJSON() format doesnot convert JSON to ol.Feature object. So write a custom method which consumes the JSON data and creates a Circle geometry
var featuresJson = geoJson.features;
for ( var i=0; i<featuresJson.length; i++ ) {
var radius = featuresJson[i].properties.circleRadius;
var center = featuresJson[i].properties.circleCenter;
var feature = new ol.Feature(new ol.geom.Circle(center,radius);
vectorSource.addFeature(feature);
}
I think this can help me somehow... will see.
map.getViewport().addEventListener("dblclick", function(e) {
var coordinate = map.getEventCoordinate(e);
vectorSource.addFeature(new ol.Feature(new ol.geom.Circle(coordinate, dist)));
});

URL parameters for Openlayers 3 to zoom to location?

I have an OL3 web application and I am wondering if it is possible to include URL parameters (such as coordinate values) for which the application can parse and open up at a specific location?
For example http://mywebsiteaddress?x=longitudevalue&y=latitudevalue
Is this something that can be done using OL3?
Sure, see: http://openlayers.org/en/latest/examples/permalink.html for an example (uses an anchor instead of url parameters but the idea is the same).
I did not like the openlayers permalink example because it uses map units and not well-known latitudes and longitudes. Sp I wrote my own code to hand over latlon coordinates, zoom and set a marker to it:
function getURLParameter(name) {
return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search) || [null, ''])[1].replace(/\+/g, '%20')) || null;
}
var mzoom=12;
var mlat = Number(getURLParameter('mlat'));
var mlon = Number(getURLParameter('mlon'));
var mzoom = Number(getURLParameter('zoom'));
var marker = 1
if (mlat == 0 || mlon == 0) {
mlat = 51.5; mlon = 7.0; mzoom=12; marker=0 //Default location
}
if (mzoom == 0 ) { mzoom=12 //Default zoom
}
var container = document.getElementById('popup');
var content = document.getElementById('popup-content');
var closer = document.getElementById('popup-closer');
closer.onclick = function() {
container.style.display = 'none';
closer.blur();
return false;
};
var overlayPopup = new ol.Overlay({
element: container
});
var expandedAttribution = new ol.control.Attribution({
collapsible: false
});
var map = new ol.Map({
controls: ol.control.defaults({attribution:false}).extend([
expandedAttribution
]),
target: document.getElementById('map'),
renderer: 'canvas',
overlays: [overlayPopup],
layers: layersList,
view: new ol.View({
center: ol.proj.fromLonLat([mlon, mlat]),
zoom: mzoom,
maxZoom: 18, minZoom: 8
})
});
if (marker == 1) {
var vectorLayer = new ol.layer.Vector({
source:new ol.source.Vector({
features: [new ol.Feature({
geometry: new ol.geom.Point(ol.proj.transform([parseFloat(mlon), parseFloat(mlat)], 'EPSG:4326', 'EPSG:3857')),
})]
}),
style: new ol.style.Style({
image: new ol.style.Icon({
anchor: [0.5, 0.5],
anchorXUnits: "fraction",
anchorYUnits: "fraction",
src: "marker.svg"
})
})
});
map.addLayer(vectorLayer);
}
I used the output of the qgis2web plugin and modified the file qgis2web.js as above.

cannot add features to WFS layer

I try to load some features from Geoserver to a vector layer in Openlayers 3.9.0.
var url = 'http://localhost:5550/geoserver/mymap/wfs?service=WFS&'+'version=1.0.0&request=GetFeature&typeName=mymap:layer&'+'outputFormat=application/json&maxFeatures=50';
var projection = ol.proj.get('EPSG:3857');
var extent = [2297128.5, 4618333, 2459120.25, 4763120];
var amir = new ol.source.Vector({
format: new ol.format.GeoJSON(),
loader: function (extent) {
$.ajax(url, {type: 'GET'})
.done(loadFeatures)
.fail(function () {alert("error");});
},
strategy: ol.loadingstrategy.bbox
});
function loadFeatures(response) {
formatWFS = new ol.format.WFS();
var features = formatWFS.readFeatures(response);
amir.addFeatures(features);
//-----------OR---------------------
var features = amir.readFeatures(response);
amir.addFeatures(features);
}
var fill = new ol.style.Fill({
color: 'rgba(0,0,0,0.2)'
});
var stroke = new ol.style.Stroke({
color: 'rgba(0,0,0,0.4)'
});
var circle = new ol.style.Circle({
radius: 6,
fill: fill,
stroke: stroke
});
jake = new ol.layer.Vector({
source: amir,
style: new ol.style.Style({
fill: fill,
stroke: stroke,
image: circle
})
});
In loadFeatures function if I use
formatWFS = new ol.format.WFS();
var features = formatWFS.readFeatures(response);
amir.addFeatures(features);
I get Uncaught AssertionError: Failure: Unknown source type pointing to a openlayers line that throws errors and to this line of my codevar features = formatWFS.readFeatures(response);.
If I use
var features = amir.readFeatures(response);
amir.addFeatures(features);
I get Uncaught TypeError: sourceVector.readFeatures is not a function pointing to var features = amir.readFeatures(response); .
The request to the WFS looks ok, with OK 200 status. If I grab the request's URL sended to Geoserver and open it in a new tab I get raw GeoJSON like {"type":"FeatureCollection","totalFeatures":422,"features":[{"type":"Feature","id":"layer.709","geometry":{"type":"Point","coordinates":[2391735.8907621,4695330.8039257005]},"geometry_name":"l_geom","properties":{"l_name":"Leeron"}},....//next feature
So its a FeatureCollection not just an array. Not that I know how to handle this
I dont get why to set a ol.format.WFS and not just read/add features. I dont know how to debug and add the features to my layer
You are instructing GeoServer to use GeoJSON as output format, so you'll need to use the GeoJSON format in OpenLayers to parse the features. You should be able to simplify your source configuration to something like
var url = 'http://localhost:5550/geoserver/mymap/wfs?service=WFS&' +
'version=1.0.0&request=GetFeature&typeName=mymap:layer&' +
'outputFormat=application/json&maxFeatures=50';
var amir = new ol.source.Vector({
format: new ol.format.GeoJSON(),
url: function(extent, projection) {
return url + '&bbox=' + extent.join(',') +
'&srsName=' + projection.getCode();
},
strategy: ol.loadingstrategy.bbox
});

How to transform MapTile image to to view

I've created a tile set of an image using MapTiler. MapTiler generates a OL 2 script that centers the tiled image in the viewing window with the following code:
var map, layer;
var mapBounds = new OpenLayers.Bounds(0.000000, -9350.000000, 14450.000000, 0.000000);
var mapMinZoom = 0;
var mapMaxZoom = 6;
var mapMaxResolution = 1.000000;
var gridBounds = new OpenLayers.Bounds(0.000000, -9350.000000, 14450.000000, 0.000000);
function init() {
var options = {
controls: [],
maxExtent : gridBounds,
minResolution: mapMaxResolution,
numZoomLevels: mapMaxZoom+1
};
map = new OpenLayers.Map('map', options);
layer = new OpenLayers.Layer.XYZ( "MapTiler layer", "${z}/${x}/${y}.png", {
transitionEffect: 'resize',
tileSize: new OpenLayers.Size(256, 256),
tileOrigin: new OpenLayers.LonLat(gridBounds.left, gridBounds.top)
});
map.addLayer(layer);
map.zoomToExtent(mapBounds);
I want to use OL3 to display the tiled map but do not know how to implement equivalent OL3 methods to achieve this. Using the following script I can display the tiled image but I cannot figure out how to center the tiles to in the view.
map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM({
url: map_path + '{z}/{x}/{y}.png'
})
})
],
view: new ol.View({
center: [0, 0],
zoom: 2
})
});
I've inspected the map extent which turns out to be:
-20037508.342789244,-20037508.342789244,20037508.342789244,20037508.342789244
My tiled image extent is given in the OL2 code, but I don't known how to use this information in OL3. I think it might have something to do with a transformation or fitExtent but without further direction, it seems I'm just guessing at what to do.
You will have to create a pixel projection for this to work properly. Then you can use fit (replacement for the former fitExtent), as you already suspected, to zoom to the full extent of the image.
The whole OpenLayers 2 code translated to OpenLayers 3 would look like this:
var mapBounds = [0.000000, -9350.000000, 14450.000000, 0.000000];
var mapMaxZoom = 6;
var gridBounds = [0.000000, -9350.000000, 14450.000000, 0.000000];
var projection = new ol.proj.Projection({
code: 'pixels',
units: 'pixels',
extent: gridBounds
});
var map = new ol.Map({
target: 'map',
view: new ol.View({
extent: mapBounds,
projection: projection
})
});
var layer = new ol.layer.Tile({
source: new ol.source.XYZ({
url: '{z}/{x}/{y}.png',
projection: projection,
maxZoom: mapMaxZoom
})
});
map.addLayer(layer);
map.getView().fit(mapBounds, map.getSize());

get point from ol.geom.MultiPolygon

I am trying to add a marker at the center or anywhere of my feature (ol.geom.MultiPolygon) and i cannot get the point (x,y) for it !!!
var coordinates= feature.getGeometry().getCoordinates();
/** marker data */
var iconFeature = new ol.Feature({
geometry: new ol.geom.Point([coordinates[0][0][0], coordinates[0][0][1]]), /** if i do this it works: geometry: new ol.geom.Point([8420.360601958382, 12492.263314383097]), */
name: 'Null Island',
population: 4000,
rainfall: 500
});
Thank;s again !
Try:
feature.getGeometry().getInteriorPoints().getPoint(0)
i've found it:
var geo = feature.getGeometry();
var poly = geo.getPolygons().reduce(function(left, right) {
return left.getArea() > right.getArea() ? left : right;
});
var point = poly.getInteriorPoint().getCoordinates();
from the book: OpenLayers 3 : Beginner's Guide

Resources