####################################################################################################### ############################################## Open Layers ########################################## ####################################################################################################### #// http://wiki.openstreetmap.org/wiki/OpenLayers #// http://openlayers.org/dev/examples #//http://docs.openlayers.org/contents.html class @Gmaps4RailsOpenlayers extends Gmaps4Rails constructor: -> super @map_options = {} @mergeWithDefault "map_options" @markers_conf = {} @mergeWithDefault "markers_conf" @openMarkers = null @markersLayer = null @markersControl = null #//////////////////////////////////////////////////// #/////////////// Basic Objects //////////////////// #//////////////////////////////////////////////////// createPoint: (lat, lng)-> createLatLng: (lat, lng)-> return new OpenLayers.LonLat(lng, lat).transform(new OpenLayers.Projection("EPSG:4326"), new OpenLayers.Projection("EPSG:900913")) # transform from WGS 1984 to Spherical Mercator Projection createAnchor: (offset)-> return null if offset == null return new OpenLayers.Pixel(offset[0], offset[1]) createSize: (width, height)-> return new OpenLayers.Size(width, height) createLatLngBounds: -> return new OpenLayers.Bounds() createMap: -> #//todo add customization: kind of map and other map options map = new OpenLayers.Map(@map_options.id) map.addLayer(new OpenLayers.Layer.OSM()) map.setCenter(@createLatLng(@map_options.center_latitude, @map_options.center_longitude), #// Center of the map @map_options.zoom) #// Zoom level return map #//////////////////////////////////////////////////// #////////////////////// Markers ///////////////////// #//////////////////////////////////////////////////// #//http://openlayers.org/dev/examples/marker-shadow.html createMarker: (args) -> style_mark = OpenLayers.Util.extend({}, OpenLayers.Feature.Vector.style['default']) style_mark.fillOpacity = 1 #//creating markers' dedicated layer if (@markersLayer == null) @markersLayer = new OpenLayers.Layer.Vector("Markers", null) @map.addLayer(@markersLayer) #//TODO move? @markersLayer.events.register("featureselected", @markersLayer, @onFeatureSelect) @markersLayer.events.register("featureunselected", @markersLayer, @onFeatureUnselect) @markersControl = new OpenLayers.Control.SelectFeature(@markersLayer) @map.addControl(@markersControl) @markersControl.activate() #//showing default pic if none available if args.marker_picture == "" #style_mark.graphicWidth = 24 style_mark.graphicHeight = 30 style_mark.externalGraphic = "http://openlayers.org/dev/img/marker-blue.png" #//creating custom pic else style_mark.graphicWidth = args.marker_width style_mark.graphicHeight = args.marker_height style_mark.externalGraphic = args.marker_picture #//adding anchor if any if args.marker_anchor != null style_mark.graphicXOffset = args.marker_anchor[0] style_mark.graphicYOffset = args.marker_anchor[1] #//adding shadow if any if args.shadow_picture != "" style_mark.backgroundGraphic = args.shadow_picture style_mark.backgroundWidth = args.shadow_width style_mark.backgroundHeight = args.shadow_height #//adding shadow's anchor if any if args.shadow_anchor != null style_mark.backgroundXOffset = args.shadow_anchor[0] style_mark.backgroundYOffset = args.shadow_anchor[1] style_mark.graphicTitle = args.title marker = new OpenLayers.Feature.Vector( new OpenLayers.Geometry.Point(args.Lng, args.Lat), null, style_mark) #//changing coordinates so that it actually appears on the map! marker.geometry.transform(new OpenLayers.Projection("EPSG:4326"), new OpenLayers.Projection("EPSG:900913")) #//adding layer to the map @markersLayer.addFeatures([marker]) return marker #//clear markers clearMarkers: -> @clearMarkersLayerIfExists() @markersLayer = null @boundsObject = new OpenLayers.Bounds() clearMarkersLayerIfExists: -> this.map.removeLayer(this.markersLayer) if @markersLayer != null and @map.getLayer(@markersLayer.id) != null extendBoundsWithMarkers: -> for marker in @markers @boundsObject.extend(@createLatLng(marker.lat,marker.lng)) #//////////////////////////////////////////////////// #/////////////////// Clusterer ////////////////////// #//////////////////////////////////////////////////// #//too ugly to be considered valid :( createClusterer: (markers_array)-> options = pointRadius: "${radius}" fillColor: "#ffcc66" fillOpacity: 0.8 strokeColor: "#cc6633" strokeWidth: "${width}" strokeOpacity: 0.8 funcs = context: width: (feature) -> return (feature.cluster) ? 2 : 1 radius: (feature) -> pix = 2 pix = Math.min(feature.attributes.count, 7) + 2 if feature.cluster return pix style = new OpenLayers.Style options, funcs strategy = new OpenLayers.Strategy.Cluster() clusters = new OpenLayers.Layer.Vector "Clusters", strategies: [strategy] styleMap: new OpenLayers.StyleMap "default": style "select": fillColor: "#8aeeef" strokeColor: "#32a8a9" @clearMarkersLayerIfExists() @map.addLayer(clusters) clusters.addFeatures(markers_array) return clusters clusterize: -> if @markers_conf.do_clustering == true #//first clear the existing clusterer if any if @markerClusterer != null @clearClusterer() markers_array = new Array for marker in markers markers_array.push(marker.serviceObject) @markerClusterer = @createClusterer markers_array clearClusterer: -> @map.removeLayer @markerClusterer #//////////////////////////////////////////////////// #/////////////////// INFO WINDOW //////////////////// #//////////////////////////////////////////////////// #// creates infowindows createInfoWindow: -> (marker_container) -> if marker_container.description? marker_container.serviceObject.infoWindow = marker_container.description onPopupClose: (evt) -> #// 'this' is the popup. @markersControl.unselect @feature onFeatureSelect: (evt) -> feature = evt.feature popup = new OpenLayers.Popup.FramedCloud("featurePopup", feature.geometry.getBounds().getCenterLonLat(), new OpenLayers.Size(300,200), feature.infoWindow, null, true, @onPopupClose) feature.popup = popup popup.feature = feature @map.addPopup popup onFeatureUnselect: (evt) -> feature = evt.feature if feature.popup #//popup.feature = null; @map.removePopup feature.popup feature.popup.destroy() feature.popup = null # #//////////////////////////////////////////////////// # #/////////////////// Other methods ////////////////// # #//////////////////////////////////////////////////// fitBounds: -> @map.zoomToExtent(@boundsObject, true) centerMapOnUser: -> @map.setCenter @userLocation