[OpenLayers-Commits] r3164 - in sandbox/tschaub/geojson: examples lib lib/Firebug lib/OpenLayers lib/OpenLayers/Format
commits at openlayers.org
commits at openlayers.org
Wed May 23 18:54:23 EDT 2007
Author: tschaub
Date: 2007-05-23 18:54:22 -0400 (Wed, 23 May 2007)
New Revision: 3164
Added:
sandbox/tschaub/geojson/lib/Firebug/
sandbox/tschaub/geojson/lib/Firebug/DebugOpenLayers.js
sandbox/tschaub/geojson/lib/Firebug/errorIcon.png
sandbox/tschaub/geojson/lib/Firebug/firebug.css
sandbox/tschaub/geojson/lib/Firebug/firebug.html
sandbox/tschaub/geojson/lib/Firebug/firebug.js
sandbox/tschaub/geojson/lib/Firebug/firebugx.js
sandbox/tschaub/geojson/lib/Firebug/infoIcon.png
sandbox/tschaub/geojson/lib/Firebug/warningIcon.png
Modified:
sandbox/tschaub/geojson/examples/geojson.html
sandbox/tschaub/geojson/lib/OpenLayers/BaseTypes.js
sandbox/tschaub/geojson/lib/OpenLayers/Format/GeoJSON.js
Log:
support for RFC-2 - read/write Point, MultiPoint, LineString, MultiLineString, Polygon, MultiPolygon, Box, GeometryCollection, Feature, and FeatureCollection - debugging framework also included
Modified: sandbox/tschaub/geojson/examples/geojson.html
===================================================================
--- sandbox/tschaub/geojson/examples/geojson.html 2007-05-23 20:18:45 UTC (rev 3163)
+++ sandbox/tschaub/geojson/examples/geojson.html 2007-05-23 22:54:22 UTC (rev 3164)
@@ -13,20 +13,27 @@
height: 350px;
border: 1px solid gray;
}
+ #controls {
+ width: 512px;
+ }
+ #geoJSONInput {
+ float: right;
+ }
#controlToggle li {
list-style: none;
}
</style>
<script src="../lib/OpenLayers.js"></script>
+ <script src="../lib/Firebug/DebugOpenLayers.js"></script>
<script type="text/javascript">
<!--
- var map, drawControls, geojson;
+ var map, drawControls, geojson, vectors;
function init(){
map = new OpenLayers.Map('map');
var wms = new OpenLayers.Layer.WMS( "OpenLayers WMS",
"http://labs.metacarta.com/wms/vmap0?", {layers: 'basic'});
- var vectors = new OpenLayers.Layer.Vector("Vector Layer");
+ vectors = new OpenLayers.Layer.Vector("Vector Layer");
map.addLayers([wms, vectors]);
map.addControl(new OpenLayers.Control.LayerSwitcher());
@@ -69,11 +76,32 @@
}
function displayGeoJSON(feature) {
- var json = geojson.write([feature]);
+ var json = geojson.write(feature);
// not a good idea in general, just for this demo
json = json.replace(/,/g, ', ');
document.getElementById('info').innerHTML = json;
}
+
+ function parseGeoJSON() {
+ var element = document.getElementById('geojson');
+ var features = geojson.read(element.value, "FeatureCollection");
+ if(features) {
+ var bounds;
+ for(var i=0; i<features.length; ++i) {
+ if (!bounds) {
+ bounds = features[i].geometry.getBounds();
+ } else {
+ bounds.extend(features[i].geometry.getBounds());
+ }
+ }
+ vectors.addFeatures(features);
+ map.zoomToExtent(bounds);
+ var plural = (features.length > 1) ? 's' : '';
+ element.value = features.length + ' feature' + plural + ' added'
+ } else {
+ element.value = 'Bad GeoJSON';
+ }
+ }
// -->
</script>
</head>
@@ -81,29 +109,36 @@
<h1>OpenLayers GeoJSON Example</h1>
<div id="info"></div>
<div id="map"></div>
- <ul id="controlToggle">
- <li>
- <input type="radio" name="type" value="none" id="noneToggle"
- onclick="toggleControl(this);" checked="checked" />
- <label for="noneToggle">navigate</label>
- </li>
- <li>
- <input type="radio" name="type" value="point" id="pointToggle" onclick="toggleControl(this);" />
- <label for="pointToggle">draw point</label>
- </li>
- <li>
- <input type="radio" name="type" value="line" id="lineToggle" onclick="toggleControl(this);" />
- <label for="lineToggle">draw line</label>
- </li>
- <li>
- <input type="radio" name="type" value="polygon" id="polygonToggle" onclick="toggleControl(this);" />
- <label for="polygonToggle">draw polygon</label>
- </li>
- <li>
- <input type="radio" name="type" value="hover" id="hoverToggle"
- onclick="toggleControl(this);" />
- <label for="hoverToggle">view GeoJSON for feature (on hover)</label>
- </li>
- </ul>
+ <div id="controls">
+ <div id="geoJSONInput">
+ <textarea id="geojson" rows="6" cols="30">paste GeoJSON here...</textarea>
+ <br />
+ <input type="button" value="add feature" onclick="parseGeoJSON();" />
+ </div>
+ <ul id="controlToggle">
+ <li>
+ <input type="radio" name="type" value="none" id="noneToggle"
+ onclick="toggleControl(this);" checked="checked" />
+ <label for="noneToggle">navigate</label>
+ </li>
+ <li>
+ <input type="radio" name="type" value="point" id="pointToggle" onclick="toggleControl(this);" />
+ <label for="pointToggle">draw point</label>
+ </li>
+ <li>
+ <input type="radio" name="type" value="line" id="lineToggle" onclick="toggleControl(this);" />
+ <label for="lineToggle">draw line</label>
+ </li>
+ <li>
+ <input type="radio" name="type" value="polygon" id="polygonToggle" onclick="toggleControl(this);" />
+ <label for="polygonToggle">draw polygon</label>
+ </li>
+ <li>
+ <input type="radio" name="type" value="hover" id="hoverToggle"
+ onclick="toggleControl(this);" />
+ <label for="hoverToggle">view GeoJSON feature collection (on hover)</label>
+ </li>
+ </ul>
+ </div>
</body>
</html>
Added: sandbox/tschaub/geojson/lib/Firebug/DebugOpenLayers.js
===================================================================
--- sandbox/tschaub/geojson/lib/Firebug/DebugOpenLayers.js (rev 0)
+++ sandbox/tschaub/geojson/lib/Firebug/DebugOpenLayers.js 2007-05-23 22:54:22 UTC (rev 3164)
@@ -0,0 +1,699 @@
+/**
+ * Include this script in your OpenLayers application after the OpenLayers.js
+ * script tag to get Firebug debugging in any browser. With this script
+ * included, if a browser has the Firebug extension installed, calls to
+ * OpenLayers.console will get rerouted to console. If a browser does not
+ * have the Firebug extension installed, this script mimics the behavior
+ * of that extension. With this script included, the Firebug console can
+ * be opened with F12 or Ctrl+Shift+L (or ?+Shift+L on a Mac).
+ *
+ * This script is based on the firebug.js script from
+ * http://www.getfirebug.com/lite.html
+ * Modifications include putting the console object in the OpenLayers
+ * namespace, modifying getFirebugURL, and re-routing OpenLayers.console calls
+ * to console if the Firebug extension is installed.
+ */
+
+
+if (("console" in window) && ("firebug" in console)) {
+ /**
+ * If the Firebug extension is installed, re-route all OpenLayers.console
+ * calls to the console object.
+ */
+ OpenLayers.Util.extend(OpenLayers.console, console);
+} else {
+ /**
+ * An anonymous function is called here so that variables are not
+ * global in scope.
+ */
+ (function()
+ {
+ OpenLayers.console =
+ {
+ log: function()
+ {
+ logFormatted(arguments, "");
+ },
+
+ debug: function()
+ {
+ logFormatted(arguments, "debug");
+ },
+
+ info: function()
+ {
+ logFormatted(arguments, "info");
+ },
+
+ warn: function()
+ {
+ logFormatted(arguments, "warning");
+ },
+
+ error: function()
+ {
+ logFormatted(arguments, "error");
+ },
+
+ assert: function(truth, message)
+ {
+ if (!truth)
+ {
+ var args = [];
+ for (var i = 1; i < arguments.length; ++i)
+ args.push(arguments[i]);
+
+ logFormatted(args.length ? args : ["Assertion Failure"], "error");
+ throw message ? message : "Assertion Failure";
+ }
+ },
+
+ dir: function(object)
+ {
+ var html = [];
+
+ var pairs = [];
+ for (var name in object)
+ {
+ try
+ {
+ pairs.push([name, object[name]]);
+ }
+ catch (exc)
+ {
+ }
+ }
+
+ pairs.sort(function(a, b) { return a[0] < b[0] ? -1 : 1; });
+
+ html.push('<table>');
+ for (var i = 0; i < pairs.length; ++i)
+ {
+ var name = pairs[i][0], value = pairs[i][1];
+
+ html.push('<tr>',
+ '<td class="propertyNameCell"><span class="propertyName">',
+ escapeHTML(name), '</span></td>', '<td><span class="propertyValue">');
+ appendObject(value, html);
+ html.push('</span></td></tr>');
+ }
+ html.push('</table>');
+
+ logRow(html, "dir");
+ },
+
+ dirxml: function(node)
+ {
+ var html = [];
+
+ appendNode(node, html);
+ logRow(html, "dirxml");
+ },
+
+ group: function()
+ {
+ logRow(arguments, "group", pushGroup);
+ },
+
+ groupEnd: function()
+ {
+ logRow(arguments, "", popGroup);
+ },
+
+ time: function(name)
+ {
+ timeMap[name] = (new Date()).getTime();
+ },
+
+ timeEnd: function(name)
+ {
+ if (name in timeMap)
+ {
+ var delta = (new Date()).getTime() - timeMap[name];
+ logFormatted([name+ ":", delta+"ms"]);
+ delete timeMap[name];
+ }
+ },
+
+ count: function()
+ {
+ this.warn(["count() not supported."]);
+ },
+
+ trace: function()
+ {
+ this.warn(["trace() not supported."]);
+ },
+
+ profile: function()
+ {
+ this.warn(["profile() not supported."]);
+ },
+
+ profileEnd: function()
+ {
+ },
+
+ clear: function()
+ {
+ consoleBody.innerHTML = "";
+ },
+
+ open: function()
+ {
+ toggleConsole(true);
+ },
+
+ close: function()
+ {
+ if (frameVisible)
+ toggleConsole();
+ }
+ };
+
+ // ********************************************************************************************
+
+ var consoleFrame = null;
+ var consoleBody = null;
+ var commandLine = null;
+
+ var frameVisible = false;
+ var messageQueue = [];
+ var groupStack = [];
+ var timeMap = {};
+
+ var clPrefix = ">>> ";
+
+ var isFirefox = navigator.userAgent.indexOf("Firefox") != -1;
+ var isIE = navigator.userAgent.indexOf("MSIE") != -1;
+ var isOpera = navigator.userAgent.indexOf("Opera") != -1;
+ var isSafari = navigator.userAgent.indexOf("AppleWebKit") != -1;
+
+ // ********************************************************************************************
+
+ function toggleConsole(forceOpen)
+ {
+ frameVisible = forceOpen || !frameVisible;
+ if (consoleFrame)
+ consoleFrame.style.visibility = frameVisible ? "visible" : "hidden";
+ else
+ waitForBody();
+ }
+
+ function focusCommandLine()
+ {
+ toggleConsole(true);
+ if (commandLine)
+ commandLine.focus();
+ }
+
+ function waitForBody()
+ {
+ if (document.body)
+ createFrame();
+ else
+ setTimeout(waitForBody, 200);
+ }
+
+ function createFrame()
+ {
+ if (consoleFrame)
+ return;
+
+ window.onFirebugReady = function(doc)
+ {
+ window.onFirebugReady = null;
+
+ var toolbar = doc.getElementById("toolbar");
+ toolbar.onmousedown = onSplitterMouseDown;
+
+ commandLine = doc.getElementById("commandLine");
+ addEvent(commandLine, "keydown", onCommandLineKeyDown);
+
+ addEvent(doc, isIE || isSafari ? "keydown" : "keypress", onKeyDown);
+
+ consoleBody = doc.getElementById("log");
+ layout();
+ flush();
+ }
+
+ var baseURL = getFirebugURL();
+
+ consoleFrame = document.createElement("iframe");
+ consoleFrame.setAttribute("src", baseURL+"/firebug.html");
+ consoleFrame.setAttribute("frameBorder", "0");
+ consoleFrame.style.visibility = (frameVisible ? "visible" : "hidden");
+ consoleFrame.style.zIndex = "2147483647";
+ consoleFrame.style.position = "fixed";
+ consoleFrame.style.width = "100%";
+ consoleFrame.style.left = "0";
+ consoleFrame.style.bottom = "0";
+ consoleFrame.style.height = "200px";
+ document.body.appendChild(consoleFrame);
+ }
+
+ function getFirebugURL()
+ {
+ var scripts = document.getElementsByTagName("script");
+ for (var i = 0; i < scripts.length; ++i)
+ {
+ if (scripts[i].src.indexOf("DebugOpenLayers.js") != -1)
+ {
+ var lastSlash = scripts[i].src.lastIndexOf("/");
+ return scripts[i].src.substr(0, lastSlash);
+ }
+ }
+ }
+
+ function evalCommandLine()
+ {
+ var text = commandLine.value;
+ commandLine.value = "";
+
+ logRow([clPrefix, text], "command");
+
+ var value;
+ try
+ {
+ value = eval(text);
+ }
+ catch (exc)
+ {
+ }
+
+ OpenLayers.console.log(value);
+ }
+
+ function layout()
+ {
+ var toolbar = consoleBody.ownerDocument.getElementById("toolbar");
+ var height = consoleFrame.offsetHeight - (toolbar.offsetHeight + commandLine.offsetHeight);
+ height = Math.max(height, 0);
+ consoleBody.style.top = toolbar.offsetHeight + "px";
+ consoleBody.style.height = height + "px";
+ commandLine.style.top = (consoleFrame.offsetHeight - commandLine.offsetHeight) + "px";
+ }
+
+ function logRow(message, className, handler)
+ {
+ if (consoleBody)
+ writeMessage(message, className, handler);
+ else
+ {
+ messageQueue.push([message, className, handler]);
+ waitForBody();
+ }
+ }
+
+ function flush()
+ {
+ var queue = messageQueue;
+ messageQueue = [];
+
+ for (var i = 0; i < queue.length; ++i)
+ writeMessage(queue[i][0], queue[i][1], queue[i][2]);
+ }
+
+ function writeMessage(message, className, handler)
+ {
+ var isScrolledToBottom =
+ consoleBody.scrollTop + consoleBody.offsetHeight >= consoleBody.scrollHeight;
+
+ if (!handler)
+ handler = writeRow;
+
+ handler(message, className);
+
+ if (isScrolledToBottom)
+ consoleBody.scrollTop = consoleBody.scrollHeight - consoleBody.offsetHeight;
+ }
+
+ function appendRow(row)
+ {
+ var container = groupStack.length ? groupStack[groupStack.length-1] : consoleBody;
+ container.appendChild(row);
+ }
+
+ function writeRow(message, className)
+ {
+ var row = consoleBody.ownerDocument.createElement("div");
+ row.className = "logRow" + (className ? " logRow-"+className : "");
+ row.innerHTML = message.join("");
+ appendRow(row);
+ }
+
+ function pushGroup(message, className)
+ {
+ logFormatted(message, className);
+
+ var groupRow = consoleBody.ownerDocument.createElement("div");
+ groupRow.className = "logGroup";
+ var groupRowBox = consoleBody.ownerDocument.createElement("div");
+ groupRowBox.className = "logGroupBox";
+ groupRow.appendChild(groupRowBox);
+ appendRow(groupRowBox);
+ groupStack.push(groupRowBox);
+ }
+
+ function popGroup()
+ {
+ groupStack.pop();
+ }
+
+ // ********************************************************************************************
+
+ function logFormatted(objects, className)
+ {
+ var html = [];
+
+ var format = objects[0];
+ var objIndex = 0;
+
+ if (typeof(format) != "string")
+ {
+ format = "";
+ objIndex = -1;
+ }
+
+ var parts = parseFormat(format);
+ for (var i = 0; i < parts.length; ++i)
+ {
+ var part = parts[i];
+ if (part && typeof(part) == "object")
+ {
+ var object = objects[++objIndex];
+ part.appender(object, html);
+ }
+ else
+ appendText(part, html);
+ }
+
+ for (var i = objIndex+1; i < objects.length; ++i)
+ {
+ appendText(" ", html);
+
+ var object = objects[i];
+ if (typeof(object) == "string")
+ appendText(object, html);
+ else
+ appendObject(object, html);
+ }
+
+ logRow(html, className);
+ }
+
+ function parseFormat(format)
+ {
+ var parts = [];
+
+ var reg = /((^%|[^\\]%)(\d+)?(\.)([a-zA-Z]))|((^%|[^\\]%)([a-zA-Z]))/;
+ var appenderMap = {s: appendText, d: appendInteger, i: appendInteger, f: appendFloat};
+
+ for (var m = reg.exec(format); m; m = reg.exec(format))
+ {
+ var type = m[8] ? m[8] : m[5];
+ var appender = type in appenderMap ? appenderMap[type] : appendObject;
+ var precision = m[3] ? parseInt(m[3]) : (m[4] == "." ? -1 : 0);
+
+ parts.push(format.substr(0, m[0][0] == "%" ? m.index : m.index+1));
+ parts.push({appender: appender, precision: precision});
+
+ format = format.substr(m.index+m[0].length);
+ }
+
+ parts.push(format);
+
+ return parts;
+ }
+
+ function escapeHTML(value)
+ {
+ function replaceChars(ch)
+ {
+ switch (ch)
+ {
+ case "<":
+ return "<";
+ case ">":
+ return ">";
+ case "&":
+ return "&";
+ case "'":
+ return "'";
+ case '"':
+ return """;
+ }
+ return "?";
+ };
+ return String(value).replace(/[<>&"']/g, replaceChars);
+ }
+
+ function objectToString(object)
+ {
+ try
+ {
+ return object+"";
+ }
+ catch (exc)
+ {
+ return null;
+ }
+ }
+
+ // ********************************************************************************************
+
+ function appendText(object, html)
+ {
+ html.push(escapeHTML(objectToString(object)));
+ }
+
+ function appendNull(object, html)
+ {
+ html.push('<span class="objectBox-null">', escapeHTML(objectToString(object)), '</span>');
+ }
+
+ function appendString(object, html)
+ {
+ html.push('<span class="objectBox-string">"', escapeHTML(objectToString(object)),
+ '"</span>');
+ }
+
+ function appendInteger(object, html)
+ {
+ html.push('<span class="objectBox-number">', escapeHTML(objectToString(object)), '</span>');
+ }
+
+ function appendFloat(object, html)
+ {
+ html.push('<span class="objectBox-number">', escapeHTML(objectToString(object)), '</span>');
+ }
+
+ function appendFunction(object, html)
+ {
+ var reName = /function ?(.*?)\(/;
+ var m = reName.exec(objectToString(object));
+ var name = m ? m[1] : "function";
+ html.push('<span class="objectBox-function">', escapeHTML(name), '()</span>');
+ }
+
+ function appendObject(object, html)
+ {
+ try
+ {
+ if (object == undefined)
+ appendNull("undefined", html);
+ else if (object == null)
+ appendNull("null", html);
+ else if (typeof object == "string")
+ appendString(object, html);
+ else if (typeof object == "number")
+ appendInteger(object, html);
+ else if (typeof object == "function")
+ appendFunction(object, html);
+ else if (object.nodeType == 1)
+ appendSelector(object, html);
+ else if (typeof object == "object")
+ appendObjectFormatted(object, html);
+ else
+ appendText(object, html);
+ }
+ catch (exc)
+ {
+ }
+ }
+
+ function appendObjectFormatted(object, html)
+ {
+ var text = objectToString(object);
+ var reObject = /\[object (.*?)\]/;
+
+ var m = reObject.exec(text);
+ html.push('<span class="objectBox-object">', m ? m[1] : text, '</span>')
+ }
+
+ function appendSelector(object, html)
+ {
+ html.push('<span class="objectBox-selector">');
+
+ html.push('<span class="selectorTag">', escapeHTML(object.nodeName.toLowerCase()), '</span>');
+ if (object.id)
+ html.push('<span class="selectorId">#', escapeHTML(object.id), '</span>');
+ if (object.className)
+ html.push('<span class="selectorClass">.', escapeHTML(object.className), '</span>');
+
+ html.push('</span>');
+ }
+
+ function appendNode(node, html)
+ {
+ if (node.nodeType == 1)
+ {
+ html.push(
+ '<div class="objectBox-element">',
+ '<<span class="nodeTag">', node.nodeName.toLowerCase(), '</span>');
+
+ for (var i = 0; i < node.attributes.length; ++i)
+ {
+ var attr = node.attributes[i];
+ if (!attr.specified)
+ continue;
+
+ html.push(' <span class="nodeName">', attr.nodeName.toLowerCase(),
+ '</span>="<span class="nodeValue">', escapeHTML(attr.nodeValue),
+ '</span>"')
+ }
+
+ if (node.firstChild)
+ {
+ html.push('></div><div class="nodeChildren">');
+
+ for (var child = node.firstChild; child; child = child.nextSibling)
+ appendNode(child, html);
+
+ html.push('</div><div class="objectBox-element"></<span class="nodeTag">',
+ node.nodeName.toLowerCase(), '></span></div>');
+ }
+ else
+ html.push('/></div>');
+ }
+ else if (node.nodeType == 3)
+ {
+ html.push('<div class="nodeText">', escapeHTML(node.nodeValue),
+ '</div>');
+ }
+ }
+
+ // ********************************************************************************************
+
+ function addEvent(object, name, handler)
+ {
+ if (document.all)
+ object.attachEvent("on"+name, handler);
+ else
+ object.addEventListener(name, handler, false);
+ }
+
+ function removeEvent(object, name, handler)
+ {
+ if (document.all)
+ object.detachEvent("on"+name, handler);
+ else
+ object.removeEventListener(name, handler, false);
+ }
+
+ function cancelEvent(event)
+ {
+ if (document.all)
+ event.cancelBubble = true;
+ else
+ event.stopPropagation();
+ }
+
+ function onError(msg, href, lineNo)
+ {
+ var html = [];
+
+ var lastSlash = href.lastIndexOf("/");
+ var fileName = lastSlash == -1 ? href : href.substr(lastSlash+1);
+
+ html.push(
+ '<span class="errorMessage">', msg, '</span>',
+ '<div class="objectBox-sourceLink">', fileName, ' (line ', lineNo, ')</div>'
+ );
+
+ logRow(html, "error");
+ };
+
+ function onKeyDown(event)
+ {
+ if (event.keyCode == 123)
+ toggleConsole();
+ else if ((event.keyCode == 108 || event.keyCode == 76) && event.shiftKey
+ && (event.metaKey || event.ctrlKey))
+ focusCommandLine();
+ else
+ return;
+
+ cancelEvent(event);
+ }
+
+ function onSplitterMouseDown(event)
+ {
+ if (isSafari || isOpera)
+ return;
+
+ addEvent(document, "mousemove", onSplitterMouseMove);
+ addEvent(document, "mouseup", onSplitterMouseUp);
+
+ for (var i = 0; i < frames.length; ++i)
+ {
+ addEvent(frames[i].document, "mousemove", onSplitterMouseMove);
+ addEvent(frames[i].document, "mouseup", onSplitterMouseUp);
+ }
+ }
+
+ function onSplitterMouseMove(event)
+ {
+ var win = document.all
+ ? event.srcElement.ownerDocument.parentWindow
+ : event.target.ownerDocument.defaultView;
+
+ var clientY = event.clientY;
+ if (win != win.parent)
+ clientY += win.frameElement ? win.frameElement.offsetTop : 0;
+
+ var height = consoleFrame.offsetTop + consoleFrame.clientHeight;
+ var toolbar = consoleBody.ownerDocument.getElementById("toolbar");
+ var y = Math.max(height - clientY,
+ toolbar.offsetHeight + commandLine.offsetHeight);
+ consoleFrame.style.height = y + "px";
+ layout();
+ }
+
+ function onSplitterMouseUp(event)
+ {
+ removeEvent(document, "mousemove", onSplitterMouseMove);
+ removeEvent(document, "mouseup", onSplitterMouseUp);
+
+ for (var i = 0; i < frames.length; ++i)
+ {
+ removeEvent(frames[i].document, "mousemove", onSplitterMouseMove);
+ removeEvent(frames[i].document, "mouseup", onSplitterMouseUp);
+ }
+ }
+
+ function onCommandLineKeyDown(event)
+ {
+ if (event.keyCode == 13)
+ evalCommandLine();
+ else if (event.keyCode == 27)
+ commandLine.value = "";
+ }
+
+ window.onerror = onError;
+ addEvent(document, isIE || isSafari ? "keydown" : "keypress", onKeyDown);
+
+ if (document.documentElement.getAttribute("debug") == "true")
+ toggleConsole(true);
+ })();
+}
Added: sandbox/tschaub/geojson/lib/Firebug/errorIcon.png
===================================================================
(Binary files differ)
Property changes on: sandbox/tschaub/geojson/lib/Firebug/errorIcon.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: sandbox/tschaub/geojson/lib/Firebug/firebug.css
===================================================================
--- sandbox/tschaub/geojson/lib/Firebug/firebug.css (rev 0)
+++ sandbox/tschaub/geojson/lib/Firebug/firebug.css 2007-05-23 22:54:22 UTC (rev 3164)
@@ -0,0 +1,209 @@
+
+html, body {
+ margin: 0;
+ background: #FFFFFF;
+ font-family: Lucida Grande, Tahoma, sans-serif;
+ font-size: 11px;
+ overflow: hidden;
+}
+
+a {
+ text-decoration: none;
+}
+
+a:hover {
+ text-decoration: underline;
+}
+
+.toolbar {
+ height: 14px;
+ border-top: 1px solid ThreeDHighlight;
+ border-bottom: 1px solid ThreeDShadow;
+ padding: 2px 6px;
+ background: ThreeDFace;
+}
+
+.toolbarRight {
+ position: absolute;
+ top: 4px;
+ right: 6px;
+}
+
+#log {
+ overflow: auto;
+ position: absolute;
+ left: 0;
+ width: 100%;
+}
+
+#commandLine {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ width: 100%;
+ height: 18px;
+ border: none;
+ border-top: 1px solid ThreeDShadow;
+}
+
+/************************************************************************************************/
+
+.logRow {
+ position: relative;
+ border-bottom: 1px solid #D7D7D7;
+ padding: 2px 4px 1px 6px;
+ background-color: #FFFFFF;
+}
+
+.logRow-command {
+ font-family: Monaco, monospace;
+ color: blue;
+}
+
+.objectBox-null {
+ padding: 0 2px;
+ border: 1px solid #666666;
+ background-color: #888888;
+ color: #FFFFFF;
+}
+
+.objectBox-string {
+ font-family: Monaco, monospace;
+ color: red;
+ white-space: pre;
+}
+
+.objectBox-number {
+ color: #000088;
+}
+
+.objectBox-function {
+ font-family: Monaco, monospace;
+ color: DarkGreen;
+}
+
+.objectBox-object {
+ color: DarkGreen;
+ font-weight: bold;
+}
+
+/************************************************************************************************/
+
+.logRow-info,
+.logRow-error,
+.logRow-warning {
+ background: #FFFFFF no-repeat 2px 2px;
+ padding-left: 20px;
+ padding-bottom: 3px;
+}
+
+.logRow-info {
+ background-image: url(infoIcon.png);
+}
+
+.logRow-warning {
+ background-color: cyan;
+ background-image: url(warningIcon.png);
+}
+
+.logRow-error {
+ background-color: LightYellow;
+ background-image: url(errorIcon.png);
+}
+
+.errorMessage {
+ vertical-align: top;
+ color: #FF0000;
+}
+
+.objectBox-sourceLink {
+ position: absolute;
+ right: 4px;
+ top: 2px;
+ padding-left: 8px;
+ font-family: Lucida Grande, sans-serif;
+ font-weight: bold;
+ color: #0000FF;
+}
+
+/************************************************************************************************/
+
+.logRow-group {
+ background: #EEEEEE;
+ border-bottom: none;
+}
+
+.logGroup {
+ background: #EEEEEE;
+}
+
+.logGroupBox {
+ margin-left: 24px;
+ border-top: 1px solid #D7D7D7;
+ border-left: 1px solid #D7D7D7;
+}
+
+/************************************************************************************************/
+
+.selectorTag,
+.selectorId,
+.selectorClass {
+ font-family: Monaco, monospace;
+ font-weight: normal;
+}
+
+.selectorTag {
+ color: #0000FF;
+}
+
+.selectorId {
+ color: DarkBlue;
+}
+
+.selectorClass {
+ color: red;
+}
+
+/************************************************************************************************/
+
+.objectBox-element {
+ font-family: Monaco, monospace;
+ color: #000088;
+}
+
+.nodeChildren {
+ margin-left: 16px;
+}
+
+.nodeTag {
+ color: blue;
+}
+
+.nodeValue {
+ color: #FF0000;
+ font-weight: normal;
+}
+
+.nodeText,
+.nodeComment {
+ margin: 0 2px;
+ vertical-align: top;
+}
+
+.nodeText {
+ color: #333333;
+}
+
+.nodeComment {
+ color: DarkGreen;
+}
+
+/************************************************************************************************/
+
+.propertyNameCell {
+ vertical-align: top;
+}
+
+.propertyName {
+ font-weight: bold;
+}
Added: sandbox/tschaub/geojson/lib/Firebug/firebug.html
===================================================================
--- sandbox/tschaub/geojson/lib/Firebug/firebug.html (rev 0)
+++ sandbox/tschaub/geojson/lib/Firebug/firebug.html 2007-05-23 22:54:22 UTC (rev 3164)
@@ -0,0 +1,23 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+
+<head>
+ <title>Firebug</title>
+ <link rel="stylesheet" type="text/css" href="firebug.css">
+</head>
+
+<body>
+ <div id="toolbar" class="toolbar">
+ <a href="#" onclick="parent.OpenLayers.console.clear()">Clear</a>
+ <span class="toolbarRight">
+ <a href="#" onclick="parent.OpenLayers.console.close()">Close</a>
+ </span>
+ </div>
+ <div id="log"></div>
+ <input type="text" id="commandLine">
+
+ <script>parent.onFirebugReady(document);</script>
+</body>
+</html>
Added: sandbox/tschaub/geojson/lib/Firebug/firebug.js
===================================================================
--- sandbox/tschaub/geojson/lib/Firebug/firebug.js (rev 0)
+++ sandbox/tschaub/geojson/lib/Firebug/firebug.js 2007-05-23 22:54:22 UTC (rev 3164)
@@ -0,0 +1,672 @@
+
+if (!("console" in window) || !("firebug" in console)) {
+(function()
+{
+ window.console =
+ {
+ log: function()
+ {
+ logFormatted(arguments, "");
+ },
+
+ debug: function()
+ {
+ logFormatted(arguments, "debug");
+ },
+
+ info: function()
+ {
+ logFormatted(arguments, "info");
+ },
+
+ warn: function()
+ {
+ logFormatted(arguments, "warning");
+ },
+
+ error: function()
+ {
+ logFormatted(arguments, "error");
+ },
+
+ assert: function(truth, message)
+ {
+ if (!truth)
+ {
+ var args = [];
+ for (var i = 1; i < arguments.length; ++i)
+ args.push(arguments[i]);
+
+ logFormatted(args.length ? args : ["Assertion Failure"], "error");
+ throw message ? message : "Assertion Failure";
+ }
+ },
+
+ dir: function(object)
+ {
+ var html = [];
+
+ var pairs = [];
+ for (var name in object)
+ {
+ try
+ {
+ pairs.push([name, object[name]]);
+ }
+ catch (exc)
+ {
+ }
+ }
+
+ pairs.sort(function(a, b) { return a[0] < b[0] ? -1 : 1; });
+
+ html.push('<table>');
+ for (var i = 0; i < pairs.length; ++i)
+ {
+ var name = pairs[i][0], value = pairs[i][1];
+
+ html.push('<tr>',
+ '<td class="propertyNameCell"><span class="propertyName">',
+ escapeHTML(name), '</span></td>', '<td><span class="propertyValue">');
+ appendObject(value, html);
+ html.push('</span></td></tr>');
+ }
+ html.push('</table>');
+
+ logRow(html, "dir");
+ },
+
+ dirxml: function(node)
+ {
+ var html = [];
+
+ appendNode(node, html);
+ logRow(html, "dirxml");
+ },
+
+ group: function()
+ {
+ logRow(arguments, "group", pushGroup);
+ },
+
+ groupEnd: function()
+ {
+ logRow(arguments, "", popGroup);
+ },
+
+ time: function(name)
+ {
+ timeMap[name] = (new Date()).getTime();
+ },
+
+ timeEnd: function(name)
+ {
+ if (name in timeMap)
+ {
+ var delta = (new Date()).getTime() - timeMap[name];
+ logFormatted([name+ ":", delta+"ms"]);
+ delete timeMap[name];
+ }
+ },
+
+ count: function()
+ {
+ this.warn(["count() not supported."]);
+ },
+
+ trace: function()
+ {
+ this.warn(["trace() not supported."]);
+ },
+
+ profile: function()
+ {
+ this.warn(["profile() not supported."]);
+ },
+
+ profileEnd: function()
+ {
+ },
+
+ clear: function()
+ {
+ consoleBody.innerHTML = "";
+ },
+
+ open: function()
+ {
+ toggleConsole(true);
+ },
+
+ close: function()
+ {
+ if (frameVisible)
+ toggleConsole();
+ }
+ };
+
+ // ********************************************************************************************
+
+ var consoleFrame = null;
+ var consoleBody = null;
+ var commandLine = null;
+
+ var frameVisible = false;
+ var messageQueue = [];
+ var groupStack = [];
+ var timeMap = {};
+
+ var clPrefix = ">>> ";
+
+ var isFirefox = navigator.userAgent.indexOf("Firefox") != -1;
+ var isIE = navigator.userAgent.indexOf("MSIE") != -1;
+ var isOpera = navigator.userAgent.indexOf("Opera") != -1;
+ var isSafari = navigator.userAgent.indexOf("AppleWebKit") != -1;
+
+ // ********************************************************************************************
+
+ function toggleConsole(forceOpen)
+ {
+ frameVisible = forceOpen || !frameVisible;
+ if (consoleFrame)
+ consoleFrame.style.visibility = frameVisible ? "visible" : "hidden";
+ else
+ waitForBody();
+ }
+
+ function focusCommandLine()
+ {
+ toggleConsole(true);
+ if (commandLine)
+ commandLine.focus();
+ }
+
+ function waitForBody()
+ {
+ if (document.body)
+ createFrame();
+ else
+ setTimeout(waitForBody, 200);
+ }
+
+ function createFrame()
+ {
+ if (consoleFrame)
+ return;
+
+ window.onFirebugReady = function(doc)
+ {
+ window.onFirebugReady = null;
+
+ var toolbar = doc.getElementById("toolbar");
+ toolbar.onmousedown = onSplitterMouseDown;
+
+ commandLine = doc.getElementById("commandLine");
+ addEvent(commandLine, "keydown", onCommandLineKeyDown);
+
+ addEvent(doc, isIE || isSafari ? "keydown" : "keypress", onKeyDown);
+
+ consoleBody = doc.getElementById("log");
+ layout();
+ flush();
+ }
+
+ var baseURL = getFirebugURL();
+
+ consoleFrame = document.createElement("iframe");
+ consoleFrame.setAttribute("src", baseURL+"/firebug.html");
+ consoleFrame.setAttribute("frameBorder", "0");
+ consoleFrame.style.visibility = (frameVisible ? "visible" : "hidden");
+ consoleFrame.style.zIndex = "2147483647";
+ consoleFrame.style.position = "fixed";
+ consoleFrame.style.width = "100%";
+ consoleFrame.style.left = "0";
+ consoleFrame.style.bottom = "0";
+ consoleFrame.style.height = "200px";
+ document.body.appendChild(consoleFrame);
+ }
+
+ function getFirebugURL()
+ {
+ var scripts = document.getElementsByTagName("script");
+ for (var i = 0; i < scripts.length; ++i)
+ {
+ if (scripts[i].src.indexOf("firebug.js") != -1)
+ {
+ var lastSlash = scripts[i].src.lastIndexOf("/");
+ return scripts[i].src.substr(0, lastSlash);
+ }
+ }
+ }
+
+ function evalCommandLine()
+ {
+ var text = commandLine.value;
+ commandLine.value = "";
+
+ logRow([clPrefix, text], "command");
+
+ var value;
+ try
+ {
+ value = eval(text);
+ }
+ catch (exc)
+ {
+ }
+
+ console.log(value);
+ }
+
+ function layout()
+ {
+ var toolbar = consoleBody.ownerDocument.getElementById("toolbar");
+ var height = consoleFrame.offsetHeight - (toolbar.offsetHeight + commandLine.offsetHeight);
+ consoleBody.style.top = toolbar.offsetHeight + "px";
+ consoleBody.style.height = height + "px";
+
+ commandLine.style.top = (consoleFrame.offsetHeight - commandLine.offsetHeight) + "px";
+ }
+
+ function logRow(message, className, handler)
+ {
+ if (consoleBody)
+ writeMessage(message, className, handler);
+ else
+ {
+ messageQueue.push([message, className, handler]);
+ waitForBody();
+ }
+ }
+
+ function flush()
+ {
+ var queue = messageQueue;
+ messageQueue = [];
+
+ for (var i = 0; i < queue.length; ++i)
+ writeMessage(queue[i][0], queue[i][1], queue[i][2]);
+ }
+
+ function writeMessage(message, className, handler)
+ {
+ var isScrolledToBottom =
+ consoleBody.scrollTop + consoleBody.offsetHeight >= consoleBody.scrollHeight;
+
+ if (!handler)
+ handler = writeRow;
+
+ handler(message, className);
+
+ if (isScrolledToBottom)
+ consoleBody.scrollTop = consoleBody.scrollHeight - consoleBody.offsetHeight;
+ }
+
+ function appendRow(row)
+ {
+ var container = groupStack.length ? groupStack[groupStack.length-1] : consoleBody;
+ container.appendChild(row);
+ }
+
+ function writeRow(message, className)
+ {
+ var row = consoleBody.ownerDocument.createElement("div");
+ row.className = "logRow" + (className ? " logRow-"+className : "");
+ row.innerHTML = message.join("");
+ appendRow(row);
+ }
+
+ function pushGroup(message, className)
+ {
+ logFormatted(message, className);
+
+ var groupRow = consoleBody.ownerDocument.createElement("div");
+ groupRow.className = "logGroup";
+ var groupRowBox = consoleBody.ownerDocument.createElement("div");
+ groupRowBox.className = "logGroupBox";
+ groupRow.appendChild(groupRowBox);
+ appendRow(groupRowBox);
+ groupStack.push(groupRowBox);
+ }
+
+ function popGroup()
+ {
+ groupStack.pop();
+ }
+
+ // ********************************************************************************************
+
+ function logFormatted(objects, className)
+ {
+ var html = [];
+
+ var format = objects[0];
+ var objIndex = 0;
+
+ if (typeof(format) != "string")
+ {
+ format = "";
+ objIndex = -1;
+ }
+
+ var parts = parseFormat(format);
+ for (var i = 0; i < parts.length; ++i)
+ {
+ var part = parts[i];
+ if (part && typeof(part) == "object")
+ {
+ var object = objects[++objIndex];
+ part.appender(object, html);
+ }
+ else
+ appendText(part, html);
+ }
+
+ for (var i = objIndex+1; i < objects.length; ++i)
+ {
+ appendText(" ", html);
+
+ var object = objects[i];
+ if (typeof(object) == "string")
+ appendText(object, html);
+ else
+ appendObject(object, html);
+ }
+
+ logRow(html, className);
+ }
+
+ function parseFormat(format)
+ {
+ var parts = [];
+
+ var reg = /((^%|[^\\]%)(\d+)?(\.)([a-zA-Z]))|((^%|[^\\]%)([a-zA-Z]))/;
+ var appenderMap = {s: appendText, d: appendInteger, i: appendInteger, f: appendFloat};
+
+ for (var m = reg.exec(format); m; m = reg.exec(format))
+ {
+ var type = m[8] ? m[8] : m[5];
+ var appender = type in appenderMap ? appenderMap[type] : appendObject;
+ var precision = m[3] ? parseInt(m[3]) : (m[4] == "." ? -1 : 0);
+
+ parts.push(format.substr(0, m[0][0] == "%" ? m.index : m.index+1));
+ parts.push({appender: appender, precision: precision});
+
+ format = format.substr(m.index+m[0].length);
+ }
+
+ parts.push(format);
+
+ return parts;
+ }
+
+ function escapeHTML(value)
+ {
+ function replaceChars(ch)
+ {
+ switch (ch)
+ {
+ case "<":
+ return "<";
+ case ">":
+ return ">";
+ case "&":
+ return "&";
+ case "'":
+ return "'";
+ case '"':
+ return """;
+ }
+ return "?";
+ };
+ return String(value).replace(/[<>&"']/g, replaceChars);
+ }
+
+ function objectToString(object)
+ {
+ try
+ {
+ return object+"";
+ }
+ catch (exc)
+ {
+ return null;
+ }
+ }
+
+ // ********************************************************************************************
+
+ function appendText(object, html)
+ {
+ html.push(escapeHTML(objectToString(object)));
+ }
+
+ function appendNull(object, html)
+ {
+ html.push('<span class="objectBox-null">', escapeHTML(objectToString(object)), '</span>');
+ }
+
+ function appendString(object, html)
+ {
+ html.push('<span class="objectBox-string">"', escapeHTML(objectToString(object)),
+ '"</span>');
+ }
+
+ function appendInteger(object, html)
+ {
+ html.push('<span class="objectBox-number">', escapeHTML(objectToString(object)), '</span>');
+ }
+
+ function appendFloat(object, html)
+ {
+ html.push('<span class="objectBox-number">', escapeHTML(objectToString(object)), '</span>');
+ }
+
+ function appendFunction(object, html)
+ {
+ var reName = /function ?(.*?)\(/;
+ var m = reName.exec(objectToString(object));
+ var name = m ? m[1] : "function";
+ html.push('<span class="objectBox-function">', escapeHTML(name), '()</span>');
+ }
+
+ function appendObject(object, html)
+ {
+ try
+ {
+ if (object == undefined)
+ appendNull("undefined", html);
+ else if (object == null)
+ appendNull("null", html);
+ else if (typeof object == "string")
+ appendString(object, html);
+ else if (typeof object == "number")
+ appendInteger(object, html);
+ else if (typeof object == "function")
+ appendFunction(object, html);
+ else if (object.nodeType == 1)
+ appendSelector(object, html);
+ else if (typeof object == "object")
+ appendObjectFormatted(object, html);
+ else
+ appendText(object, html);
+ }
+ catch (exc)
+ {
+ }
+ }
+
+ function appendObjectFormatted(object, html)
+ {
+ var text = objectToString(object);
+ var reObject = /\[object (.*?)\]/;
+
+ var m = reObject.exec(text);
+ html.push('<span class="objectBox-object">', m ? m[1] : text, '</span>')
+ }
+
+ function appendSelector(object, html)
+ {
+ html.push('<span class="objectBox-selector">');
+
+ html.push('<span class="selectorTag">', escapeHTML(object.nodeName.toLowerCase()), '</span>');
+ if (object.id)
+ html.push('<span class="selectorId">#', escapeHTML(object.id), '</span>');
+ if (object.className)
+ html.push('<span class="selectorClass">.', escapeHTML(object.className), '</span>');
+
+ html.push('</span>');
+ }
+
+ function appendNode(node, html)
+ {
+ if (node.nodeType == 1)
+ {
+ html.push(
+ '<div class="objectBox-element">',
+ '<<span class="nodeTag">', node.nodeName.toLowerCase(), '</span>');
+
+ for (var i = 0; i < node.attributes.length; ++i)
+ {
+ var attr = node.attributes[i];
+ if (!attr.specified)
+ continue;
+
+ html.push(' <span class="nodeName">', attr.nodeName.toLowerCase(),
+ '</span>="<span class="nodeValue">', escapeHTML(attr.nodeValue),
+ '</span>"')
+ }
+
+ if (node.firstChild)
+ {
+ html.push('></div><div class="nodeChildren">');
+
+ for (var child = node.firstChild; child; child = child.nextSibling)
+ appendNode(child, html);
+
+ html.push('</div><div class="objectBox-element"></<span class="nodeTag">',
+ node.nodeName.toLowerCase(), '></span></div>');
+ }
+ else
+ html.push('/></div>');
+ }
+ else if (node.nodeType == 3)
+ {
+ html.push('<div class="nodeText">', escapeHTML(node.nodeValue),
+ '</div>');
+ }
+ }
+
+ // ********************************************************************************************
+
+ function addEvent(object, name, handler)
+ {
+ if (document.all)
+ object.attachEvent("on"+name, handler);
+ else
+ object.addEventListener(name, handler, false);
+ }
+
+ function removeEvent(object, name, handler)
+ {
+ if (document.all)
+ object.detachEvent("on"+name, handler);
+ else
+ object.removeEventListener(name, handler, false);
+ }
+
+ function cancelEvent(event)
+ {
+ if (document.all)
+ event.cancelBubble = true;
+ else
+ event.stopPropagation();
+ }
+
+ function onError(msg, href, lineNo)
+ {
+ var html = [];
+
+ var lastSlash = href.lastIndexOf("/");
+ var fileName = lastSlash == -1 ? href : href.substr(lastSlash+1);
+
+ html.push(
+ '<span class="errorMessage">', msg, '</span>',
+ '<div class="objectBox-sourceLink">', fileName, ' (line ', lineNo, ')</div>'
+ );
+
+ logRow(html, "error");
+ };
+
+ function onKeyDown(event)
+ {
+ if (event.keyCode == 123)
+ toggleConsole();
+ else if ((event.keyCode == 108 || event.keyCode == 76) && event.shiftKey
+ && (event.metaKey || event.ctrlKey))
+ focusCommandLine();
+ else
+ return;
+
+ cancelEvent(event);
+ }
+
+ function onSplitterMouseDown(event)
+ {
+ if (isSafari || isOpera)
+ return;
+
+ addEvent(document, "mousemove", onSplitterMouseMove);
+ addEvent(document, "mouseup", onSplitterMouseUp);
+
+ for (var i = 0; i < frames.length; ++i)
+ {
+ addEvent(frames[i].document, "mousemove", onSplitterMouseMove);
+ addEvent(frames[i].document, "mouseup", onSplitterMouseUp);
+ }
+ }
+
+ function onSplitterMouseMove(event)
+ {
+ var win = document.all
+ ? event.srcElement.ownerDocument.parentWindow
+ : event.target.ownerDocument.defaultView;
+
+ var clientY = event.clientY;
+ if (win != win.parent)
+ clientY += win.frameElement ? win.frameElement.offsetTop : 0;
+
+ var height = consoleFrame.offsetTop + consoleFrame.clientHeight;
+ var y = height - clientY;
+
+ consoleFrame.style.height = y + "px";
+ layout();
+ }
+
+ function onSplitterMouseUp(event)
+ {
+ removeEvent(document, "mousemove", onSplitterMouseMove);
+ removeEvent(document, "mouseup", onSplitterMouseUp);
+
+ for (var i = 0; i < frames.length; ++i)
+ {
+ removeEvent(frames[i].document, "mousemove", onSplitterMouseMove);
+ removeEvent(frames[i].document, "mouseup", onSplitterMouseUp);
+ }
+ }
+
+ function onCommandLineKeyDown(event)
+ {
+ if (event.keyCode == 13)
+ evalCommandLine();
+ else if (event.keyCode == 27)
+ commandLine.value = "";
+ }
+
+ window.onerror = onError;
+ addEvent(document, isIE || isSafari ? "keydown" : "keypress", onKeyDown);
+
+ if (document.documentElement.getAttribute("debug") == "true")
+ toggleConsole(true);
+})();
+}
Added: sandbox/tschaub/geojson/lib/Firebug/firebugx.js
===================================================================
--- sandbox/tschaub/geojson/lib/Firebug/firebugx.js (rev 0)
+++ sandbox/tschaub/geojson/lib/Firebug/firebugx.js 2007-05-23 22:54:22 UTC (rev 3164)
@@ -0,0 +1,10 @@
+
+if (!("console" in window) || !("firebug" in console))
+{
+ var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml",
+ "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
+
+ window.console = {};
+ for (var i = 0; i < names.length; ++i)
+ window.console[names[i]] = function() {}
+}
\ No newline at end of file
Added: sandbox/tschaub/geojson/lib/Firebug/infoIcon.png
===================================================================
(Binary files differ)
Property changes on: sandbox/tschaub/geojson/lib/Firebug/infoIcon.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: sandbox/tschaub/geojson/lib/Firebug/warningIcon.png
===================================================================
(Binary files differ)
Property changes on: sandbox/tschaub/geojson/lib/Firebug/warningIcon.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Modified: sandbox/tschaub/geojson/lib/OpenLayers/BaseTypes.js
===================================================================
--- sandbox/tschaub/geojson/lib/OpenLayers/BaseTypes.js 2007-05-23 20:18:45 UTC (rev 3163)
+++ sandbox/tschaub/geojson/lib/OpenLayers/BaseTypes.js 2007-05-23 22:54:22 UTC (rev 3164)
@@ -936,3 +936,25 @@
return __method.call(object, event || window.event);
}
};
+
+/*********************
+ * *
+ * CONSOLE *
+ * *
+ *********************/
+
+/**
+ * Create empty functions for all console methods. The real value of these
+ * properties will be set if the Firebug/DebugOpenLayers.js script is included
+ * after OpenLayers.js.
+ */
+
+OpenLayers.console = {};
+(function() {
+ var methods = ['log', 'debug', 'info', 'warn', 'error', 'assert',
+ 'dir', 'dirxml', 'trace', 'group', 'groupEnd', 'time',
+ 'timeEnd', 'profile', 'profileEnd', 'count'];
+ for(var i=0; i<methods.length; ++i) {
+ OpenLayers.console[methods[i]] = function() {};
+ }
+})();
\ No newline at end of file
Modified: sandbox/tschaub/geojson/lib/OpenLayers/Format/GeoJSON.js
===================================================================
--- sandbox/tschaub/geojson/lib/OpenLayers/Format/GeoJSON.js 2007-05-23 20:18:45 UTC (rev 3163)
+++ sandbox/tschaub/geojson/lib/OpenLayers/Format/GeoJSON.js 2007-05-23 22:54:22 UTC (rev 3164)
@@ -13,38 +13,146 @@
/**
* Deserialize a GeoJSON string.
* @param {String} json A GeoJSON string
+ * @param {String} type Optional string that determines the structure of
+ * the output. Supported values are "Geometry",
+ * "Feature", "GeometryCollection", and
+ * "FeatureCollection". If absent or null, a
+ * default of "FeatureCollection" is assumed.
* @param {Function} filter A function which will be called for every key
* and value at every level of the final result.
* Each value will be replaced by the result of
* the filter function. This can be used to reform
* generic objects into instances of classes, or to
* transform date strings into Date objects.
- * @returns {Array(OpenLayers.Feature.Vector)} An array of features
+ * @returns {Object} The return depends on the value of the type argument.
+ * If type is "FeatureCollection" (the default), the
+ * return will be an array of OpenLayers.Feature.Vector.
+ * If type is "Geometry", the input json must represent a
+ * single geometry, and the return will be an
+ * OpenLayers.Geometry. If type is "Feature", the input
+ * json must represent a single feature, and the return
+ * will be an OpenLayers.Feature.Vector. If type is
+ * "GeometryCollection", the input json must represent
+ * a geometry collection, and the return will be an array
+ * of OpenLayers.Geometry.
*/
- read: function(json, filter) {
+ read: function(json, type, filter) {
+ type = (!!type) ? type : "FeatureCollection";
+ var results = null;
var obj = OpenLayers.Format.JSON.prototype.read.apply(this, [json, filter]);
- var features = [];
- var f = null;
- if(!(obj.features instanceof Array)) {
- // deal with bad GeoJSON
- //OpenLayers.console.error("Bad GeoJSON: " + obj);
- } else {
- for(var i=0; i<obj.features.length; ++i) {
- try {
- f = this.parseFeature(obj.features[i]);
- features.push(f);
- } catch(err) {
- // deal with bad features
- //OpenLayers.console.error('Bad Features:' + err);
- }
+ if(!obj) {
+ OpenLayers.console.error("Bad JSON: " + json);
+ } else if(typeof(obj.type) != "string") {
+ OpenLayers.console.error("Bad GeoJSON - no type: " + json);
+ } else if(this.isValidType(obj, type)) {
+ switch(type) {
+ case "Geometry":
+ try {
+ results = this.parseGeometry(obj);
+ } catch(err) {
+ OpenLayers.console.error(err);
+ }
+ break;
+ case "Feature":
+ try {
+ results = this.parseFeature(obj);
+ resutls.type = "Feature";
+ } catch(err) {
+ OpenLayers.console.error(err);
+ }
+ break;
+ case "GeometryCollection":
+ results = [];
+ for(var i=0; i<obj.geometries.length; ++i) {
+ try {
+ results.push(this.parseGeometry(obj.geometries[i]));
+ } catch(err) {
+ results = null;
+ OpenLayers.console.error(err);
+ }
+ }
+ break;
+ case "FeatureCollection":
+ // for type FeatureCollection, we allow input to be any type
+ results = [];
+ switch(obj.type) {
+ case "Feature":
+ try {
+ results.push(this.parseFeature(obj));
+ } catch(err) {
+ results = null;
+ OpenLayers.console.error(err);
+ }
+ break;
+ case "FeatureCollection":
+ for(var i=0; i<obj.members.length; ++i) {
+ try {
+ results.push(this.parseFeature(obj.members[i]));
+ } catch(err) {
+ results = null;
+ OpenLayers.console.error(err);
+ }
+ }
+ break;
+ case "GeometryCollection":
+ for(var i=0; i<obj.members.length; ++i) {
+ try {
+ var geom = this.parseGeometry(obj.members[i]);
+ results.push(new OpenLayers.Feature.Vector(geom));
+ } catch(err) {
+ results = null;
+ OpenLayers.console.error(err);
+ }
+ }
+ break;
+ default:
+ try {
+ var geom = this.parseGeometry(obj);
+ results.push(new OpenLayers.Feature.Vector(geom));
+ } catch(err) {
+ results = null;
+ OpenLayers.console.error(err);
+ }
+ }
+ break;
}
}
- return features;
+ return results;
},
+ isValidType: function(obj, type) {
+ var valid = false;
+ switch(type) {
+ case "Geometry":
+ if(OpenLayers.Util.indexOf(["Point", "MultiPoint", "LineString",
+ "MultiLineString", "Polygon",
+ "MutiPolygon", "Box"], obj.type) == -1) {
+ // unsupported geometry type
+ OpenLayers.console.error("Unsupported geometry type: " +
+ obj.type);
+ } else {
+ valid = true;
+ }
+ break;
+ case "FeatureCollection":
+ // allow for any type to be converted to a feature collection
+ valid = true;
+ break
+ default:
+ // for GeometryCollection and Feature, types must match
+ if(obj.type == type) {
+ valid = true;
+ } else {
+ OpenLayers.console.error("Cannot convert types from " +
+ obj.type + " to " + type);
+ }
+ }
+ return valid;
+ },
+
/**
* Convert a feature object from GeoJSON into an OpenLayers.Feature.Vector.
- * @param {Object} obj An object created from a GeoJSON fragment
+ * @param {Object} obj An object created from a GeoJSON object
* @returns {OpenLayers.Feature.Vector} A feature
* @private
*/
@@ -63,7 +171,7 @@
/**
* Convert a geometry object from GeoJSON into an OpenLayers.Geometry.
- * @param {Object} obj An object created from a GeoJSON fragment
+ * @param {Object} obj An object created from a GeoJSON object
* @returns {OpenLayers.Geometry} A geometry
* @private
*/
@@ -97,14 +205,10 @@
* @private
*/
"point": function(array) {
- if(array.length != 1) {
- throw "Bad point coordinates: " + array;
+ if(array.length != 2) {
+ throw "Only 2D points are supported: " + array;
}
- if(array[0].length != 2) {
- throw "Only 2D points are supported: " + array[0];
- }
- // let this [[x, y]] be gone please
- return new OpenLayers.Geometry.Point(array[0][0], array[0][1]);
+ return new OpenLayers.Geometry.Point(array[0], array[1]);
},
/**
@@ -117,7 +221,11 @@
var points = [];
var p = null;
for(var i=0; i<array.length; ++i) {
- p = this.parseCoords["point"].apply(this, [[array[i]]]);
+ try {
+ p = this.parseCoords["point"].apply(this, [array[i]]);
+ } catch(err) {
+ throw err;
+ }
points.push(p);
}
return new OpenLayers.Geometry.MultiPoint(points);
@@ -133,7 +241,11 @@
var points = [];
var p = null;
for(var i=0; i<array.length; ++i) {
- p = this.parseCoords["point"].apply(this, [[array[i]]]);
+ try {
+ p = this.parseCoords["point"].apply(this, [array[i]]);
+ } catch(err) {
+ throw err;
+ }
points.push(p);
}
return new OpenLayers.Geometry.LineString(points);
@@ -149,7 +261,11 @@
var lines = [];
var l = null;
for(var i=0; i<array.length; ++i) {
- l = this.parseCoords["linestring"].apply(this, [array[i]]);
+ try {
+ l = this.parseCoords["linestring"].apply(this, [array[i]]);
+ } catch(err) {
+ throw err;
+ }
lines.push(l);
}
return new OpenLayers.Geometry.MultiLineString(lines);
@@ -165,13 +281,17 @@
var rings = [];
var r, l;
for(var i=0; i<array.length; ++i) {
- l = this.parseCoords["linestring"].apply(this, [array[i]]);
+ try {
+ l = this.parseCoords["linestring"].apply(this, [array[i]]);
+ } catch(err) {
+ throw err;
+ }
r = new OpenLayers.Geometry.LinearRing(l.components);
rings.push(r);
}
return new OpenLayers.Geometry.Polygon(rings);
},
-
+
/**
* Convert a coordinate array from GeoJSON into an OpenLayers.Geometry.
* @param {Object} array The coordinates array from the GeoJSON fragment
@@ -182,60 +302,122 @@
var polys = [];
var p = null;
for(var i=0; i<array.length; ++i) {
- p = this.parseCoords["polygon"].apply(this, [array[i]]);
+ try {
+ p = this.parseCoords["polygon"].apply(this, [array[i]]);
+ } catch(err) {
+ throw err;
+ }
polys.push(p);
}
return new OpenLayers.Geometry.MultiPolygon(polys);
+ },
+
+ /**
+ * Convert a coordinate array from GeoJSON into an OpenLayers.Geometry.
+ * @param {Object} array The coordinates array from the GeoJSON fragment
+ * @returns {OpenLayers.Geometry} A geometry
+ * @private
+ */
+ "box": function(array) {
+ if(array.length != 4) {
+ throw "GeoJSON box coordinates must have 4 elements";
+ }
+ return new OpenLayers.Geometry.Polygon([
+ new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point(array[0], array[1]),
+ new OpenLayers.Geometry.Point(array[2], array[1]),
+ new OpenLayers.Geometry.Point(array[2], array[3]),
+ new OpenLayers.Geometry.Point(array[0], array[3]),
+ new OpenLayers.Geometry.Point(array[0], array[1])
+ ])
+ ]);
}
},
/**
- * Serialize an array of features into a GeoJSON string.
- * @param {Array} features An array of OpenLayers.Feature.Vector
- * @returns {String} The GeoJSON string representation of the input features
+ * Serialize a feature, geometry, array of features, or array of geometries
+ * into a GeoJSON string.
+ * @param {Object} obj An OpenLayers.Feature.Vector, OpenLayers.Geometry,
+ * or an array of either features or geometries.
+ * @returns {String} The GeoJSON string representation of the input geometry,
+ * features, array of geometries, or array of features.
*/
- write: function(features) {
- var feature, geometry, type, data, crs;
- var array = [];
- try {
- crs = features[0].layer.projection;
- } catch(e) {
- crs = null;
- }
- for(var i=0; i<features.length; ++i) {
- feature = features[i];
- geometry = feature.geometry;
- type = geometry.CLASS_NAME.split('.')[2];
- data = this.extract[type.toLowerCase()].apply(this, [geometry]);
- // please let this go away
- if(type == "Point") {
- data = [data];
- }
- array.push({
- 'id': feature.id,
- 'properties': feature.attributes,
- 'geometry': {
- 'type': type,
- 'coordinates': data
+ write: function(obj) {
+ var geojson = {
+ "type": null
+ };
+ if(obj instanceof Array) {
+ geojson.members = [];
+ for(var i=0; i<obj.length; ++i) {
+ var element = obj[i];
+ if(element instanceof OpenLayers.Feature.Vector) {
+ if(geojson.type == null) {
+ geojson.type = "FeatureCollection";
+ } else if(geojson.type != "FeatureCollection") {
+ OpenLayers.console.error("FeatureCollection only supports collections of features: " + element);
+ break;
+ }
+ geojson.members.push(this.extract.feature.apply(this, [element]));
+ } else if (element instanceof OpenLayers.Geometry) {
+ if(geojson.type == null) {
+ geojson.type = "GeometryCollection";
+ } else if(geojson.type != "GeometryCollection") {
+ OpenLayers.console.error("GeometryCollection only supports collections of geometries: " + element);
+ break;
+ }
+ geojson.members.push(this.extract.geometry.apply(this, [element]));
}
- });
+ }
+ } else if (obj instanceof OpenLayers.Geometry) {
+ geojson = this.extract.geometry.apply(this, [obj]);
+ } else if (obj instanceof OpenLayers.Feature.Vector) {
+ geojson = this.extract.feature.apply(this, [obj]);
}
- return OpenLayers.Format.JSON.prototype.write.apply(this, [{
- 'features': array,
- 'crs': crs
- }]);
+ return OpenLayers.Format.JSON.prototype.write.apply(this, [geojson]);
},
/**
- * Object with properties corresponding to the geometry types.
+ * Object with properties corresponding to the GeoJSON types.
* Property values are functions that do the actual value extraction.
*/
extract: {
/**
+ * Return a partial GeoJSON object representing a single feature.
+ * @param {OpenLayers.Feature.Vector} feature
+ * @returns {Object} An object representing the point
+ * @private
+ */
+ 'feature': function(feature) {
+ var geom = this.extract.geometry.apply(this, [feature.geometry]);
+ return {
+ "type": "Feature",
+ "id": feature.id,
+ "properties": feature.attributes,
+ "geometry": geom
+ }
+ },
+
+ /**
+ * Return a GeoJSON object representing a single geometry.
+ * @param {OpenLayers.Geometry} point
+ * @returns {Object} An object representing the geometry
+ * @private
+ */
+ 'geometry': function(geometry) {
+ var geometryType = geometry.CLASS_NAME.split('.')[2];
+ var data = this.extract[geometryType.toLowerCase()].apply(this, [geometry]);
+ return {
+ "type": geometryType,
+ "coordinates": data
+ }
+ },
+
+ /**
* Return an array of coordinates from a point.
* @param {OpenLayers.Geometry.Point} point
* @returns {Array} An array of coordinates representing the point
+ * @private
*/
'point': function(point) {
return [point.x, point.y];
@@ -246,6 +428,7 @@
* @param {OpenLayers.Geometry.MultiPoint} multipoint
* @returns {Array} An array of point coordinate arrays representing
* the multipoint
+ * @private
*/
'multipoint': function(multipoint) {
var array = [];
@@ -260,6 +443,7 @@
* @param {OpenLayers.Geometry.LineString} linestring
* @returns {Array} An array of coordinate arrays representing
* the linestring
+ * @private
*/
'linestring': function(linestring) {
var array = [];
@@ -274,6 +458,7 @@
* @param {OpenLayers.Geometry.MultiLineString} linestring
* @returns {Array} An array of linestring arrays representing
* the multilinestring
+ * @private
*/
'multilinestring': function(multilinestring) {
var array = [];
@@ -287,6 +472,7 @@
* Return an array of linear ring arrays from a polygon.
* @param {OpenLayers.Geometry.Polygon} polygon
* @returns {Array} An array of linear ring arrays representing the polygon
+ * @private
*/
'polygon': function(polygon) {
var array = [];
@@ -301,6 +487,7 @@
* @param {OpenLayers.Geometry.MultiPolygon} multipolygon
* @returns {Array} An array of polygon arrays representing
* the multipolygon
+ * @private
*/
'multipolygon': function(multipolygon) {
var array = [];
More information about the Commits
mailing list