I want add these circles onClick of mouse on Openlayer map - javascript

I want to make a circle on map using jQuery. In this given code circles are made randomly. But I want to make only one circle on click. Openlayer.js can be found on Openlayer website.
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<script type='text/javascript' src='OpenLayers.js'></script>
<script type='text/javascript'>
var map;
var vector_layer;
function init() {
//Create a map with an empty array of controls
map = new OpenLayers.Map('map_element');
//Create a base layer
var wms_layer = new OpenLayers.Layer.WMS(
'OpenLayers WMS',
'http://vmap0.tiles.osgeo.org/wms/vmap0',
{layers: 'basic'},
{}
);
map.addLayer(wms_layer);
//Add vector layer
vector_layer = new OpenLayers.Layer.Vector('Settlement Vector Layer');
map.addLayer(vector_layer);
var settlement_values = {
4: 'circle'
}
//Create some points
for(var i=0; i<20; i++){
vector_layer.addFeatures([new OpenLayers.Feature.Vector(
new OpenLayers.Geometry.Point(
(Math.floor(Math.random() * 360) - 180),
(Math.floor(Math.random() * 180) - 90)
),
{
'settlement_type': settlement_values[(Math.floor(Math.random() * 5))]
}
)]);
}
//Create a style map object
var vector_style_map = new OpenLayers.StyleMap({});
//ADD RULES
//We need to create a 'lookup table' that contains the desired values
// and corresponding symbolizer
var symbolizers_lookup = {
'circle': {
'fillColor': '#336699','fillOpacity':.8, 'pointRadius':50, 'strokeColor': '#003366', 'strokeWidth':2
}
}
//Now, call addUniqueValueRules and pass in the symbolizer lookups
vector_style_map.addUniqueValueRules('default', 'settlement_type', symbolizers_lookup);
//Add the style map to the vector layer
vector_layer.styleMap = vector_style_map;
if(!map.getCenter()){
map.zoomToMaxExtent();
}
}
</script>
</head>
<body onload='init();'>
<div id='map_element' style='width: 600px; height: 600px;'></div>
</body>
</html>

I strongly recommend you to study this: http://openlayers.org/en/latest/examples/draw-features.html
Here is a minimalist edition of the example:
var draw; // global so we can remove it later
function addInteraction() {
var value = "circle"
draw = new ol.interaction.Draw({
source: source,
type: /** #type {ol.geom.GeometryType} */ (typeSelect.value)
});
map.addInteraction(draw);
}
addInteraction();
Although it does not create shapes by jquery, it allows to draw circles on the map.
Hope it helps, happy coding :)

Yes If you are talking in Openlayer2 the this will help you cheers.further I have attached code in jsfiddle
`
var point1 = new OpenLayers.Geometry.Point(0, 0);
var point2 = new OpenLayers.Geometry.Point(5000000, 1000000);
var point3 = new OpenLayers.Geometry.Point(2000000, 2000000);
var radius = $("#amount").val();
var mycircle = OpenLayers.Geometry.Polygon.createRegularPolygon(point2, radius, 20, 0);
var featurecircle = new OpenLayers.Feature.Vector(mycircle);
marker1 = new OpenLayers.Feature.Vector(point1, null, {
externalGraphic: "marker.png",
graphicWidth: 32,
graphicHeight: 32,
fillOpacity: 1
});
marker1.style = {
display: 'none'
};
http://jsfiddle.net/zLjae81b/18/`

Related

OpenLayers creating a complex style (polygon with a hole and a stroke on one side)

There was a difficulty in creating a complex polygon style.
The wording is as follows:
the polygon should be drawn as a polygon with a hole and a stroke on the outside.
In a difficult (as it seems to me) way, I made drawing a polygon with a hole:
convert to turf
using turf.buffer and a negative buffer value, I get an internal buffer
using turf.difference (source polygon and buffer) I get a polygon with a hole
But I don't understand how to draw the border only from the outside%)
If in the same function I try to return 2 styles (line + polygon), then I get an error (Uncaught TypeError: s.simplifyTransformed is not a function).
In general, is it possible to return 2 different geometries in the style?
In the picture the red polygon is what I need to get in the end.
Also I made a minimal example on codepen
I would be grateful for your help!
upd.
loops
and zoom out
To adapt the OpenLayers 3: Offset stroke style example for a polygon you would need to extend the ring by one segment at each end so you can correctly calculate the new coordinates at the original start/end point, then remove the excess when creating the resulting polygon.
var style = function(feature, resolution) {
var poly = feature.getGeometry();
if (poly.getType() == 'Polygon') {
var coordinates = poly.getCoordinates()[0];
coordinates = coordinates.slice(-2, -1).concat(coordinates).concat(coordinates.slice(1, 2));
var geom = new ol.geom.LineString(coordinates);
var colors = ['green', 'yellow', 'red'];
var width = 4;
var styles = [];
for (var line = 0; line < colors.length; line++) {
var dist = width * resolution * (line - (colors.length-1)/2);
var coords = [];
var counter = 0;
geom.forEachSegment(function(from, to) {
var angle = Math.atan2(to[1] - from[1], to[0] - from[0]);
var newFrom = [
Math.sin(angle) * dist + from[0],
-Math.cos(angle) * dist + from[1]
];
var newTo = [
Math.sin(angle) * dist + to[0],
-Math.cos(angle) * dist + to[1]
];
coords.push(newFrom);
coords.push(newTo);
if (coords.length > 2) {
var intersection = math.intersect(coords[counter], coords[counter+1], coords[counter+2], coords[counter+3]);
coords[counter+1] = (intersection) ? intersection : coords[counter+1];
coords[counter+2] = (intersection) ? intersection : coords[counter+2];
counter += 2;
}
});
styles.push(
new ol.style.Style({
geometry: new ol.geom.Polygon([coords.slice(2, -1)]),
stroke: new ol.style.Stroke({
color: colors[line],
width: width
})
})
);
}
return styles;
}
};
var raster = new ol.layer.Tile({
source: new ol.source.OSM()
});
var source = new ol.source.Vector();
var vector = new ol.layer.Vector({
source: source,
style: style
});
var map = new ol.Map({
layers: [raster, vector],
target: 'map',
view: new ol.View({
center: [-11000000, 4600000],
zoom: 4
})
});
map.addInteraction(new ol.interaction.Draw({
source: source,
type: 'Polygon',
style: style
}));
html, body, .map {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
<link href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css" rel="stylesheet" />
<script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/5.4.1/math.min.js"></script>
<div id="map" class="map"></div>
There is a problem with the original algorithm for LineStrings at corners with multiple vertices
When zoomed out the two vertices on the inner line should merge to a single point, but that is not happening, instead they cross and cause a kink in the line.

Here Maps polyline with altitude

I need to display different polylines from A to B. So, these lines should be distinguishable from each other. I haved tried to set polylines using pushpoint function with altitude parameter. However it is still on the ground level. And the last polyline I inserted overwrites the previous one.
Altitude value works on markers but I want to apply it on polyline.
I changed the sample code here markers with altitude as below. You can see the orange line is just on top of the gray line when you change the code with the below one. I would like both lines to be displayed like the markers you see above them.
/**
* Calculate the bicycle route.
* #param {H.service.Platform} platform A stub class to access HERE services
*/
function calculateRouteFromAtoB (platform) {
var router = platform.getRoutingService(),
routeRequestParams = {
mode: 'fastest;bicycle',
representation: 'display',
routeattributes : 'shape',
waypoint0: '-16.1647142,-67.7229166',
waypoint1: '-16.3705847,-68.0452683',
// explicitly request altitude values
returnElevation: true
};
router.calculateRoute(
routeRequestParams,
onSuccess,
onError
);
}
/**
* Process the routing response and visualise the descent with the help of the
* H.map.Marker
*/
function onSuccess(result) {
var lineString = new H.geo.LineString(),
lineString2 = new H.geo.LineString(),
routeShape = result.response.route[0].shape,
group = new H.map.Group(),
dict = {},
polyline,
polyline2;
routeShape.forEach(function(point) {
var parts = point.split(',');
var pp= new H.geo.Point(parts[0],parts[1],4000,"SL");
console.log(parts[2]);
lineString.pushLatLngAlt(parts[0], parts[1]);
lineString2.pushPoint(pp);
// normalize the altitude values for the color range
var p = (parts[2] - 1000) / (4700 - 1000);
var r = Math.round(255 * p);
var b = Math.round(255 - 255 * p);
// create or re-use icon
var icon;
if (dict[r + '_' + b]) {
icon = dict[r + '_' + b];
} else {
var canvas = document.createElement('canvas');
canvas.width = 4;
canvas.height = 4;
var ctx = canvas.getContext('2d');
ctx.fillStyle = 'rgb(' + r + ', 0, ' + b + ')';
ctx.fillRect(0, 0, 4, 4);
icon = new H.map.Icon(canvas);
// cache the icon for the future reuse
dict[r + '_' + b] = icon;
}
// the marker is placed at the provided altitude
var marker = new H.map.Marker({
lat: parts[0], lng: parts[1], alt: parts[2]
}, {icon: icon});
var marker2 = new H.map.Marker({
lat: parts[0], lng: parts[1], alt: parts[2]-800
}, {icon: icon});
group.addObject(marker);
group.addObject(marker2);
});
polyline = new H.map.Polyline(lineString, {
style: {
lineWidth: 6,
strokeColor: '#555555'
}
});
polyline2 = new H.map.Polyline(lineString2, {
style: {
lineWidth: 3,
strokeColor: '#FF5733'
}
});
// Add the polyline to the map
map.addObject(polyline);
map.addObject(polyline2);
// Add markers to the map
map.addObject(group);
// Zoom to its bounding rectangle
map.getViewModel().setLookAtData({
bounds: polyline.getBoundingBox(),
tilt: 60
});
}
/**
* This function will be called if a communication error occurs during the JSON-P request
* #param {Object} error The error message received.
*/
function onError(error) {
alert('Can\'t reach the remote server');
}
/**
* Boilerplate map initialization code starts below:
*/
// set up containers for the map + panel
var mapContainer = document.getElementById('map'),
routeInstructionsContainer = document.getElementById('panel');
//Step 1: initialize communication with the platform
// In your own code, replace variable window.apikey with your own apikey
var platform = new H.service.Platform({
apikey: window.apikey
});
var defaultLayers = platform.createDefaultLayers();
//Step 2: initialize a map - this map is centered over Berlin
var map = new H.Map(mapContainer,
defaultLayers.vector.normal.map,{
center: {lat:52.5160, lng:13.3779},
zoom: 13,
pixelRatio: window.devicePixelRatio || 1
});
// add a resize listener to make sure that the map occupies the whole container
window.addEventListener('resize', () => map.getViewPort().resize());
//Step 3: make the map interactive
// MapEvents enables the event system
// Behavior implements default interactions for pan/zoom (also on mobile touch environments)
var behavior = new H.mapevents.Behavior(new H.mapevents.MapEvents(map));
// Create the default UI components
var ui = H.ui.UI.createDefault(map, defaultLayers);
// Now use the map as required...
calculateRouteFromAtoB (platform);
Unfortunately, for now only markers support altitudes.
Polylines should follow in near future.

How to drawing in Here Map with HERE MAP Javascript 3 API?

How to drawing a geoshapes (polygon) in HERE Maps javascript 3.0 with mouse event click? and save the coordinates in database..
I search the guides at developer.here.com but no one script guides showing how to draw in here map javascript 3.0 API. (https://developer.here.com/api-explorer/maps-js/geoshapes/polygon-on-the-map)
Beside that in javascript 2.5 API show the guides, but it will be expired and deleted soon.
here a script to draw in javascript 2.5 (http://developer.here.com/apiexplorer/index.html#js/pub/shapes/map-with-polyline-on-click/):
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=7; IE=EmulateIE9; IE=10" />
<base href="./../../../..//examples/public/api-for-js/shapes/map-with-polyline-on-click.html" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>HERE Maps API for JavaScript Example: Click to create a polyline on map</title>
<meta name="description" content="Creating a polyline wih markers by clicking on the map"/>
<meta name="keywords" content="drawpolyline, map objects, shape, shapes, triangle, rectangle, circle, polyline, polygon"/>
<meta name=viewport content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
<link rel="stylesheet" type="text/css" href="./../../../..//examples/templates/js/exampleHelpers.css"/>
<script type="text/javascript" charset="UTF-8" src="http://js.cit.api.here.com/se/2.5.4/jsl.js?with=all"></script>
<script type="text/javascript" charset="UTF-8" src="./../../../..//examples/templates/js/exampleHelpers.js"></script>
<style type="text/css">
html {
overflow:hidden;
}
body {
margin: 0;
padding: 0;
overflow: hidden;
width: 100%;
height: 100%;
position: absolute;
}
#mapContainer {
width: 100%;
height: 100%;
left: 0;
top: 0;
position: absolute;
}
</style>
</head>
<body>
<div id="mapContainer"></div>
<div id="uiContainer"></div>
<script type="text/javascript" id="exampleJsSource">
nokia.Settings.set("app_id", "DemoAppId01082013GAL");
nokia.Settings.set("app_code", "AJKnXv84fjrb0KIHawS0Tg");
// Use staging environment (remove the line for production environment)
nokia.Settings.set("serviceMode", "cit");
// Get the DOM node to which we will append the map
var mapContainer = document.getElementById("mapContainer");
// Create a map inside the map container DOM node
var map = new nokia.maps.map.Display(mapContainer, {
// Initial center and zoom level of the map
center: [52.51, 13.4],
zoomLevel: 10,
components: [
// ZoomBar provides a UI to zoom the map in & out
new nokia.maps.map.component.ZoomBar(),
// we add the behavior component to allow panning / zooming of the map
new nokia.maps.map.component.Behavior(),
// creates UI to easily switch between street map satellite and terrain mapview modes
new nokia.maps.map.component.TypeSelector()
]
});
var noteContainer = new NoteContainer({
id: "drawPolylineUi",
parent: document.getElementById("uiContainer"),
title: "Drawing a polyline",
content:
'<p>Click or touch anywhere on the map to add a new point to the existing polyline.</p>' +
'<input id="resetPolyline" role="button" type="button" value="Reset Polyline"/>'
});
// We bind DOM element to variable so we use it later to install event handler.
var resetPolylineUiElt = document.getElementById("resetPolyline");
// Javascript inheritance helper function
function extend(B, A) {
function I() {}
I.prototype = A.prototype;
B.prototype = new I();
B.prototype.constructor = B;
}
var MarkerPolyline = function (coords, props) {
// Call the "super" constructor to initialize properties inherited from Container
nokia.maps.map.Container.call(this);
// Calling MarkerPolyline constructor
this.init(coords, props);
};
extend(MarkerPolyline, nokia.maps.map.Container);
// MarkerPolyline constructor function
MarkerPolyline.prototype.init = function (coords, props) {
var i,
coord,
marker,
lineProps = props.polyline || {},
markerProps = (this.markerProps = props.marker || {});
this.coords = {};
// Create a polyline
this.polyline = new nokia.maps.map.Polyline(coords, lineProps);
// Add the polyline to the container
this.objects.add(this.polyline);
/* We loop through the point to create markers
* for each of the points and we store them
*/
for (i = 0; coord = coords[i]; i++) {
marker = new nokia.maps.map.StandardMarker(coord, markerProps);
this.coords[coord.latitude + "_" + coord.longitude] = { idx: i + 1, marker: marker };
this.objects.add(marker);
}
};
// The add function allows you to add a new point to a MarkerPolyline
MarkerPolyline.prototype.add = function (coord) {
// Create a new standard marker
var markerProps = this.markerProps,
marker,
key = coord.latitude + "_" + coord.longitude;
if (!this.coords[key]) {
marker = new nokia.maps.map.StandardMarker(coord, markerProps);
this.coords[key] = { idx: this.objects.getLength(), marker: marker };
/* Add the marker to the object's collections
* so the marker will be rendered onto the map
*/
this.objects.add(marker);
this.polyline.path.add(coord);
}
};
// The remove function allows you to remove a point from MarkerPolyline
MarkerPolyline.prototype.remove = function (coord) {
var coords = this.polyline.path.internalArray,
i = this.polyline.path.getLength(),
marker,
key = coord.latitude + "_" + coord.longitude,
idx;
if (!this.coords[key])
return;
while (i--) {
if (coords[i * 3 ] === coord.latitude && coords[i * 3 + 1] === coord.longitude) {
idx = i;
}
}
// Index of coordinate found, now we remove coordinate from polyline
this.polyline.path.remove(idx);
// Remove the marker
marker = this.coords[key].marker;
this.objects.remove(marker);
marker.destroy();
delete this.coords[key];
};
// Set of initial geo coordinates to create the polyline
var coords = [
new nokia.maps.geo.Coordinate(52.5032, 13.2790),
new nokia.maps.geo.Coordinate(52.5102, 13.2818),
new nokia.maps.geo.Coordinate(52.5121, 13.3224),
new nokia.maps.geo.Coordinate(52.5145, 13.3487),
new nokia.maps.geo.Coordinate(52.5139, 13.3501),
new nokia.maps.geo.Coordinate(52.5146, 13.3515),
new nokia.maps.geo.Coordinate(52.5161, 13.3769)
];
// Create a new polyline with markers
var markerPolyline = new MarkerPolyline(
coords,
{
polyline: { pen: { strokeColor: "#00F8", lineWidth: 4 } },
marker: { brush: { color: "#1080dd" } }
}
);
/* Add the markerPolyline to the map's object collection so
* all of its containing shapes will be rendered onto the map.
*/
map.objects.add(markerPolyline);
/* We would like to add event listener on mouse click or finger tap so we check
* nokia.maps.dom.Page.browser.touch which indicates whether the used browser has a touch interface.
*/
var TOUCH = nokia.maps.dom.Page.browser.touch,
CLICK = TOUCH ? "tap" : "click",
addedCoords = [];
// Attach an event listeners on mouse click / touch to add points to
map.addListener(CLICK, function (evt) {
// We translate a screen pixel into geo coordinate (latitude, longitude)
var coord = map.pixelToGeo(evt.displayX, evt.displayY);
// Next we add the geoCoordinate to the markerPolyline
markerPolyline.add(coord);
// We store added coordinates so we can remove them later on
addedCoords.push(coord);
});
// Reset markerPolyline to its original shape on click of reset button
resetPolylineUiElt.onclick = function () {
var i = addedCoords.length;
while (i--) {
markerPolyline.remove(addedCoords[i]);
}
addedCoords = [];
};
// Zoom the map to encapsulate the initial polyline, once the map is initialized and ready
map.addListener("displayready", function () {
map.zoomTo(markerPolyline.getBoundingBox());
});
</script>
</body>
</html>
You must update the strip of the GeoShape:
get the strip via getStrip()
push a geo.Point to the strip via pushPoint()
apply the updated strip via setStrip()
// enable the event system
var behavior = new H.mapevents.Behavior(new H.mapevents.MapEvents(map)),
//create the line
line=new H.map.Polyline(new H.geo.Strip([ 52.5032, 13.2790,0,
52.5102, 13.2818,0,
52.5121, 13.3224,0,
52.5145, 13.3487,0,
52.5139, 13.3501,0,
52.5146, 13.3515,0,
52.5161, 13.3769,0])
);
//draw the line
map.addObject(line);
//add tap-listener
map.addEventListener('tap', function(e){
var pointer = e.currentPointer,
//create geo.Point
latLng = map.screenToGeo(pointer.viewportX, pointer.viewportY),
//get current strip
strip=line.getStrip();
//push point to strip
strip.pushPoint(latLng);
//set updated strip
line.setStrip(strip);
});

how can I set markers with different colours depending on the markertype, and how to determinate their coordinates?, Im using openlayers.org library

I am starting using openlayers javascript library from openlayers.org.
I want to set dinamic markers with diferent colours for each device type(cam marker, server marker and so on), and I tried different ways to set this, but it doesn't work actually.
This is the map that Im developing: http://manotazsoluciones.com/map/.
Another problem that Im facing is when I set coordinates. For example: if I set [0,0] coordinates on a marker, when I use click event, the marker get another coordinates like
[30000,-7.081154551613622e-10].
this is the code that Im using to display the map on manotazsoluciones.com/map
<!DOCTYPE html>
<html>
<head>
<title>Manotaz Soluciones</title>
<script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ol3/3.6.0/ol.css" type="text/css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/ol3/3.6.0/ol.js"></script>
</head>
<body>
<div class="container-fluid">
<div class="row-fluid">
<div class="col-md-10 col-md-offset-1">
<div id="map" class="map">
<div id="popup">
<div id="popup-content"></div>
</div>
</div>
</div>
</div>
</div>
<script>
$( document ).ready(function() {
/**************** DRAG AND DROP EVENTS ****************/
/**
* Define a namespace for the application.
*/
window.app = {};
var app = window.app;
/**
* #constructor
* #extends {ol.interaction.Pointer}
*/
app.Drag = function() {
ol.interaction.Pointer.call(this, {
handleDownEvent: app.Drag.prototype.handleDownEvent,
handleDragEvent: app.Drag.prototype.handleDragEvent,
handleMoveEvent: app.Drag.prototype.handleMoveEvent,
handleUpEvent: app.Drag.prototype.handleUpEvent
});
/**
* #type {ol.Pixel}
* #private
*/
this.coordinate_ = null;
/**
* #type {string|undefined}
* #private
*/
this.cursor_ = 'pointer';
/**
* #type {ol.Feature}
* #private
*/
this.feature_ = null;
/**
* #type {string|undefined}
* #private
*/
this.previousCursor_ = undefined;
};
ol.inherits(app.Drag, ol.interaction.Pointer);
/**
* #param {ol.MapBrowserEvent} evt Map browser event.
* #return {boolean} `true` to start the drag sequence.
*/
app.Drag.prototype.handleDownEvent = function(evt) {
var map = evt.map;
var feature = map.forEachFeatureAtPixel(evt.pixel,
function(feature, layer) {
return feature;
});
if (feature) {
this.coordinate_ = evt.coordinate;
this.feature_ = feature;
}
return !!feature;
};
/**
* #param {ol.MapBrowserEvent} evt Map browser event.
*/
app.Drag.prototype.handleDragEvent = function(evt) {
var map = evt.map;
var feature = map.forEachFeatureAtPixel(evt.pixel,
function(feature, layer) {
return feature;
});
var deltaX = evt.coordinate[0] - this.coordinate_[0];
var deltaY = evt.coordinate[1] - this.coordinate_[1];
var geometry = /** #type {ol.geom.SimpleGeometry} */
(this.feature_.getGeometry());
geometry.translate(deltaX, deltaY);
this.coordinate_[0] = evt.coordinate[0];
this.coordinate_[1] = evt.coordinate[1];
};
/**
* #param {ol.MapBrowserEvent} evt Event.
*/
app.Drag.prototype.handleMoveEvent = function(evt) {
if (this.cursor_) {
var map = evt.map;
var feature = map.forEachFeatureAtPixel(evt.pixel,
function(feature, layer) {
return feature;
});
var element = evt.map.getTargetElement();
if (feature) {
if (element.style.cursor != this.cursor_) {
this.previousCursor_ = element.style.cursor;
element.style.cursor = this.cursor_;
}
} else if (this.previousCursor_ !== undefined) {
element.style.cursor = this.previousCursor_;
this.previousCursor_ = undefined;
}
}
};
/**
* #param {ol.MapBrowserEvent} evt Map browser event.
* #return {boolean} `false` to stop the drag sequence.
*/
app.Drag.prototype.handleUpEvent = function(evt) {
this.coordinate_ = null;
this.feature_ = null;
return false;
};
/*************** DRAG AND DROP EVENTS END *************/
You can ignore the drag and drop events above, because it works fine
var devices = [
{
'id' : 1,
'device' : 'cam',
'brand' : 'dahua',
'coordinates' : [0,0]
},
{
'id' : 2,
'device' : 'cam',
'brand' : 'vivotes',
'coordinates' : [0,1]
},
{
'id' : 3,
'device' : 'cam',
'brand' : 'dahua',
'coordinates' : [0, 2]
},
{
'id' : 4,
'device' : 'rack',
'brand' : 'dahua',
'coordinates' : [0, 3]
}
];
the code above is just an example of the resource that I want to display
var circle = [];
for (var i = 0; i < devices.length; i++) {
circle[i] = new ol.Feature(
new ol.geom.Circle(
ol.proj.transform(devices[i].coordinates, 'EPSG:4326', 'EPSG:3857'),//usar latitud, longitud, coord sys
30000
)
);
}
on var circle Im saving the coordinates and size for each marker.
var styles = [
new ol.style.Style({
image: new ol.style.Icon({ //#type {olx.style.IconOptions}
anchor: [0.5, 46],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
opacity: 1,
population: 4000,
rainfall: 500
}),
fill: new ol.style.Fill({
color: [150, 150, 255, 1]
})
})
];
in styles im setting the color for all markers, but I want to change his values depending on the device type
// RENDER DEVICES
var objects = new ol.source.Vector({ features: circle })
var bullets = new ol.layer.Vector({
source : objects,
style: styles
});
above Im setting the markers and styles.
//layers-capaImagen, propiedades imagen principal
var extent = ol.proj.transformExtent([-50, 50, 50, -40], 'EPSG:4326', 'EPSG:3857');
var imgProjection = new ol.proj.Projection({
code: 'xkcd-image',
units: 'pixels',
extent: [0, 0, 1024, 968]
});
var capaImagen = new ol.layer.Image();
source = new ol.source.ImageStatic({
url: 'plano-vertical-knits.jpg',
imageExtent: extent,
projection: imgProjection,
center: ol.extent.getCenter(imgProjection.getExtent()),
extent: imgProjection.getExtent()
});
capaImagen.setSource(source);
//end propiedades imagen principal
//map features before render
var features = {
controls : ol.control.defaults({attribution : false}).extend([ new ol.control.FullScreen() ]),
interactions: ol.interaction.defaults().extend([new app.Drag()]),
layers : [capaImagen, bullets],
view: new ol.View({ center: [0, 0], zoom: 3 }),
target : 'map'
};
var map = new ol.Map(features);
above Im rendering the map with their features
// display popup on click
var pops = document.getElementById('popup');
var popupContent = document.getElementById('popup-content');
var popup = new ol.Overlay({/** #type {olx.OverlayOptions} */
element: pops,
autoPan: true,
stopEvent: false,
positioning: 'bottom-center',
autoPanAnimation: {
duration: 250
}
});
map.addOverlay(popup);
/* events ON map */
map.on('click', function(evt) {
var feature = map.forEachFeatureAtPixel(evt.pixel, function(feature, layer) {
return feature;
});
if (feature) {
var geometry = feature.getGeometry();
var firstCoord = geometry.getFirstCoordinate();
var lastCoord = geometry.getLastCoordinate();
popup.setPosition(firstCoord);
$(pops).popover({
'placement': 'top',
'html': true,
'content': feature.get('name')
});
//var latlong = ol.proj.transform([firstCoord, lastCoord], 'EPSG:4326', 'EPSG:3857');
popupContent.innerHTML = '<p>You clicked here:</p><p>'+lastCoord+'</p>';
$(pops).popover('show');
}
});
// change mouse cursor when over marker
map.on('pointermove', function(e) {
if (e.dragging) {
$('#popup-content').empty();
return;
}
});
/* events ON map END */
});
</script>
</body>
</html>
on click function Im trying to get the coordinates, and is where the coordinates shows me another values.
I extracted some of your codes and I added some modifications.
Style problem
Each feature needs to have a reference to the properties that you saved in array devices:
for (var i = 0; i < devices.length; i++) {
circle[i] = new ol.Feature(
{geometry: new ol.geom.Circle(
ol.proj.transform(devices[i].coordinates, ), 'EPSG:4326', 'EPSG:3857'),//usar latitud, longitud, coord sys
1
),
device: devices[i].device}
);
}
Additionally, it is necessary to set a different style for each desired property. Something like that should work:
var bullets = new ol.layer.Vector({
source: objects,
style: function (el, resolution) {//this is a style function
console.log(el, el.getProperties().device);
if (el.getProperties().device === 'cam')
return styles;
return styles2;
}
});
Problem with the coordinates
I think the problem in this case is due to the projection. You defined a custom projection (based on pixel) and applied it to the image. For the map view you don't define any projection (so it remains the default EPSG:3857). All the coordinates of the circle are converted from 'EPSG:4326' to 'EPSG:3857'. Therefore, the values that you see in the popup are in EPSG:3857 (not longitude and latitude). If you decide to continue to use EPSG:3857, you should also adapt the static image to this coordinates system via:
source = new ol.source.ImageStatic({
...............
imageExtent: .....
As you can find in the documentation imageExtent is the extent of the image in map coordinates. But in your code imageExtent is just the extent in pixel of the image.......

OpenLayers 2.13: clustering strategy is not working

I am trying to apply a simple clustering stategy to my OpenLayers v2.13 map, but it is not working.
Here is my code so far, it all loads correctly but the random points on the map do not cluster, they just overlap horribly...
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta charset="utf-8">
<title>OpenLayers 2.13.x Clustered Markers</title>
<script src="../OpenLayers.js"></script>
</head>
<body onload="run()" style="position: absolute; top: 0; bottom: 0; left: 0; right: 0;">
<div id='map' style="width: 100%; height: 100%">
</div>
<script>
function run(){
// create the map
var map = new OpenLayers.Map("map");
// add a google maps layer to the map
var layer = new OpenLayers.Layer.WMS("OpenLayers WMS", "http://vmap0.tiles.osgeo.org/wms/vmap0", {
layers: "basic"
});
map.addLayers([layer]);
// set up cluster strategy and vector layer
var strategy = new OpenLayers.Strategy.Cluster({
distance: 15,
clustering: true
});
var markersLayer = new OpenLayers.Layer.Vector("Clustered markers", {strategies: [strategy]});
// create and add all markers randomly
var markers = [];
for (var i = 0; i < 700; i++) {
var r1 = Math.random();
var r2 = Math.random();
var r3 = Math.random();
var r4 = Math.random();
var px = r1 * 180 * ((r2 < 0.5) ? -1 : 1);
var py = r3 * 90 * ((r4 < 0.5) ? -1 : 1);
var p = new OpenLayers.Geometry.Point(px, py);
var clazz = (i % 10 === 0) ? 4 : Math.ceil(r4 * 3);
var f = new OpenLayers.Feature.Vector(p, {clazz: clazz});
markers.push(f);
}
markersLayer.addFeatures(markers);
// add markers layer to the map
map.addLayer(markersLayer);
map.zoomToMaxExtent();
}
</script>
</body>
</html>
Note: OpenLayers is locally on my machine and is version 2.13.1
I have looked at several examples, none have helped me solve this issue. I have looked at several stack overflow answers, the best of them was about marker clustering, but also didn't help.
I must be missing something obvious but I cant see what?
[UPDATE]
Taking advice from the answers below, here is the code snippet (from above) edited to run correctly, adding the markers after the layer has been added to the map and not including the clustering flag...
// set up cluster strategy and vector layer
var strategy = new OpenLayers.Strategy.Cluster({
distance: 15 // <-- removed clustering flag
});
var markersLayer = new OpenLayers.Layer.Vector("Clustered markers", {strategies: [strategy]});
// add markers layer to the map
map.addLayer(markersLayer); // <-- adding layer before adding features
// create and add all markers randomly
var markers = [];
for (var i = 0; i < 700; i++) {
var r1 = Math.random();
var r2 = Math.random();
var r3 = Math.random();
var r4 = Math.random();
var px = r1 * 180 * ((r2 < 0.5) ? -1 : 1);
var py = r3 * 90 * ((r4 < 0.5) ? -1 : 1);
var p = new OpenLayers.Geometry.Point(px, py);
var clazz = (i % 10 === 0) ? 4 : Math.ceil(r4 * 3);
var f = new OpenLayers.Feature.Vector(p, {clazz: clazz});
markers.push(f);
}
markersLayer.addFeatures(markers); // <-- now can add features
// zoom to extent
map.zoomToMaxExtent();
It looks like maybe a good practice to follow is to make sure that you add a layer to the map before adding/removing features to it.
I removed "clustering" from the cluster strategy options
// set up cluster strategy and vector layer
var strategy = new OpenLayers.Strategy.Cluster({
distance: 15
});
and then added the markers after I'd added the layer to the map
// add markers layer to the map
map.addLayer(markersLayer);
markersLayer.addFeatures(markers);
map.zoomToMaxExtent();
then all seemed to work.
Mailed similar to Angela to you internally.
Not sure why removing clustering has any affect, I think its true by default anyway.
As for the order of adding the points, I seem to remember reading something about the fact your points are replaced by the clusters so adding the layer to map after adding points to layer may mean that process doesn't happen. Or something. ;)
Cheers
Ian

Categories