I developed a canvas visualization of OpenStreetMaps by means of miscellaneous scripts and rendering algorithms from the internet. On top of this I have a Kinetic Stage which draws custom objects which cannot be drawn by the functionality of Openlayers.
Openlayers provides many functions which I want to use and therefore I’m trying to switch over to this framework. I’m currently stuck with the event propagation, because I don’t know how to propagate an event to Openlayers.
index.html
<div id="canvasdiv"> <div id="KineticDiv"> </div> <div id="OLMapDiv"> </div> </div>
style.css
#KineticDiv { position: absolute; z-index: 1000; } #OLMapDiv { position: absolute; width: 1000px; height: 600px; z-index: 0; }
ol.js
function OpenLayersMap(divname) { var osmLayer = new OpenLayers.Layer.OSM("Open Street Maps", ["http://a.tile.openstreetmap.org/${z}/${x}/${y}.png", "http://b.tile.openstreetmap.org/${z}/${x}/${y}.png", "http://c.tile.openstreetmap.org/${z}/${x}/${y}.png"]); ]); var gmLayer = new OpenLayers.Layer.Google("Google Maps"); var proj = new OpenLayers.Projection("EPSG:4326"); OpenLayers.ImgPath = "/static/img/"; this.map = new OpenLayers.Map({ div: divname, allOverlays: false, theme: null, controls: [ new OpenLayers.Control.Attribution(), new OpenLayers.Control.Navigation(), new OpenLayers.Control.LayerSwitcher(), new OpenLayers.Control.PanZoomBar(), new OpenLayers.Control.ScaleLine(), new OpenLayers.Control.MousePosition({ displayProjection: proj }), new OpenLayers.Control.KeyboardDefaults() ] }); this.map.addLayers([osmLayer, gmLayer]); this.map.setCenter( new OpenLayers.LonLat(8.56, 50).transform(proj, this.map.getProjectionObject()), 10 ); } OpenLayersMap.prototype = { constructor: OpenLayersMap }
main.js
function main() { var self = this; this.olmap = new OpenLayersMap("OLMapDiv"); this.kinetic = new KineticStage("KineticDiv"); $("div#canvasdiv").bind("mouseout", function(event){ // TODO self.olmap.mouseOut(event); }).bind("mouseup", function(event){ // TODO self.olmap.mouseUp(event); }).bind("mousedown", function(event){ // TODO self.olmap.mouseDown(event); }).bind("mousewheel", function(event, delta){ // TODO self.olmap.mouseWheel(event, delta); }).bind("touchmove", function(event){ // TODO self.olmap.touchMove(event); }).bind("touchstart", function(event){ // TODO self.olmap.touchStart(event); }).bind("touchend", function(event){ // TODO self.olmap.touchEnd(event); }); }
Due to a higher z-index of the Kinetic Stage the event is recognized there. The event propagation is only stopped if a Kinetic Shape is hit!
Is there any suitable method in Openlayers which accepts events? (I found OpenLayers.Events.triggerEvent, but I didn’t succeed with it)
Advertisement
Answer
I came up with a solution which is almost satisfying. Only a few events have to be handled by the user. Replacing the TODO’s with
self.olmap.map.events.handleBrowserEvent(event);
enables the drag&drop function on the map. Here is an example how to handle the mousewheel event:
// main.js $("div#canvasdiv").bind("mousewheel", function(event, delta){ self.olmap.zoom(event, delta); }) // ol.js zoom : function(event, delta) { if(this.zoomExpireTime && this.zoomExpireTime == 0) { this.zoomExpireTime = event.timeStamp - 1; } if(this.zoomExpireTime < event.timeStamp) { this.map.zoomTo(this.map.getZoom() + delta); this.zoomExpireTime = event.timeStamp + 500; } }
The controls of OpenLayers cannot be used, because they only react on click events and not on mousedown ones. I tried to convert the mousedown event to a click one, but then the drag&drop didn’t work anymore. Thus, I did a workaround which raises only the controls to the top as follows:
var z = parseInt($("div#KineticDiv").css("z-index")) + 100; $("div[id=OpenLayers\.Control\.LayerSwitcher_8]").css("z-index", z); $("div[id=OpenLayers\.Control\.LayerSwitcher_8]").appendTo($("div#canvasdiv")); $("div[id=OpenLayers\.Control\.PanZoomBar_9]").css("z-index", z); $("div[id=OpenLayers\.Control\.PanZoomBar_9]").appendTo($("div#canvasdiv"));
So this is my first scratch solution, but I think there is potential to improve it …