/*********************************
*** Class: PPolyCreatorOptions ***
*********************************/
PPolyCreatorOptions = function() {
this.icon = new PIcon();
this.icon.image = PEnvironment.kamapUrl + "images/icon_polypoint.gif";
this.icon.iconSize = new PSize(10,10);
this.icon.shadowSize = new PSize(0,0);
this.icon.iconAnchor = new PPoint(5,5);
this.line = new Object();
this.line.color = "#999999";
this.line.weight = 4;
this.line.opacity = 0.7;
this.poly = new Object();
this.poly.color = "#eb5920";
this.poly.weight = 4;
this.poly.opacity = 0.7;
this.poly.fill = "#eb7041";
// add more options later
}
var polycreatorurl = "http://pin.gis.policymap.com";
/**************************
*** Class: PPolyCreator ***
**************************/
PPolyCreator = function(options) {
if (options)
this.options = options;
else
this.options = new PPolyCreatorOptions();
this.click = null;
this.points = [];
this.savePoints = [];
//this.places = [];
//this.radius = null;
//this.allPolylines = [];
this.polyline = null;
this.name = null;
this.description = null;
// This array will keep track of all the overlays added to the map that are used for building the region
// So either the markers and polylines used for drawing an overlay, or the polygons used in assembling, or the marker and polygon for radius
this.buildingOverlays = [];
this.eventTypes = new Object();
this.eventTypes.addpoly = 'addpoly';
this.eventTypes.savepoly = 'savepoly';
this.eventTypes.saveAssembledPoly = 'saveassemblepoly';
this.eventTypes.saveCirclePoly = 'savecirclepoly';
this.eventTypes.removepoly = 'removepoly';
this.eventManager = new _eventManager();
for (var ev in this.eventTypes)
this.eventManager.registerEventID(ev);
this.buildType = null;
// 3 different type of custom regions that you can build
// each type has an object to keep track of the required data
this.DRAW = {};
this.DRAW.title = 'Show Boundaries in Region:';
this.DRAW.regions = {}; // keeps track of all drawn regions
this.DRAW.ctypeid = '1';
this.ASSEMBLE = {};
this.ASSEMBLE.title = 'Select Areas on the Map By:';
this.ASSEMBLE.polygons = []; // used to keep track of the polygons as they're being added
this.ASSEMBLE.places = [];
this.ASSEMBLE.placeids = [];
this.ASSEMBLE.ctypeid = '2';
this.CIRCLE = {};
this.CIRCLE.title = 'Show Boundaries in Region:';
this.CIRCLE.centerpoint = null;
this.CIRCLE.address = null;
this.CIRCLE.radius = null;
this.CIRCLE.ctypeid = '3';
// keeps track of the custom places place objects and polygons as they're added to the map
// this way we can remove the polygons and also keep track of each place so when using getPlacesWithin we have the right info
this.customPlacesOnMap = {};
this.customPlacesCount = 0;
// keeps track of the polygons that are shown within the custom places so we know which overlays to remove when user clears the polygons within
this.polygonsWithin = [];
}
PPolyCreator.prototype.addListener = function(eventId, func) {
this.eventManager.registerForEvent(eventId, [], func);
}
PPolyCreator.prototype.removeListener = function(eventId, func) {
this.eventManager.deregisterForEvent(eventId, [], func);
}
PPolyCreator.prototype.attachMap = function(map) {
this.map = map;
this.initCustomRegionType();
}
PPolyCreator.prototype.detachMap = function() {
if (this.map && this.click)
this.map.removeListener(this.click);
}
PPolyCreator.prototype.cancelPoly = function(stillBuilding) {
if (!stillBuilding)
this.resetBuildType();
this.resetBuildOptions();
//this.map.clearOverlays();
this.clearBuildingOverlays();
//this.detachMap();
// since same widget is used for assembling and showing places within
// we need to re-populate the boundaryWidget so it resets to the places within version
this.boundaryWidget.populate();
}
// clear only the overlays for the custom region that's in the process of being built
PPolyCreator.prototype.clearBuildingOverlays = function() {
var overlays = this.buildingOverlays;
for (var i=0; i 1) {
var polyline = new PPolyline([point,this.points[this.points.length-2]],this.options.line.color,this.options.line.weight,this.options.line.opacity);
this.buildingOverlays.push(polyline);
this.map.addOverlay(polyline);
}
}
}
PPolyCreator.prototype.saveDrawPoly = function() {
// ensure polygon and closed
if (this.savePoints.length < 3) return;
if (!this.savePoints[0].equals(this.savePoints[this.savePoints.length-1]))
this.savePoints.push(this.savePoints[0]);
//map.clearOverlays();
this.clearBuildingOverlays();
// send to servlet
var query = "&vtc=MULTIPOLYGON(((";
for (var i=0; i";
html += "Save Region";
html += "";
polycreator.map.openInfoWindowHtml(point, html);
*/
assverts.push(verts[i]);
place.savedPolys.push(polygon);
// Only store the place once all polygons are drawn so it doesn't duplicate
if (i==verts.length-1)
assplaces.push(place);
// update info displayed
polycreator.assembleInfoWidget.update();
}
});
}
PPolyCreator.prototype.showSaveInfoWindow = function(point) {
var polycreator = this;
if (this.buildType == this.DRAW) {
var html = "
";
html += "Name: ";
html += "Description:
";
html += " ";
html += "";
html += "
";
var icon = new PIcon(PIcon.POINT);
icon.iconSize = new PSize(12,12);
icon.shadow = "";
icon.image = 'images/pins/polygon_red.png';
var marker = new PMarker(point, icon);
marker.image.point = point;
PEvent.addListener(marker, "click", function() {
polycreator.showSaveInfoWindow(this.point);
});
this.buildingOverlays.push(marker);
this.map.addOverlay(marker);
marker.openInfoWindowHtml(html);
this.points = [];
}
else if (this.buildType == this.ASSEMBLE) {
// don't allow if only one place is used
if (this.ASSEMBLE.places.length < 2) {
customAlert("You need more than one place to create this type of custom regions. Select another place and then click save region again.");
return;
}
var html = "
";
html += "Name: ";
html += "Description:
";
html += " ";
html += "";
html += "
";
this.map.openInfoWindowHtml(point, html);
}
else if (this.buildType == this.CIRCLE) {
var html = "
";
html += "Name: ";
html += "Description:
";
html += " ";
html += "";
html += "
";
var icon = new PIcon(PIcon.POINT);
icon.iconSize = new PSize(12,12);
icon.shadow = "";
icon.image = 'images/pins/polygon_red.png';
var marker = new PMarker(point, icon);
marker.image.point = point;
PEvent.addListener(marker, "click", function() {
polycreator.showSaveInfoWindow(this.point);
});
this.buildingOverlays.push(marker);
this.map.addOverlay(marker);
marker.openInfoWindowHtml(html);
this.points = [];
}
}
PPolyCreator.prototype.resetType = function() {
this.ASSEMBLE.verts = [];
this.ASSEMBLE.places = [];
// Clear all the polygons added with assembling if there are any
var polygons = this.ASSEMBLE.polygons;
for (var i=0; i 0)
return true;
else
return false;
}
PPolyCreator.prototype.toggleWidgets = function() {
// hide the circle and assembe widgets
this.circleWidget.hide();
this.assembleInfoWidget.hide();
// Note: put this in the if statement below when showing places within custom regions is added back to the app
// There are a few places in MapCommon.js that need to be uncommented out, all are noted just as is it is here
this.boundaryWidget.hide();
// clear and remove widget related things if no custom regions are on map
if (!this.customRegionsOn()) {
this.clearPolygonsWithin();
this.clearBuildingOverlays();
}
}
PPolyCreator.prototype.addPlacesWithinAllRegions = function(type) {
// clear all the polygons everytime type is changed
this.clearPolygonsWithin();
var count = this.getCustomPlacesCount();
var places = this.customPlacesOnMap;
if (count > 0) {
for (var i in places) {
this.showPlacesWithin(places[i].place, type);
}
}
}
PPolyCreator.prototype.showPlacesWithin = function(place, type) {
var polycreator = this;
// get all the places within and add polygons for each
place.getPlacesWithin(type, function(places) {
for (var i=0; i 0) {
for (var i=0; i 0) ? true : false;
}
/********************************************
***** Class: PPolyCreatorBoundaryWidget *****
********************************************/
// This widget is to show the boundaries within the custom regions
// And also is used in the assemble option to select what placetype to use when assembling
PPolyCreatorBoundaryWidget = function(polycreator) {
this.polycreator = polycreator;
this.listeners = []; // keeps track of the events added to the dropdown so we can remove them
var container = document.createElement('div');
this.container = container;
container.id = 'PolyBoundaryWidget';
container.className = 'CustomRegionWidgets';
jQuery("#map").append(container);
var div = document.createElement('div');
div.className = 'title';
this.titleContainer = div;
this.defaultTitle = 'Show Boundaries in Region:';
this.container.appendChild(div);
var select = document.createElement('select');
select.className = 'boundaries';
select.disabled = true;
this.container.appendChild(select);
this.typeMenu = select;
}
PPolyCreatorBoundaryWidget.prototype = {
enable : function() {
this.typeMenu.disabled = false;
},
disable : function() {
this.typeMenu.disabled = true;
},
show : function() {
this.populate();
this.container.style.display = "block";
},
hide : function() {
this.container.style.display = "none";
},
addTitle : function() {
if (this.polycreator.isBuildOn())
this.titleContainer.innerHTML = this.polycreator.buildType.title;
else
this.titleContainer.innerHTML = this.defaultTitle;
},
populate : function() {
for (var i=0; i= 0; i--) {
ptype = PPlaceTypeConfig.PLEGEND.zooms[i];
if (ptype) {
if (ptype.id) {
break;
}
}
}
}
for (var i=0; i", " ");
var label = this.maplayers[0].getLabel().replace(" ", " ");
text = "To see the " + label + " boundaries and labels on the map you'll need to zoom out.";
showAlert = true;
}
else if (this.maplayers[0].maxScale && scale > this.maplayers[0].maxScale) {
var label = this.maplayers[0].getLabel().replace(" ", " ");
text = "To see the " + label + " boundaries and labels on the map you'll need to zoom in.";
showAlert = true;
}
if (showAlert) {
var alerter = new PAlerter();
var position = getAlertPosition(parseInt(alerter.box.style.width));
alerter.popup(text, position[0], position[1], "OK");
}
}
},
removeMapLayers : function() {
if (this.maplayers) {
for (var i=0; i" + places.addr + "\" not found. For help finding your address: click here";
alerter.popup(content,pos[0],pos[1],"OK");
}
} else {
var alerter = new PAlerter();
var pos = getAlertPosition(parseInt(alerter.box.style.width));
alerter.popup("Please specify a street address, not an area.",pos[0],pos[1],"OK");
}
});
this.container.appendChild(searchContainer);
var div = document.createElement('div');
div.className = 'title';
div.innerHTML = 'OR Click Map to Center Radius';
this.container.appendChild(div);
var div = document.createElement('div');
div.className = 'radiusDiv';
var span = document.createElement('span');
span.className = 'title';
span.innerHTML = 'Specify Radius:';
div.appendChild(span);
var radius = document.createElement('input');
radius.type = 'text';
radius.className = 'radius';
radius.id = "radiusSetting";
radius.value = 0.5; // default radius
PEvent.addListener(radius, 'keydown', function(e) {
e = (e)?e:((event)?event:null);
if (e && e.keyCode == 13)
that.searchbox.submit();
});
this.radius = radius;
div.appendChild(radius);
var span = document.createElement('span');
span.innerHTML = 'Miles';
span.className = 'radiusText';
div.appendChild(span);
var go = document.createElement('input');
go.type = 'image';
go.src = 'images/global-button-go-xlarge.gif';
go.alt = 'Go';
go.style.margin = "-6px 5px";
PEvent.addListener(go, 'click', function() {
that.searchbox.submit();
});
div.appendChild(go);
this.container.appendChild(div);
}
PPolyCreatorCircleWidget.prototype = {
show : function() {
// set textbox to default value
this.searchbox.textbox.value = this.exampleAddress;
this.container.style.display = "block";
},
hide : function() {
this.container.style.display = "none";
},
showCircle : function(address) {
var point = new PLatLng(address.y, address.x);
var miles = this.polycreator.circleWidget.radius.value;
var vert = this.polycreator.drawCircle(point, miles, true);
// if address is PLatLng because user clicked on map to create custom region, than make the coordinates the address
this.polycreator.CIRCLE.address = (address instanceof PLatLng) ? address : address.y + ', ' + address.x;
var polyline = new PPolyline(vert, '#e68000');
this.polycreator.map.addOverlay(polyline);
this.polycreator.buildingOverlays.push(polyline);
this.polycreator.eventManager.triggerEvent('addpoly', [point]);
}
}
/**********************************************
**** Class: PPolyCreatorAssembleInfoWidget ****
**********************************************/
// Displays the places that are selected while assembling
PPolyCreatorAssembleInfoWidget = function(polycreator) {
this.polycreator = polycreator;
var container = document.createElement('div');
container.id = "PolyAssembleInfoBox";
container.className = "CustomRegionWidgets";
this.container = container;
var title = document.createElement('div');
title.className = "title";
//title.style.color = "#33F900";
var html = "Click Map to Assemble Region";
title.innerHTML = html
// div used to show place labels
var contenttitle = document.createElement('span');
contenttitle.innerHTML = "Current places: ";
var content = document.createElement('span');
content.className = "placeLabels";
this.content = content;
jQuery(container).append(title);
jQuery(container).append(contenttitle);
jQuery(container).append(content);
var footer = document.createElement('div');
footer.className = "footer";
var clear = document.createElement('a');
clear.innerHTML = "Clear All and Start Over";
clear.widget = this;
clear.onclick = function() {
this.widget.clear();
}
var save = document.createElement('a');
save.innerHTML = "Save Region";
save.widget = this;
save.onclick = function() {
this.widget.polycreator.showSaveInfoWindow(this.widget.polycreator.ASSEMBLE.lastpoint)
}
/*
var cancel = document.createElement('a');
cancel.innerHTML = "Cancel";
cancel.polycreator = this;
cancel.onclick = function() {
// cancel and remove element
this.polycreator.cancelPoly();
jQuery(this.polycreator.assembleInfoBox).remove();
}
*/
jQuery(footer).append(clear);
jQuery(footer).append(save);
//jQuery(footer).append(cancel);
jQuery(container).append(footer);
jQuery('#map').append(container);
this.update();
}
PPolyCreatorAssembleInfoWidget.prototype = {
show : function() {
this.container.style.display = "block";
},
hide : function() {
this.container.style.display = "none";
},
clear : function() {
// clear overlays
this.polycreator.clearBuildingOverlays();
// clear stored places so we can update the labels
this.polycreator.ASSEMBLE.places = [];
// update place labels
this.polycreator.assembleInfoWidget.update();
},
update : function() {
var div = this.content;
jQuery(div).empty();
var places = this.polycreator.ASSEMBLE.places;
if (places && places.length == 0) {
var span = document.createElement('span');
span.className = "empty";
span.innerHTML = "(no places selected)";
jQuery(div).append(span);
}
// add link for each place
for (var i=0; i=0; i--) {
var place = places[i];
var li = document.createElement('li');
var div = document.createElement('div');
div.className = 'name';
li.appendChild(div);
li.index = i;
li.dropdown = this;
li.place = place;
li.on = false;
div.innerHTML = place.getLabel();
var remove = document.createElement('img');
remove.className = 'remove';
remove.title = 'Remove';
var activeSrc = 'images/remove_icon_active.png';
var inactiveSrc = 'images/close_button2.gif';
remove.src = inactiveSrc;
// For charts the remove icon isn't needed for the drop down
// Only one custom region is allowed at a time in charts, if that changes the remove option will have to be added
if (PAGE_ID != "c_")
li.appendChild(remove);
var br = document.createElement('br');
br.className = "clear";
li.appendChild(br);
// the image src changes when cusom region is selected from list
li.remove = remove;
// check if custom place is on the map
// if so turn on the place in the dropdown
if (polycreator.customPlacesOnMap[place.id]) {
li.on = true;
li.className = "active";
li.remove = remove;
remove.src = activeSrc;
polycreator.customPlacesOnMap[place.id].dropdownEl = li;
}
this.listeners.push(PEvent.addListener(li, 'mousedown', function() {
var place = this.place;
this.dropdown.dropdown.style.display = "none";
//this.dropdown.onchange();
if (this.on == true) {
// removes place from map and clears the place from the dropdown
polycreator.removeCustomRegionFromMap(place);
}
else {
if (PAGE_ID == "c_") {
// for charts add custom place to global var and refresh cube and add place to session
// currently only one custom place is allowed at a time so don't need to turn on the list item so it can be removed
custom_place = place;
refreshCube();
session2.put('cp', place.id);
}
else {
this.className = "active";
this.remove.src = activeSrc;
this.on = true;
var html = function(){ return PMIdentificationPrinter.printCustomPolyPlaces(place); };
polycreator.addPolylines(place, html, map);
// when place is added we need to store the LI element so we can turn it off when needed
polycreator.customPlacesOnMap[place.id].dropdownEl = this;
map.setCenterBounds(place.getBounds());
}
this.dropdown.toggle();
}
}));
this.dropdown.appendChild(li);
}
},
toggle : function() {
if (!isSubscriber()) {
subscribeAlert();
return;
}
if (this.dropdown.style.display == "none")
this.dropdown.style.display = "block";
else
this.dropdown.style.display = "none";
},
show : function() {
this.container.style.display = "block";
},
hide : function() {
this.container.style.display = "none";
},
setUsersPlaces : function() {
// get all the custom regions for the user and then populate the dropdown
var that = this;
var loading = document.createElement('li');
loading.style.margin = "10px";
loading.innerHTML = "Loading...";
this.dropdown.appendChild(loading);
polycreator.loadByUser(session2.get('_userid'), function(places) {
that.refresh(places);
});
// show the custom regions drop down feature
this.show();
},
reset : function() {
this.dropdown.style.display = "none";
this.setUsersPlaces();
}
}
/*****************************
*** Class: PMap extensions ***
*****************************/
PMap.prototype.enablePolyCreator = function(polycreator) {
polycreator.attachMap(this);
}
PMap.prototype.disablePolyCreator = function(polycreator) {
polycreator.detachMap(this);
}