'use strict'; /*@ Ox.MapPlace <f> MapPlace Object (options) -> <o> MapPlace Object options <o> Options object east <n|0> editing <b|false> geoname <s|''> map <o|null> markerColor <a|[255> 0> 0]> markerSize <n|16> name <s|''> north <n|0> selected <b|false> south <n|0> type <s|''> visible <b|false> west <n|0> @*/ Ox.MapPlace = function(options) { options = Ox.extend({ east: 0, editing: false, geoname: '', map: null, name: '', north: 0, selected: false, south: 0, type: '', visible: false, west: 0 }, options); var that = this; Ox.forEach(options, function(val, key) { that[key] = val; }); update(); function update(updateMarker) { that.points = { ne: new google.maps.LatLng(that.north, that.east), sw: new google.maps.LatLng(that.south, that.west) }; that.bounds = new google.maps.LatLngBounds(that.points.sw, that.points.ne); that.center = that.bounds.getCenter(); that.lat = that.center.lat(); that.lng = that.center.lng(); Ox.extend(that.points, { e: new google.maps.LatLng(that.lat, that.east), s: new google.maps.LatLng(that.south, that.lng), se: new google.maps.LatLng(that.south, that.east), n: new google.maps.LatLng(that.north, that.lng), nw: new google.maps.LatLng(that.north, that.west), w: new google.maps.LatLng(that.lat, that.west) }); // fixme: use bounds.toSpan() that.sizeNorthSouth = (that.north - that.south) * Ox.EARTH_CIRCUMFERENCE / 360; that.sizeEastWest = (that.east + (that.west > that.east ? 360 : 0) - that.west) * Ox.getMetersPerDegree(that.lat); that.area = Ox.getArea( {lat: that.south, lng: that.west}, {lat: that.north, lng: that.east} ); if (!that.marker) { that.marker = new Ox.MapMarker({ map: that.map, place: that }); that.rectangle = new Ox.MapRectangle({ map: that.map, place: that }); } else if (updateMarker) { that.marker.update(); that.rectangle.update(); } } function editable() { return that.map.options('editable') && that.editable; } /*@ add <f> add @*/ that.add = function() { that.visible = true; that.marker.add(); return that; }; /*@ cancel <f> cancel @*/ that.cancel = function() { if (editable()) { that.undo(); that.editing = false; that.marker.update(); that.rectangle.deselect(); } return that; }; /*@ crossesDateline <f> crossesDateline @*/ that.crossesDateline = function() { return that.west > that.east; } /*@ deselect <f> dselect @*/ that.deselect = function() { that.editing && that.submit(); that.selected = false; that.marker.update(); that.rectangle.remove(); return that; }; /*@ edit <f> edit @*/ that.edit = function() { if (editable()) { that.editing = true; that.original = { south: that.south, west: that.west, north: that.north, east: that.east }; that.marker.edit(); that.rectangle.select(); } return that; }; // fixme: make this an Ox.Element to get options handling for free? that.options = function(options) { options = Ox.makeObject(arguments); Ox.forEach(options, function(value, key) { that[key] = value; }); update(true); }; /*@ remove <f> remove @*/ that.remove = function() { that.editing && that.submit(); that.selected && that.deselect(); that.visible = false; that.marker.remove(); return that; }; /*@ select <f> select @*/ that.select = function() { that.selected = true; !that.visible && that.add(); that.marker.update(); that.rectangle.add(); return that; }; /*@ submit <f> submit @*/ that.submit = function() { if (editable()) { that.editing = false; that.marker.update(); that.rectangle.deselect(); } return that; }; /*@ update <f> update @*/ that.update = function(updateMarker) { update(updateMarker); that.map.triggerEvent('changeplace', that); return that; }; /*@ undo <f> undo @*/ that.undo = function() { if (editable()) { Ox.forEach(that.original, function(v, k) { that[k] = v; }); that.update(); that.marker.update(); that.rectangle.update(); } return that; }; return that; };