diff --git a/source/Ox.UI/js/Map/Ox.Map.js b/source/Ox.UI/js/Map/Ox.Map.js index 24774963..90e5e2f4 100644 --- a/source/Ox.UI/js/Map/Ox.Map.js +++ b/source/Ox.UI/js/Map/Ox.Map.js @@ -18,6 +18,9 @@ Ox.Map Basic map object editable If true, places are editable find Initial query findPlaceholder Placeholder text for the find input element + keys Additional place properties to be requested + markerColor <[n]|f|s|'auto'> Color of place markers ([r, g, b]) + markerSize Size of place markers in px maxMarkers Maximum number of markers to be displayed places <[o]|f|null> Array of, or function that returns, place objects countryCode ISO 3166 country code @@ -26,8 +29,6 @@ Ox.Map Basic map object geoname Geoname (like "Paris, Île-de-France, France") lat Latitude in degrees lng Longitude in degrees - markerColor CSS color of the place marker - markerSize size of the place marker in px name Name (like "Paris") north Latitude of the northern boundary in degrees south Latitude of the southern boundary in degrees @@ -36,10 +37,9 @@ Ox.Map Basic map object selected Id of the selected place showControls If true, show controls showLabels If true, show labels on the map - showTypes If true, color markers according to place type - statusbar If true, the map has a statusbar - toolbar If true, the map has a toolbar - zoombar If true, the map has a zoombar + showStatusbar If true, the map has a statusbar + showToolbar If true, the map has a toolbar + showZoombar If true, the map has a zoombar zoomOnlyWhenFocused If true, scroll-zoom only when focused self Shared private variable # EVENTS ------------------------------------------------------------------- @@ -98,20 +98,22 @@ Ox.Map = function(options, self) { self = self || {}; var that = Ox.Element({}, self) .defaults({ - // fixme: isClickable? hasZoombar? + // fixme: isClickable? clickable: false, editable: false, find: '', findPlaceholder: 'Find', + keys: [], + markerColor: 'auto', + markerSize: 'auto', maxMarkers: 100, places: null, selected: '', showControls: false, showLabels: false, - showTypes: false, - statusbar: false, // FIXME: showStatusbar - toolbar: false, // FIXME: showToolbar - zoombar: false, // FIXME: showZoombar + showStatusbar: false, + showToolbar: false, + showZoombar: false, zoomOnlyWhenFocused: false // fixme: width, height }) @@ -192,15 +194,30 @@ Ox.Map = function(options, self) { } }); - self.isAsync = Ox.isFunction(self.options.places); + // HANDLE DEPRECATED OPTIONS + ['statusbar', 'toolbar', 'zoombar'].forEach(function(key) { + if (options[key]) { + self.options['show' + Ox.toTitleCase(key)] = options[key]; + } + }); + + if (Ox.isArray(self.options.places)) { + self.options.places.forEach(function(place) { + if (Ox.isUndefined(place.id)) { + place.id = Ox.encodeBase32(Ox.uid()); + } + }); + self.options.places = Ox.api(self.options.places, {geo: true}); + } + self.mapHeight = getMapHeight(); self.metaKey = false; self.minZoom = getMinZoom(); - self.placeKeys = [ + self.placeKeys = Ox.merge([ 'id', 'name', 'alternativeNames', 'geoname', 'countryCode', 'type', 'lat', 'lng', 'south', 'west', 'north', 'east', 'area', 'editable' - ]; + ], self.options.keys); self.resultPlace = null; self.scaleMeters = [ 50000000, 20000000, 10000000, @@ -213,7 +230,7 @@ Ox.Map = function(options, self) { ]; self.shiftKey = false; - if (self.options.toolbar) { + if (self.options.showToolbar) { self.$toolbar = Ox.Bar({ size: 24 }) @@ -275,23 +292,23 @@ Ox.Map = function(options, self) { self.$map = Ox.Element() .css({ left: 0, - top: self.options.toolbar * 24 + 'px', + top: self.options.showToolbar * 24 + 'px', right: 0, - bottom: self.options.zoombar * 16 + self.options.statusbar * 24 + 'px' + bottom: self.options.showZoombar * 16 + self.options.showStatusbar * 24 + 'px' }) .appendTo(that); - if (self.options.zoombar) { + if (self.options.showZoombar) { self.$zoombar = Ox.Bar({ size: 16 }) .css({ - bottom: self.options.statusbar * 24 + 'px' + bottom: self.options.showStatusbar * 24 + 'px' }) .appendTo(that); } - if (self.options.statusbar) { + if (self.options.showStatusbar) { self.$statusbar = Ox.Bar({ size: 24 }) @@ -438,14 +455,6 @@ Ox.Map = function(options, self) { $placeControl.css({opacity: 0}).hide(); }); - if (!self.isAsync) { - self.options.places.forEach(function(place) { - if (Ox.isUndefined(place.id)) { - place.id = Ox.encodeBase32(Ox.uid()); - } - }); - } - if (window.google) { initMap(); } else if (window.googleCallback) { @@ -471,6 +480,7 @@ Ox.Map = function(options, self) { place.remove(); }); self.places = []; + /* if (!self.isAsync) { self.options.places.forEach(function(place) { self.places.push(new Ox.MapPlace(Ox.extend({ @@ -478,6 +488,7 @@ Ox.Map = function(options, self) { }, place))); }); } + */ } function addPlaceToMap(place) { @@ -590,7 +601,7 @@ Ox.Map = function(options, self) { } function constructZoomInput() { - if (self.options.zoombar) { + if (self.options.showZoombar) { self.$zoomInput && self.$zoomInput.remove(); self.$zoomInput = Ox.Range({ arrows: true, @@ -634,31 +645,20 @@ Ox.Map = function(options, self) { function getMapBounds(callback) { // get initial map bounds - var mapBounds; - if (!self.isAsync) { - self.options.places.forEach(function(place, i) { - var bounds = getBounds(place); - mapBounds = i == 0 ? bounds : mapBounds.union(bounds); - }); - callback(mapBounds); - } else { - self.options.places({}, function(result) { - callback(getBounds(result.data.area)); - }); - } - function getBounds(place) { - return new google.maps.LatLngBounds( - new google.maps.LatLng(place.south, place.west), - new google.maps.LatLng(place.north, place.east) - ); - } + self.options.places({}, function(result) { + var area = result.data.area; + callback(new google.maps.LatLngBounds( + new google.maps.LatLng(area.south, area.west), + new google.maps.LatLng(area.north, area.east) + )); + }); } function getMapHeight() { return self.options.height - - self.options.statusbar * 24 - - self.options.toolbar * 24 - - self.options.zoombar * 16; + - self.options.showStatusbar * 24 + - self.options.showToolbar * 24 + - self.options.showZoombar * 16; } function getMapType() { @@ -916,67 +916,47 @@ Ox.Map = function(options, self) { west = southWest.lng(), north = northEast.lat(), east = northEast.lng(); - if (!self.isAsync) { - self.places.sort(function(a, b) { - var sort = { - a: a.selected ? Infinity - : bounds.contains(a.center) ? a.area - : -Infinity, - b: b.selected ? Infinity - : bounds.contains(b.center) ? b.area - : -Infinity, - }; - return sort.b - sort.a; - }).forEach(function(place, i) { - if (i < self.options.maxMarkers && !place.visible) { + self.options.places({ + keys: self.placeKeys, + query: { + conditions: Ox.merge([ + {key: 'lat', value: [south, north], operator: '='} + ], spansGlobe() ? [ + {key: 'lng', value: [-180, 180], operator: '='} + ] : crossesDateline() ? [ + {key: 'lng', value: [east, west], operator: '!='} + ] : [ + {key: 'lng', value: [west, east], operator: '='} + ]), + operator: '&' + }, + range: [0, self.options.maxMarkers], + sort: [{key: 'area', operator: '-'}] + }, function(result) { + Ox.Log('Map', 'RESULT', result) + var ids = []; + result.data.items.forEach(function(item, i) { + var place = getPlaceById(item.id); + if (!place) { + self.places.push( + new Ox.MapPlace(Ox.extend({ + map: that + }, item)).add() + ); + } else if (!place.visible) { place.add(); - } else if (i >= self.options.maxMarkers && place.visible) { + } + ids.push(item.id); + }); + self.places.forEach(function(place) { + if ( + !place.selected && place.visible + && ids.indexOf(place.id) == -1 + ) { place.remove(); } }); - } else { - self.options.places({ - keys: self.placeKeys, - query: { - conditions: Ox.merge([ - {key: 'lat', value: [south, north], operator: '='} - ], spansGlobe() ? [ - {key: 'lng', value: [-180, 180], operator: '='} - ] : crossesDateline() ? [ - {key: 'lng', value: [east, west], operator: '!='} - ] : [ - {key: 'lng', value: [west, east], operator: '='} - ]), - operator: '&' - }, - range: [0, self.options.maxMarkers], - sort: [{key: 'area', operator: '-'}] - }, function(result) { - Ox.Log('Map', 'RESULT', result) - var ids = []; - result.data.items.forEach(function(item, i) { - var place = getPlaceById(item.id); - if (!place) { - self.places.push( - new Ox.MapPlace(Ox.extend({ - map: that - }, item)).add() - ); - } else if (!place.visible) { - place.add(); - } - ids.push(item.id); - }); - self.places.forEach(function(place) { - if ( - !place.selected && place.visible - && ids.indexOf(place.id) == -1 - ) { - place.remove(); - } - }); - }); - } + }); self.boundsChanged = false; } if (self.centerChanged) { @@ -1189,13 +1169,12 @@ Ox.Map = function(options, self) { } } function select() { - //Ox.print('select...', place) place && place.select(); self.options.selected = id; setPlaceControls(place); setStatus(); - that.triggerEvent('selectplace', place); - // FIXME: all these events should rather pass {place: place} + that.triggerEvent('selectplace', place); // DEPRECATED + that.triggerEvent('select', {place: place}); } }; @@ -1222,8 +1201,9 @@ Ox.Map = function(options, self) { function setScale() { var metersPerPixel = getMetersPerPixel(); Ox.forEach(self.scaleMeters, function(meters) { - var scaleWidth = Math.round(meters / metersPerPixel); - if (scaleWidth <= self.options.width / 2 - 4) { + var mapWidth = self.options.width || that.width(), + scaleWidth = Math.round(meters / metersPerPixel); + if (scaleWidth <= mapWidth / 2 - 4) { self.$controls.scale .options({ title: '\u2190 ' + ( @@ -1241,7 +1221,7 @@ Ox.Map = function(options, self) { function setStatus() { //Ox.Log('Map', 'setStatus()', self.options.selected) var code, country, disabled, place, title; - if (self.options.statusbar) { + if (self.options.showStatusbar) { place = getSelectedPlace(); country = place ? Ox.getCountryByGeoname(place.geoname) : ''; code = country ? country.code : 'NTHH'; @@ -1355,13 +1335,13 @@ Ox.Map = function(options, self) { function updateFormElements() { var width = that.width(); - if (self.options.zoombar) { + if (self.options.showZoombar) { getMaxZoom(function(zoom) { self.maxZoom = zoom; constructZoomInput(); }); } - if (self.options.statusbar) { + if (self.options.showStatusbar) { self.$placeNameInput.options({ width: Math.floor((width - 132) / 2) }); @@ -1404,8 +1384,6 @@ Ox.Map = function(options, self) { that.$element.css(key, value + 'px'); that.resizeMap(); } else if (key == 'places') { - // fixme: assumes !self.isAsync - //Ox.print('MAP SET OPTIONS PLACES', value); addPlaces(); getMapBounds(function(mapBounds) { if (mapBounds) { @@ -1483,8 +1461,8 @@ Ox.Map = function(options, self) { that.resizeMap = function() { // keep center on resize has been commented out // var center = self.map.getCenter(); - self.options.height = that.$element.height(); - self.options.width = that.$element.width(); + self.options.height = that.height(); + self.options.width = that.width(); // check if map has initialized if (self.map) { self.mapHeight = getMapHeight(); @@ -1496,7 +1474,7 @@ Ox.Map = function(options, self) { height: self.mapHeight + 'px', width: self.options.width + 'px' }); - self.options.zoombar && self.$zoomInput.options({ + self.options.showZoombar && self.$zoomInput.options({ size: self.options.width }); updateFormElements();