How to add draw over an OpenLayer 3 map? - gis

I am new to OpenLayers 3. I am trying to learn how to draw and save data over an OpenLayers map. Following an example, I am trying to learn about drawing and saving data. However, I am unable to draw anything over the map. I am posting the code below.
<!doctype html>
<html lang="en">
<head>
<link rel="stylesheet" href="css/ol.css" type="text/css">
<style>
.map {
height: 400px;
width: 100%;
}
</style>
<title>OpenLayers 3 example</title>
<script src="js/ol.js" type="text/javascript"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
</head>
<body>
<div id="map" class="map"></div>
<div>
<label>Interaction type: </label>
<label>draw</label>
<input type="radio" id="interaction_type_draw" name="interaction_type" value="draw" checked>
<label>modify</label>
<input type="radio" id="interaction_type_modify" name="interaction_type" value="modify">
</div>
<div>
<label>Geometry type</label>
<select id="geom_type">
<option value="Point" selected>Point</option>
<option value="LineString">LineString</option>
<option value="Polygon">Polygon</option>
</select>
</div>
<div>
<label>Data type</label>
<select id="data_type">
<option value="GeoJSON" selected>GeoJSON</option>
<option value="KML">KML</option>
<option value="GPX">GPX</option>
</select>
</div>
<div id="delete" style="text-decoration:underline;cursor:pointer">
Delete all features
</div>
<label>Data:</label>
<textarea id="data" rows="12" style="width:100%"></textarea>
<script>
var source = new ol.source.Vector();
var vector = new ol.layer.Vector({
source: source, style: new ol.style.Style({
fill: new ol.style.Fill({
color: 'rgba(255, 255, 255, 0.2)' }),
stroke: new ol.style.Stroke({
color: '#ffcc33',
width: 2
}),
image: new ol.style.Circle({
radius: 7,
fill: new ol.style.Fill({
color: '#ffcc33'
})
})
})
});
// Create a map
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
}),
vector
],
view: new ol.View({
zoom: 2,
center: [0, 0]
})
});
// make draw global so it can later be removed
var draw;
// creat a select to choose geometry type
var typeSelect = document.getElementById('type');
// rebuild interaction when changed
typeSelect.onchange = function(e) {
map.removeInteraction(draw);
addInteraction();
};
// create a select to choose a data type to save in
dataTypeSelect = document.getElementById('data_type');
// clear map and rebuild interaction when changed
dataTypeSelect.onchange = function(e) {
clearMap();
map.removeInteraction(draw);
addInteraction();
};
// add draw interaction
function addInteraction() {
var geom_type = typeSelect.value;
if (geom_type !== 'None') {
draw = new ol.interaction.Draw({
source: source,
type: /** #type {ol.geom.GeometryType} */ (geom_type)
});
draw.on('drawend', function(evt) {
saveData();
});
map.addInteraction(draw);
}
}
function saveData() {
var allFeatures = vector.getSource().getFeatures(),
format = new ol.format[dataTypeSelect.value](),
data;
try {
data = format.writeFeatures(allFeatures);
} catch (e) {
// at time of creation there is an error in the GPX format (18.7.2014)
document.getElementById('data').value = e.name + ": " + e.message;
return;
}
if (dataTypeSelect.value === 'GeoJSON') {
// format is JSON
document.getElementById('data').value = JSON.stringify(data, null, 4);
} else {
// format is XML (GPX or KML)
var serializer = new XMLSerializer();
document.getElementById('data').value = serializer.serializeToString(data);
}
}
// add the interaction when the page is first shown
addInteraction();
// clear map when user clicks on 'Delete all features'
$("#delete").click(function() {
clearMap();
});
// clears the map and the output of the data
function clearMap() {
vector.getSource().clear();
document.getElementById('data').value = '';
}
</script>
</body>
</html>
Please tell me why am I not able to see any drawings over the map? However, the example that I am looking at works just fine. I am unable to find out the problem. Please help me out so that I can experiment with openLayers and learn more. Thanks!

You should be more careful about selecting dom elements using jquery. Also i strongly recommend using Firebug and checking the console for errors on page load. Here's the fixed full source.
<!doctype html>
<html lang="en">
<head>
<link rel="stylesheet" href="css/ol.css" type="text/css">
<style>
.map {
height: 400px;
width: 100%;
}
</style>
<title>OpenLayers 3 example</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ol3/3.17.1/ol-debug.js"></script>
<!--<script src="js/ol.js" type="text/javascript"></script>-->
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
</head>
<body>
<div id="map" class="map"></div>
<div>
<label>Interaction type: </label>
<label>draw</label>
<input type="radio" id="interaction_type_draw" name="interaction_type" value="draw" checked>
<label>modify</label>
<input type="radio" id="interaction_type_modify" name="interaction_type" value="modify">
</div>
<div>
<label>Geometry type</label>
<select id="geom_type">
<option value="Point" selected>Point</option>
<option value="LineString">LineString</option>
<option value="Polygon">Polygon</option>
</select>
</div>
<div>
<label>Data type</label>
<select id="data_type">
<option value="GeoJSON" selected>GeoJSON</option>
<option value="KML">KML</option>
<option value="GPX">GPX</option>
</select>
</div>
<div id="delete" style="text-decoration:underline;cursor:pointer">
Delete all features
</div>
<label>Data:</label>
<textarea id="data" rows="12" style="width:100%"></textarea>
<script>
var source = new ol.source.Vector();
var vector = new ol.layer.Vector({
source: source, style: new ol.style.Style({
fill: new ol.style.Fill({
color: 'rgba(255, 255, 255, 0.2)'
}),
stroke: new ol.style.Stroke({
color: '#ffcc33',
width: 2
}),
image: new ol.style.Circle({
radius: 7,
fill: new ol.style.Fill({
color: '#ffcc33'
})
})
})
});
// Create a map
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
}),
vector
],
view: new ol.View({
zoom: 2,
center: [0, 0]
})
});
// make draw global so it can later be removed
var draw;
// creat a select to choose geometry type
var typeSelect = document.getElementById('geom_type');
// rebuild interaction when changed
typeSelect.onchange = function (e) {
map.removeInteraction(draw);
addInteraction();
};
// create a select to choose a data type to save in
dataTypeSelect = document.getElementById('data_type');
// clear map and rebuild interaction when changed
dataTypeSelect.onchange = function (e) {
clearMap();
map.removeInteraction(draw);
addInteraction();
};
// add draw interaction
function addInteraction() {
var geom_type = typeSelect.value;
if (geom_type !== 'None') {
draw = new ol.interaction.Draw({
source: source,
type: /** #type {ol.geom.GeometryType} */ (geom_type)
});
draw.on('drawend', function (evt) {
saveData();
});
map.addInteraction(draw);
}
}
function saveData() {
var allFeatures = vector.getSource().getFeatures(),
format = new ol.format[dataTypeSelect.value](),
data;
try {
data = format.writeFeatures(allFeatures);
} catch (e) {
// at time of creation there is an error in the GPX format (18.7.2014)
document.getElementById('data').value = e.name + ": " + e.message;
return;
}
if (dataTypeSelect.value === 'GeoJSON') {
// format is JSON
document.getElementById('data').value = JSON.stringify(data, null, 4);
} else {
// format is XML (GPX or KML)
var serializer = new XMLSerializer();
document.getElementById('data').value = serializer.serializeToString(data);
}
}
// add the interaction when the page is first shown
addInteraction();
// clear map when user clicks on 'Delete all features'
$("#delete").click(function () {
clearMap();
});
// clears the map and the output of the data
function clearMap() {
vector.getSource().clear();
document.getElementById('data').value = '';
}
</script>
</body>
</html>

Related

Why I'm getting this error "Cannot draw chart: no data specified."?

I'm trying to load my google spreadsheet into my very basic webapp but I keep getting this error "Cannot draw chart: no data specified." what I'm doing wrong ?
Here is my HTML
<!DOCTYPE html>
<html>
<head>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<script>
const loaded = new Promise((res, rej) => {
google.charts.load('current');
google.charts.setOnLoadCallback(res);
});
let wrapper = null;
async function drawTable(arr) {
await loaded; //wait if charts is not loaded
wrapper = new google.visualization.ChartWrapper({
chartType: 'Table',
dataTable: arr,
containerId: 'table_div',
});
wrapper.draw();
}
function getData(form) {
google.script.run
.withSuccessHandler(drawTable)
.getDataFromServer(form);//change server function name
}
</script>
</head>
<body>
<form>
<input type="text" name="searchtext" />
<input type="button" value="ok" onclick="getData(this.parentNode)" />
</form>
<div id="table_div"></div>
</body>
</html>
and here is my CODE.GS
function doGet() {
return HtmlService.createHtmlOutputFromFile('index');
}
function getDataFromServer(e) {
var id ="1GRi3NAdannp3uNDi202HC5hKNMNIVMNw_WPDYIes5Hs";
var data = SpreadsheetApp.openById(id)
.getSheetByName("Daily report")
.getDataRange()
.getValues();
var ar = data.splice(0,1); //add headers
data.forEach(function(f) {
if (~f.indexOf(e.searchtext)) ar.push(f);
});
return ar;
}
And this is the link of my google spreadsheet .
https://docs.google.com/spreadsheets/d/1GRi3NAdannp3uNDi202HC5hKNMNIVMNw_WPDYIes5Hs/edit?usp=sharing
Thanks,
Here's a simple example of how I load data into a chart. First column date string and the other four columns are numbers.
function drawMealsChartOld(){
$('#btnC').css('background-color','#ffff00');
google.script.run
.withSuccessHandler(function(mObj){
var dt=mObj.dA;
var hA=dt[0];
dt.splice(0,1);
var dA=dt.slice();
var data = new google.visualization.DataTable();
for(var i=0;i<hA.length;i++){
if(i===0){
data.addColumn('string',hA[i]);
}else{
data.addColumn('number',hA[i]);
}
}
data.addRows(dA);
var options={
title:'Meals Grams (Starts: ' + mObj.start + ' - Ends: ' + mObj.end + ')',
fontSize: 14,
fontName: 'Roman',
width:640,
height:350,
pointSize:3,
hAxis:{slantedText:true,slantedTextAngle:90,textStyle:{color:'#333300',fontName:'Verdana',fontSize:8,bold:true}},
legend:{position:'top'},
chartArea:{left:75,top:75,width:'75%',height:'50%'},
series:{0: {targetAxisIndex: 0}, 1:{targetAxisIndex: 0}},
vAxes:[{title:'GRAMS',titleTextStyle:{color:'#0000CC',fontName:'Verdana',fontSize:12,bold:true,italic:false},textStyle:{color:'#0000CC',fontName:'Verdana',fontSize:10,bold:true,italic:false}}]
};
var chart=new google.visualization.LineChart(document.getElementById('mcht'));
//Not interested in emailing this chart I just want to be able to see how the average is doing.
//google.visualization.events.addListener(chart,'click',function(){emailVitalsDialog()});
//google.visualization.events.addListener(chart,'ready',function(){
//gImgObj['base64Data']=chart.getImageURI().split(',')[1];
//gImgObj.ready=true;
//});
chart.draw(data,options);
$('#btnC').css('background-color','#ffffff');
})
.getMealsData();
}

Export Google visualization as picture

I'm trying to convert a wordtree Google visualization to an image. The current code below runs the wordtree so I can see the visual, but I can't figure out the last section to convert to an image or export as an image. (var my_div = section to end)
I have tried changing code from link below, but can't get it to save as an image.
https://developers.google.com/chart/interactive/docs/printing
I'm also doing this inside of jsfiddle.net to try and make this work.
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current'); // Don't need to specify chart libraries!
google.charts.setOnLoadCallback(drawVisualization);
function drawVisualization() {
google.visualization.drawChart({
"containerId": "mywordtree",
"dataSourceUrl": "https://docs.google.com/spreadsheets/d/1vi-YzV7s7eZ25938Q57DbZvT0iqggiCqRvDgxeZtP6c/edit?usp=sharing",
"query":"SELECT A",
"chartType": "WordTree",
"options": {
wordtree: {
format: 'implicit',
//alt type is 'suffix', 'prefix'
type: 'suffix',
word: 'prescription'
}
}
});
}
var my_div = document.getElementById('chart_div');
var my_chart = new google.visualization.ChartType(mywordtree);
google.visualization.events.addListener(my_chart, 'ready', function () {
mywordtree.innerHTML = '<img src="' + my_chart.getImageURI() + '">';
});
my_chart.draw(data);
</script>
</head>
<body style="font-family: Arial;border: 0 none;">
<div id="mywordtree" style="width: 1000px; height: 1000px;"></div>
</body>
</html>
first, in order to generate an image of the chart,
you need to wait for the chart's 'ready' event.
in order to wait for the 'ready' event,
you need access to the chart object.
you will not be able to use the google.visualization.drawChart method,
because it does not return a handle to the chart.
next, the WordTree chart, does not have a method for getImageURI,
so you will need to create the image manually, from a blob.
see following working snippet...
google.charts.load('current').then(function () {
// get chart container
var container = document.getElementById('mywordtree');
// create chart
var chart = new google.visualization.ChartWrapper({
chartType: 'WordTree',
containerId: container.id,
dataSourceUrl: 'https://docs.google.com/spreadsheets/d/1vi-YzV7s7eZ25938Q57DbZvT0iqggiCqRvDgxeZtP6c/edit?usp=sharing',
options: {
wordtree: {
format: 'implicit',
//alt type is 'suffix', 'prefix'
type: 'suffix',
word: 'prescription'
}
}
});
// listen for ready event
google.visualization.events.addListener(chart, 'ready', function () {
var domUrl; // object url
var image; // chart image
var imageUrl; // chart image url
var svg; // svg element
// add svg namespace to chart
svg = container.getElementsByTagName('svg')[0];
svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
// create image url from svg
domUrl = window.URL || window.webkitURL || window;
imageUrl = domUrl.createObjectURL(new Blob([svg.outerHTML], {type: 'image/svg+xml'}));
// create chart image
image = new Image();
image.onload = function() {
// replace chart with image
container.innerHTML = image.outerHTML;
}
image.src = imageUrl;
});
// draw chart
chart.draw();
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="mywordtree"></div>

move multiple images from one canvas to other canvas

There is an example given at http://www.rgraph.net/blog/2013/january/an-example-of-html5-canvas-drag-n-drop.html
I am not able to add multiple images into canvas 1 and move those added images to canvas 2. Also I should be able to drag(move the added image within canvas 2) those added images in second canvas.
function dragDrop(e, ui) {
// get the drop point (be sure to adjust for border)
var x = parseInt(ui.offset.left - offsetX) - 1;
var y = parseInt(ui.offset.top - offsetY);
// get the drop payload (here the payload is the $tools index)
var theIndex = ui.draggable.data("toolsIndex");
// drawImage at the drop point using the dropped image
ctx.drawImage($tools[theIndex], x, y, 32, 32);
}
http://jsfiddle.net/cyur7/
This jsfiddle link is working fine.
This solution uses the KineticJS library to accomplish your need.
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/bSpBF/
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.5.1.min.js"></script>
<style>
body{ background-color: ivory; padding:10px;}
#container1,#container2{
border:solid 1px #ccc;
margin-top: 10px;
width:300px;
height:100px;
}
#container2{
height:300px;
}
</style>
<script>
$(function(){
var highlightWidth=8;
var stage = new Kinetic.Stage({
container: 'container1',
width: 300,
height: 100
});
var layer = new Kinetic.Layer();
stage.add(layer);
var dropzone = new Kinetic.Stage({
container: 'container2',
width: 300,
height: 300
});
var dropLayer = new Kinetic.Layer();
dropzone.add(dropLayer);
// these must go after the creation of stages & layers
addBackground(stage,layer,dropLayer);
layer.draw();
addBackground(dropzone,dropLayer,layer);
dropLayer.draw();
// get images & then trigger start()
var images={};
var URLs = {
house1: 'https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-3.jpg',
house2: 'https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-4.jpg',
house3: 'https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-1.jpg'
};
loadImages(URLs,start);
function start(){
var house1=kImage(images.house1,10,10,50,50,layer);
var house2=kImage(images.house2,75,10,50,50,layer);
var house3=kImage(images.house3,140,10,50,50,layer);
layer.draw();
}
function swapStagesIfSelected(sourceLayer,destinationLayer,startX,startY){
// get all elements on the source layer
var elements=sourceLayer.get("Image");
// don't let dropped elements fall off the stage
var totalWidth=0;
var maxHeight=-999;
var layerWidth=destinationLayer.getStage().getWidth();
var layerHeight=destinationLayer.getStage().getHeight();
for(var i=0;i<elements.length;i++){
if(elements[i].isSelected){
totalWidth+=elements[i].getWidth();
maxHeight=Math.max(elements[i].getHeight(),maxHeight);
}
}
if(startX+totalWidth>layerWidth){
startX=layerWidth-totalWidth-15;
}
if(startY+maxHeight>layerHeight){
startY=layerHeight-maxHeight-15;
}
// move all selected images
// to the clicked x/y of the destination layer
for(var i=0;i<elements.length;i++){
var element=elements[i];
if(element.isSelected){
var img=element.getImage();
kImage(img,startX,startY,element.getWidth(),element.getHeight(),destinationLayer);
startX+=element.getWidth()+10;
element.remove();
}
}
sourceLayer.draw();
destinationLayer.draw();
}
// build the specified KineticJS Image and add it to the specified layer
function kImage(image,x,y,width,height,theLayer){
var image=new Kinetic.Image({
image:image,
x:x,
y:y,
width:width,
height:height,
strokeWidth:0.1,
stroke:"green",
draggable:true
});
image.myLayer=theLayer;
image.isSelected=false;
image.on("click",function(){
highlight(this);
this.myLayer.draw();
});
image.myLayer.add(image);
return(image);
}
// build a background image and add it to the specified stage
function addBackground(theStage,theLayer,otherLayer){
var background = new Kinetic.Rect({
x: 0,
y: 0,
width: theStage.getWidth(),
height: theStage.getHeight(),
fill: "white",
stroke: "green",
strokeWidth: 1
});
background.on("click",function(){
var pos=theStage.getMousePosition();
var mouseX=parseInt(pos.x);
var mouseY=parseInt(pos.y);
swapStagesIfSelected(otherLayer,theLayer,mouseX,mouseY);
});
theLayer.add(background);
}
///////////// Image loader
function loadImages(URLs, callback) {
var loaded = 0;
var needed = 0;
for(var url in URLs) { needed++; console.log(url); }
for(var url in URLs) {
images[url] = new Image();
images[url].onload = function() {
if(++loaded >= needed) {
callback(images);
}
};
images[url].src = URLs[url];
}
}
///////////// Toggle Highlighting
function highlight(element,setStrokeWidth){
if(setStrokeWidth){
element.setStrokeWidth(setStrokeWidth);
}else{
if(element.getStrokeWidth()>5){
element.setStrokeWidth(0.1);
element.isSelected=false;
}else{
element.setStrokeWidth(highlightWidth);
element.isSelected=true;
}
}
}
}); // end $(function(){});
</script>
</head>
<body>
<p>Click on image(s) to toggle selection</p>
<p>Then click in the other canvas to drop</p>
<div id="container1"></div>
<div id="container2"></div>
<button id="clear">Clear Hightlights</button>
<button id="swap">Swap Selected</button>
</body>
</html>

Google Maps JS API with KML layer control

I have found different solutions for switching KmlLayers on/off using JavaScript. All scripts that I've seen require separate functions for each layer, but I want to have only one function for all layers so when adding a new layer to my web page I don't have to edit the existing JavaScript code.
My code:
<!DOCTYPE html>
<html><head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no"/>
<style type="text/css">
* {margin:0; padding:0; border:0; outline:0; font-size:100%;
vertical-align:baseline}
html, body {width:100%; height:100%}
#map {width:100%; height:95%}
</style>
<script type="text/javascript"
src="http://maps.googleapis.com/maps/api/js?sensor=false&language=lv">
</script>
<script type="text/javascript">
var G = google.maps; var kml = null; var show = false;
function toggle() {
var tr = this.rel;
if (!tr) {
tr = new G.KmlLayer('http://www.eiranet.lv/kartes/Anjo/kmz/' +
this.id + '.kmz', {preserveViewport:true})
};
show = !show;
if (show) {
tr.setMap(map)
}
else {
tr.setMap(null)
};
};
function initialize() {
var layers = document.getElementsByTagName('input');
var options = {
center: new G.LatLng(34.9, 137.3),
zoom: 10,
mapTypeId: G.MapTypeId.TERRAIN,
scaleControl: true,
overviewMapControl: true,
mapTypeControlOptions: {
style:G.MapTypeControlStyle.DROPDOWN_MENU }
};
map = new G.Map(document.getElementById('map'), options);
for (var i=0; i<layers.length; i++) {
layers[i].type = 'checkbox';
G.event.addDomListener(layers[i], 'click', toggle)
};
};
G.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map"></div>
<input id="Didzis_21.03-03.04" rel="d1"/>
<input id="Didzis_04.04-17.04" rel="d2"/>
<input id="Didzis_18.04-01.05" rel="d3"/>
<input id="Didzis_02.05-15.05" rel="d4"/>
</body></html>
Here is my problem: actually I can switch multiple layers on but I can't turn them off. I think that all of the code is good except function toggle(). Also, it would be good if 'rel' attributes wouldn't be necessary, only 'id'.
It looks like each KmlLayer that you create gets orphaned; they are assigned to a function local var named tr, but then never assigned to anything that will remain available across multiple calls to toggle(). I suggest some changes to the toggle() function:
function toggle() {
if (!this.kmlLayer ) {
this.kmlLayer = new G.KmlLayer(
'http://www.eiranet.lv/kartes/Anjo/kmz/' + this.id + '.kmz',
{ preserveViewport:true } );
}
show = !show;
if (show) {
this.kmlLayer.setMap(map)
}
else {
this.kmlLayer.setMap(null)
};
};
After reviewing your page in some more detail, I suggest additional changes:
function toggle() {
if (!this.kmlLayer ) {
this.kmlLayer = new G.KmlLayer(
'http://www.eiranet.lv/kartes/Anjo/kmz/' + this.id + '.kmz',
{ preserveViewport:true } );
this.displayIsOn = false;
}
//show = !show; -- Remove this line, it is causing display state problems
if ( this.displayIsOn ) {
this.kmlLayer.setMap( null );
this.displayIsOn = false;
}
else {
this.kmlLayer.setMap( map );
this.displayIsOn = true;
};
};

Openlayers zoom in on cluster

Is it possible to zoom in on cluster on click? I also don't know how to disable cluster popup. I read this question , but still have no idea how to do it.
Here is the code:
<html>
<script src="../ol/OpenLayers.js"></script>
<script>
var map, select;
var lat = 53.507;
var lon = 28.145;
var zoom = 7;
function init() {
map = new OpenLayers.Map("map",
{ maxExtent: new OpenLayers.Bounds(-20037508.34,-20037508.34,20037508.34,20037508.34),
numZoomLevels: 19,
maxResolution: 156543.0399,
units: 'm',
projection: new OpenLayers.Projection("EPSG:900913"),
displayProjection: new OpenLayers.Projection("EPSG:4326"),
controls: [
new OpenLayers.Control.Navigation(),
new OpenLayers.Control.PanZoomBar(),
new OpenLayers.Control.ScaleLine(),
new OpenLayers.Control.Permalink('permalink'),
new OpenLayers.Control.Attribution(),
new OpenLayers.Control.MousePosition()
] });
var osm = new OpenLayers.Layer.OSM("OpenStreetMap");
map.addLayer(osm);
var lonLat = new OpenLayers.LonLat(lon, lat).transform(map.displayProjection, map.projection);
if (!map.getCenter()) map.setCenter (lonLat, zoom);
var MyStyle = new OpenLayers.Style({
// 'cursor' : 'pointer',
fillColor : "#336699",
fillOpacity : 0.9,
fontColor: "#000080",
fontFamily: "sans-serif, Arial",
// fontWeight: "bold",
externalGraphic: "atm.png",
graphicWidth: 32,
graphicHeight: 37,
label: "${count}",
labelAlign: "ct",
fontSize: "15px",
});
var layer = new OpenLayers.Layer.Vector("Atm", {
protocol: new OpenLayers.Protocol.HTTP({
url: "atm.txt",
format: new OpenLayers.Format.Text({extractStyles: true}),
params: {
extractAttributes: false,
}
}),
styleMap: MyStyle, <!-- --------------------- style -->
projection: map.displayProjection,
strategies: [
new OpenLayers.Strategy.BBOX({ratio: 1, resFactor: 1.1}),
new OpenLayers.Strategy.Cluster({distance: 50, threshold: 3})
]
});
map.addLayer(layer);
// Interaction; not needed for initial display.
selectControl = new OpenLayers.Control.SelectFeature(layer);
map.addControl(selectControl);
selectControl.activate();
layer.events.on({
'featureselected': onFeatureSelect,
'featureunselected': onFeatureUnselect
});
}
// Needed only for interaction, not for the display.
function onPopupClose(evt) {
// 'this' is the popup.
var feature = this.feature;
if (feature.layer) { // The feature is not destroyed
selectControl.unselect(feature);
} else { // After "moveend" or "refresh" events on POIs layer all
// features have been destroyed by the Strategy.BBOX
this.destroy();
}
}
function onFeatureSelect(evt) {
feature = evt.feature;
popup = new OpenLayers.Popup.FramedCloud("featurePopup",
feature.geometry.getBounds().getCenterLonLat(),
new OpenLayers.Size(100,100),
"<h2>"+feature.attributes.title + "</h2>" +
feature.attributes.description,
null, true, onPopupClose);
feature.popup = popup;
popup.feature = feature;
map.addPopup(popup, true);
}
function onFeatureUnselect(evt) {
feature = evt.feature;
if (feature.popup) {
popup.feature = null;
map.removePopup(feature.popup);
feature.popup.destroy();
feature.popup = null;
}
}
</script>
</head>
<body onload="init()">
<div id="map"></div>
</body>
</html>
Thanks. Your post does not have much context to explain the code sections; please explain your scenario more clearly.
function onFeatureSelect(event) {
if(!event.feature.cluster) // if not cluster
{
// handle your popup code for the individual feature
}
else
{
// fetch the cluster's latlon and set the map center to it and call zoomin function
// which takes you to a one level zoom in and I hope this solves your purpose :)
map.setCenter(event.feature.geometry.getBounds().getCenterLonLat());
map.zoomIn();
}
}
Using the example code in the linked question I would iterate over all features in the cluster to create a BBX, and then zoom into that extent.
var cluster_bounds=new OpenLayers.Bounds();
event.feature.cluster.forEach(function(feature){
clouster_bounds.extend(feature.geometry);
})
map.zoomToExtent(cluster_bounds)
If you really don't know how to disable the popups then remove these functions:
function onFeatureSelect(evt) {
function onFeatureUnselect(evt) {
And replace it with:
function onFeatureSelect(event) {
var cluster_bounds=new OpenLayers.Bounds();
event.feature.cluster.forEach(function(feature){
cluster_bounds.extend(feature.geometry);
});
map.zoomToExtent(cluster_bounds);
}