Openlayers 3 Select two features from two different layers at same position - openlayers-3

I have a layer with markers and one layer with polylines. The markers are at the end of the polylines. I like to drag any marker synchronous with the end (overapping) of the polyline.
var features = new ol.Collection();
var featureOverlay = new ol.layer.Vector({source: new ol.source.Vector({features: features}),style:styles});
featureOverlay.setMap(map);
var markers = new ol.Collection();
var markerOverlay = new ol.layer.Vector({source: new ol.source.Vector({features: markers}),style:styles});
markerOverlay.setMap(map);
var modify = new ol.interaction.Modify({features: features});
map.addInteraction(modify);
var modifyn = new ol.interaction.Modify({features: markers});
map.addInteraction(modifyn);
It's not working synchronous. I have to drag the end of the polyline and the marker separate.
How can I drag both at the same time?
Thanks for helping!
Andreas.

I got it!
I collect all features at the mouse position in realtime and save them in a collection. This collection is the feature in modify.
Cheers!
var allFeaturesAtPixel = new ol.Collection();
var modify = new ol.interaction.Modify({features: allFeaturesAtPixel});
map.addInteraction(modify);
map.on('pointermove', function (evt)
{
allFeaturesAtPixel.clear();
map.forEachFeatureAtPixel(evt.pixel, function (feature) {allFeaturesAtPixel.push(feature);});
});

Related

Draw LineString using webgl

How can I draw a LineString using WebGL over Openlayers 3 map? Please guide.
I have gone through below links which didn't help:
http://openlayers.org/en/master/examples/icon-sprite-webgl.html
http://openlayers.org/en/master/examples/symbol-atlas-webgl.html
You can easily add the Draw interaction to the map, as it is shown in some Openlayers 3 examples:
https://openlayers.org/en/latest/examples/draw-features.html
https://openlayers.org/en/latest/examples/draw-and-modify-features.html
https://openlayers.org/en/latest/examples/draw-freehand.html
You only have to create a Vector Layer and Draw Interaction with a shared vector source, and add them to the map:
var drawSource = new ol.source.Vector({wrapX: false});
var drawVector = new ol.layer.Vector({
source: drawSource
});
var draw = new ol.interaction.Draw({
source: drawSource,
type: 'LineString'
});
drawVector.setMap(map);
map.addInteraction(draw);
You will find an example in this jsfiddle

OL3: Clustering Vector Features when can't determine Feature type

I have to load some Features in a Vector layer and have a style function.
var features = new ol.format.GeoJSON().readFeatures( geojsonStr, {
featureProjection: 'EPSG:3857'
});
var vectorSource = new ol.source.Vector({
features: features,
});
/*
var clusterSource = new ol.source.Cluster({
distance: 15,
source: vectorSource
});
*/
var customStyleFunction = function( feature, resolution ) {
....
}
var vectorLayer = new ol.layer.Vector({
//source: clusterSource,
source: vectorSource,
style : customStyleFunction
});
map.addLayer( vectorLayer );
I don't know what kind of geometry I will get in geojsonStr. The problem is: When my collection is of type "Point" I can cluster it, but with any other types I can't see the Layer... How can I cluster Points and ignore Polygons and Lines? or let OL3 be clever enough to decide?
EDIT: I've read https://github.com/openlayers/openlayers/pull/4917
I would recommend you to create 2 different layers: One for clustering and a another one for a common vector layer.
To solve your problem, you can loop through the features and check the geometry type of each, and add it to an already existing source with the addFeature method:
for (var i = 0; i < geojsonFeatures.length; i++) {
if (geojsonFeatures[i].getGeometry().getType() === 'Point') {
clusterSource.addFeature(geojsonFeatures[i]);
} else {
vectorSource.addFeature(geojsonFeatures[i]);
}
}
I have created a jsfiddle which gets a couple of features from a GeoJSON object and add them to different sources depending on the geometry type. If you want to see more points in the cluster souce to make sure that it is working properly, you can use the commented lines as well.

Customize style of a vector layer ol3

I use a geojson file to build the layer added to a map. What I want is to customize style of the layer's polygons in order to have hatched polygons such as we can do that with mapserver symbols. Is it possible to do this with ol3? I tried to create an image and use it but it only works for point geometry. Thank you for your help.
Regards.
Fill patterns for polygons are not (yet) supported in OpenLayers 3, see also https://github.com/openlayers/ol3/issues/2208
It is possible by now. The ol.style.Style object accepts a CanvasRenderingContext2D instance, where you can apply an image pattern to your polygons.
Example Code Snippet
var geojsonObject = 'someGeoJSON'
var source = new ol.source.Vector({
features: (new ol.format.GeoJSON()).readFeatures(geojsonObject)
});
var layer = new ol.layer.Vector({
source: source
});
var cnv = document.createElement('canvas');
var ctx = cnv.getContext('2d');
var img = new Image();
img.src = 'https://mdn.mozillademos.org/files/222/Canvas_createpattern.png';
img.onload = function() {
var pattern = ctx.createPattern(img, 'repeat');
layer.setStyle(new ol.style.Style({
fill: new ol.style.Fill({
color: pattern
})
}));
};
A full example can be seen here: jsfiddle

Is it possible to add a icon symbol to a polygon

I am currently working on a openlayers 3 project and for better visulaizing i need to show both. The Polygon shape(attribute based color) which works great and an icon on the polygon position. I know that the polygon contains multiple coordinates and so its not so easy to define a position for the icon. Now i have some kind of workaround that creates an seperate overlay with the interior Points of the polygon to mark the position of the icons. To make the project more simple i want to combine these two styling. Does anyone know if its possible?
Kind Regards
I presumes that you use a ol.source.serversource for your data.
The trick is to test all your features for being a polygon. If it is, you create a point feature you add to your source.
First create the source and the layer:
var avlVectorSource = new ol.source.ServerVector({
format: new ol.format.GeoJSON(),
loader: function(extent, resolution, projection) {
myLoader(resolution);
}
});
var myLayer = new ol.layer.Vector({
source: myVectorSource,
style: myStyleFunction
});
The layer has a style function to set the right icon.
The main thing is the loader:
var myLoader = function(resolution){
$.ajax({
url: "http://myJsonSource.com",
timeout: 1000,
success: function(response) {
var layerJSONString = $.parseJSON(response);
var newFeatures = [];
j= 0;
var size=layerJSONString.features.length;
for (i = 0; i < size; i++){
var feat = layerJSONString.features[i];
var geom = feat.geometry;
var type = geom.type;
if(type == "Polygon")
{
var poly = new ol.geom.Polygon(geom.coordinates);
var extent = poly.getExtent();
var coord = [];
coord[0] = (extent[2]-extent[0])/2 + extent[0];
coord[1] = (extent[3]-extent[1])/2 + extent[1];
var point = new ol.geom.Point(coord);
newFeatures[j++] = new ol.Feature({
geometry : point,
StyleName : feat.properties.StyleName
});
}
}
avlVectorSource.addFeatures(myVectorSource.readFeatures(response));
avlVectorSource.addFeatures(newFeatures);
},
error: myLoadError
});
}
};
The documentation says that ol.geom.Polygon has a method called getInteriorPoint(). It has but I can get it to work. So I calculate the center point of the extent of the polygon.
I use "StyleName" to set the right icon in my style function.

Adding markers from a SQL db to OSM

I'm new to OpenStreetMap and I've been browsing the wiki and the net and I can't seem to find a tutorial anywhere but I've seen examples on the net.
Basically I want to generate my own OpenStreetmap and plot markers taking the latitude and longitude from a MySQL database and plotting them on my map. When the user clicks on a mark I'd like to have a popup. Basically I want this http://code.google.com/apis/maps/articles/phpsqlajax.html but for OpenStreetMap and not Google-maps.
Looks like they are using openLayer for map rendering. Here are some examples and api docs.
http://openlayers.org/dev/examples/
http://trac.osgeo.org/openlayers/wiki/Documentation
To accomplish this, you need to figure out the javascript for presenting markers on a "slippy map" interface.
OpenLayers is the name of a popular javascript library. It's free and open source. It's used to display a slippy map on the OpenStreetMap.org homepage, and various other sites around the web. It's often confused with OpenStreetMap itself, or people mistakenly get the impression that you must use OpenLayers if you want to embed OpenStreetMap maps on your site. Not true. There's lots of alternative javascript libraries for displaying a slippy map
...including the google maps API! You can set up a google maps display, but show OpenStreetMap "tile" images instead of google tiles. See Google Maps Example. This has the advantage of code compatibility, meaning you could follow through google maps tutorial you've linked there, but then drop in a cheeky bit of code to specify OpenStreetMap as the tile layer.
This has the disadvantage of showing an big evil google logo, and requiring an even more evil google maps API key, so all the cool kids are using OpenLayers.
There's various examples of using OpenLayers on the OpenStreetMap wiki. The "OpenLayers Dynamic POI" example shows the use of database for markers (although that example is a bit convoluted). Another popups example on my site
Hope that helps
// Sample code by August Li
// Modified by Tom Moore to work with SQL
var zoom, center, currentPopup, map, lyrMarkers;
var popupClass = OpenLayers.Class(OpenLayers.Popup.FramedCloud, {
"autoSize": true,
"minSize": new OpenLayers.Size(300, 50),
"maxSize": new OpenLayers.Size(500, 300),
"keepInMap": true
});
var bounds = new OpenLayers.Bounds();
var lat=36.287179515680556;
var lon=-96.69170379638672;
var zoom=11;
var lonLat = new OpenLayers.LonLat(lon, lat).transform(
new OpenLayers.Projection("EPSG:4326"), new OpenLayers.Projection("EPSG:900913"));
// begin addMarker function
// info1 I was going to use to add a tooltip. Haven't figured out
// how to do that in OpenLayers yet :( Someone who knows share that with us
// iconurl is the url to the png file that you want to use for the icon.
// you MUST call addMarker at least once to initialize the map
function addMarker(lat, lng, info, info1, iconurl) {
// First check to see if the map has been initialized. If not, do that now ...
if (map == null) {
var options = {
projection: new OpenLayers.Projection("EPSG:900913"),
displayProjection: new OpenLayers.Projection("EPSG:4326"),
units: "m",
numZoomLevels: 19,
maxResolution: 156543.0339,
maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34)
};
map = new OpenLayers.Map("map", options);
map.addControl(new OpenLayers.Control.PanZoomBar());
var lyrOsm = new OpenLayers.Layer.OSM();
map.addLayer(lyrOsm);
lyrMarkers = new OpenLayers.Layer.Markers("Markers");
map.addLayer(lyrMarkers);
//add marker on given coordinates
map.setCenter(lonLat, zoom);
zoom = map.getZoom();
}
var iconSize = new OpenLayers.Size(36, 36);
var iconOffset = new OpenLayers.Pixel(-(iconSize.w / 2), -iconSize.h);
var icon = new OpenLayers.Icon(iconurl, iconSize, iconOffset);
var pt = new OpenLayers.LonLat(lng, lat).transform(
new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject());
bounds.extend(pt);
var feature = new OpenLayers.Feature(lyrMarkers, pt);
feature.closeBox = true;
feature.popupClass = popupClass;
feature.data.popupContentHTML = info;
feature.data.overflow = "auto";
var marker = new OpenLayers.Marker(pt, icon.clone());
var markerClick = function(evt) {
if (currentPopup != null && currentPopup.visible()) {
currentPopup.hide();
}
if (this.popup == null) {
this.popup = this.createPopup(this.closeBox);
map.addPopup(this.popup);
this.popup.show();
} else {
this.popup.toggle();
}
currentPopup = this.popup;
OpenLayers.Event.stop(evt);
};
marker.events.register("mousedown", feature, markerClick);
lyrMarkers.addMarker(marker);
}
// end addMarker function
Best regards! I hope this helps someone who needs this to work...

Resources