POI-Editor (Netzwolf)

Hallo,

auf der Suche nach einem Skript für das Setzen und Bearbeiten von POI´s, bin ich auf die Seite von Netzwolf gestoßen:
http://www.netzwolf.info/kartografie/openlayers/poi_editor
der ganau das macht, was ich benötige - die POI-Daten in MySql abspeichert.
Leider fehlt auf seiner Seite jegliche Kontakt-Angabe.

Das ganze läuft über eine CSV-Datei, die dann in die MySql-Datenbank eingelesen wird.
Hier liegt mein Problem: Wo wird der Name der CSV-Datei abgefragt, d.h. welchen Namen muß ich der Datei geben? (habe poi_editor.csv gewählt)
Trotz intensiver Suche habe ich nichts gefunden.
Ich bekomme lediglich die Meldung : Error loading file "pioserver.phtml?db=demo&limit …not a CSV file.

Ich gehe davon aus, daß der Poi-Editor im OpenStreeMap-Forum bekannt ist, falls nicht, hier das Skript poiserver.phtml
und popupmarker.js in denen ein Aufruf der CSV-Datei in irgendeiner Form enthalten sein müßte!?

Kann mir bitte einer von euch helfen?

<?php
#--------------------------------------------------------------------------------
#	$Id: poiserver.phtml,v 1.2 2012/03/21 12:24:58 wolf Exp wolf $
#--------------------------------------------------------------------------------

$RESULT_SIZE_LIMIT	= 2000;
$RESULT_SIZE_DEFAULT	= 100;
$MYSQL_SERVER		= "localhost";
$MYSQL_USER		= "root";
$MYSQL_PASSWORD		= "";
$MYSQL_DATABASE		= "poi";
$TABLE_NAME_PREFIX	= "poi_demo";

#-----------------------------------------------------
#	Get credentials from outside html tree
#-----------------------------------------------------

require_once 'mysql/login.php';

#-----------------------------------------------------
#	Get db table name from "db="
#-----------------------------------------------------

if (!preg_match ('#^(\w+)$#', $_GET['db'], $match)) {
	Fail ("parameter 'db=' missing or invalid");
}

$tableName = "{$TABLE_NAME_PREFIX}{$match[1]}";

#-----------------------------------------------------
#	Get limit for result records from "limit="
#-----------------------------------------------------

$limit = @intval (@$_GET['limit']);
if ($limit<1)
	$limit = $RESULT_SIZE_DEFAULT;
if ($limit>$RESULT_SIZE_LIMIT)
	$limit = $RESULT_SIZE_LIMIT;

#-----------------------------------------------------
#	Connect to server
#-----------------------------------------------------

if (!@mysql_connect ($MYSQL_SERVER, $MYSQL_USER, $MYSQL_PASSWORD)) Fail();

#-----------------------------------------------------
#	Select database
#-----------------------------------------------------

if (!@mysql_select_db ($MYSQL_DATABASE)) Fail();

#-----------------------------------------------------
#	Empty read to get meta data
#-----------------------------------------------------

$query = "SELECT * FROM {$tableName} WHERE FALSE";
$result = @mysql_query ($query);

if (!$result) Fail();

#-----------------------------------------------------
#	Build tables of metadata
#-----------------------------------------------------

$fieldNames=array();
$fieldTypes=array();
$fieldCodes=array();

$nFields = mysql_num_fields($result);
for ($i=0; $i<$nFields; $i++) {

	$name = mysql_field_name ($result, $i);
	if ($name=='mtime') continue;
	$fieldNames[$name] = $name;
	#---------------------------------------------
	#	BOOL-emulation
	#---------------------------------------------
	$type = mysql_field_type ($result, $i);
	if ($type=='int' && mysql_field_len($result, $i)==1) $type='bool';
	$fieldTypes[$name] = $type;
	$fieldCodes[$name] = $type=='bool' ? "IF ({$name}<>0, 't', 'f')" : $name;
}

#-----------------------------------------------------
#	Needs id, lat, lon
#-----------------------------------------------------

if (!isset($fieldNames['id'   ])) Fail ("db: no id");
if (!isset($fieldNames['lat'  ])) Fail ("db: no lat");
if (!isset($fieldNames['lon'  ])) Fail ("db: no lon");

#-----------------------------------------------------
#	Condition for select
#-----------------------------------------------------

$Conds = array();

#-----------------------------------------------------
#	Process $_POST-Data (Insert, Update)
#-----------------------------------------------------

if (count ($_POST)) {

	$fields = array();
	$values = array();
	$assigns= array();

	#---------------------------------------------------
	#	COMMAND
	#---------------------------------------------------

	$command = $_POST['COMMAND'];
	unset ($_POST['COMMAND']);

	#---------------------------------------------------
	#	fields
	#---------------------------------------------------

	foreach ($_POST as $field => $value) {

		if (!preg_match ('#^(\w+)$#', $field, $match)) {
			Fail ("invalid post field '{$field}'");
		}

		$field = $match[1];

		if (!isset ($fieldNames[$field])) {
			Fail ("field '{$field}' not in db table");
		}

		if ($field=='id' || $field=='mtime') continue;

		if ($fieldTypes[$field]=='bool') {
			$value = preg_match ('#^[tT1]#', $value) ? 1 : 0;
		}

		$sqlField = $field;
		$sqlValue = "'" . mysql_real_escape_string ($value) . "'";

		$fields[] = $sqlField;
		$values[] = $sqlValue;
		$assigns[]= "{$sqlField}={$sqlValue}";
	}

	#---------------------------------------------------
	#	id
	#---------------------------------------------------

	$id = @intval ($_POST['id']);

	#---------------------------------------------------
	#	UPDATE
	#---------------------------------------------------

	if ($id > 0 && count($assigns)>0) {

		$assignList = join (', ', $assigns);

		$query = "UPDATE {$tableName} SET {$assignList} WHERE id={$id};";

		$result = mysql_query ($query);

		if (!$result) Fail();
	}

	#---------------------------------------------------
	#	DELETE
	#---------------------------------------------------

	if ($id > 0 && $command=='DELETE') {

		$query = "DELETE FROM {$tableName} WHERE id={$id};";

		$result = mysql_query ($query);

		if (!$result) Fail();
	}

	#---------------------------------------------------
	#	INSERT?
	#---------------------------------------------------

	if ($id < 0) {

		$data = "DEFAULT VALUES";
		if (count($fields)) {
			$fieldList = join (', ', $fields);
			$valueList = join (', ', $values);
			$data = "({$fieldList}) VALUES ({$valueList});";
		}

		$query = "INSERT INTO {$tableName} $data";
		$result = mysql_query ($query);

		if (!$result) Fail();

		$id = mysql_insert_id();
	}

	#---------------------------------------------------
	#	Condition to get exactly this (or no) record
	#---------------------------------------------------

	$sqlValue = "'" . mysql_real_escape_string ($id) . "'";
	$Conds[] = "id={$sqlValue}";

} else {

#-----------------------------------------------------
#	Process $_GET query conditions
#-----------------------------------------------------

	$unknownFields = array();
	$unknownOps    = array();

	foreach ($_GET as $tag => $value) {

		#-----------------------------------------------------
		#	Skip conditions w/o value
		#-----------------------------------------------------

		$value = trim ($value);
		if ($value=='') continue;

		#-----------------------------------------------------
		#	Conditions look like:
		#	[field].[operator]=[value]
		#-----------------------------------------------------

		if (!preg_match ('#^(\w+)[.-]([a-z]+)$#', $tag, $match))
			continue;

		$field	= $match[1];
		$op	= $match[2];

		#-----------------------------------------------------
		#	Check fieldname
		#-----------------------------------------------------

		if (!$fieldNames[$field]) {
			@$unknownFields[$field]++;
			continue;
		}

		#-----------------------------------------------------
		#	Check operator
		#-----------------------------------------------------

		$sqlValue = "'" . mysql_real_escape_string ($value) . "'";
		$sqlField = $field;

		switch ($op) {

		case 'eq':
		case 'seq':
			$Conds[] = "{$sqlField} = {$sqlValue}";
			break;
		case 'ne':
		case 'sne':
			$Conds[] = "{$sqlField} <> {$sqlValue}";
			break;
		case 'le':
		case 'sle':
			$Conds[] = "{$sqlField} <= {$sqlValue}";
			break;
		case 'lt':
		case 'slt':
			$Conds[] = "{$sqlField} < {$sqlValue}";
			break;
		case 'ge':
		case 'sge':
			$Conds[] = "{$sqlField} >= {$sqlValue}";
			break;
		case 'gt':
		case 'sgt':
			$Conds[] = "{$sqlField} > {$sqlValue}";
			break;
		default:
			$unknownOps[$op]++;
			continue;
		}
	}

	#-----------------------------------------------------
	#	Unknown fieldnames?
	#-----------------------------------------------------

	if (count($unknownFields)) {
		$names = join (', ', array_keys ($unknownFields));
		Fail ("Unknown field(s): {$names}");
	}

	#-----------------------------------------------------
	#	Unknown operators?
	#-----------------------------------------------------

	if (count($unknownOps)) {
		$names = join ('* ', array_keys ($unknownOps));
		Fail ("Unknown operator(s): {$names}");
	}
}

#-----------------------------------------------------
#	SELECT query
#-----------------------------------------------------

$WHERE = "";
if (count ($Conds)) $WHERE = "WHERE " . join (' AND ', $Conds);

$codesList = join (', ', $fieldCodes);

$query = "SELECT {$codesList} FROM {$tableName} {$WHERE} ORDER BY mtime DESC LIMIT {$limit};";
$result= mysql_query ($query);

if (!$result) Fail();

#-----------------------------------------------------
#	HTTP header
#-----------------------------------------------------

header ("Content-Type: text/csv; charset=utf-8");

#-----------------------------------------------------
#	CSV header
#-----------------------------------------------------

echo join ("\t", $fieldNames), "\n";

#-----------------------------------------------------
#	CSV body
#-----------------------------------------------------

while ($values = mysql_fetch_row ($result)) {

	for ($i=0; $i<count($values); $i++) {
		if ($i>0) echo "\t";
		echo str_replace (array ("\t", "\n"), array (" ", "\034"), $values[$i]);
	}
	echo "\n";
}

exit ();

#-----------------------------------------------------
#	Error handler
#-----------------------------------------------------

function Fail ($msg='') {
	if (!$msg) $msg = mysql_error();
	header ("HTTP/1.0 400 Bad request");
	header ("Content-Type: text/plain; charset=utf-8");
	echo "ERROR: {$msg}";
	exit ();
}

#--------------------------------------------------------------------------------
#	$Id: poiserver.phtml,v 1.2 2012/03/21 12:24:58 wolf Exp wolf $
#--------------------------------------------------------------------------------
?>

	$Id: popupmarker.js,v 1.84 2012/03/21 12:49:43 wolf Exp wolf $
//--------------------------------------------------------------------------------
//	Erklaerung:	http://www.netzwolf.info/kartografie/openlayers/#csv
//--------------------------------------------------------------------------------
//	Fragen, Wuensche, Bedenken, Anregungen?
//	<openlayers(%40)netzwolf.info>
//--------------------------------------------------------------------------------
//
//	$Log: popupmarker.js,v $
//	Revision 1.84  2012/03/21 12:49:43  wolf
//	+ authentication vorbereitet.
//
//	Revision 1.83  2012/03/20 15:40:16  wolf
//	+ label
//	+ enableLocate
//
//	Revision 1.82  2012/03/19 23:25:40  wolf
//	*** empty log message ***
//
//	Revision 1.81  2012/03/19 22:48:15  wolf
//	+ enableDelete
//
//	Revision 1.79  2012/03/10 14:01:50  wolf
//	+ POI-Edit
//
//	Revision 1.77  2012/03/09 10:01:23  wolf
//	* Anpassung an Opera.
//
//	Revision 1.76  2012/03/08 10:33:00  wolf
//	+ minZoom auch für Markeredit.
//
//	Revision 1.75  2012/03/07 23:54:19  wolf
//	+ Editmarker: textarea, checkbox, radiobutton
//
//	Revision 1.74  2012/03/07 20:17:40  wolf
//	* Markereditor + Select-Felder.
//
//	Revision 1.73  2012/03/07 19:48:11  wolf
//	+ selectValues.
//
//	Revision 1.72  2012/03/07 17:15:23  wolf
//	* Vorbereitung Markereditor.
//
//	Revision 1.71  2012/03/03 12:42:32  wolf
//	* wrap() um diverse trim() ergänzt.
//
//	Revision 1.70  2012/03/02 13:07:28  wolf
//	* Interaktion clickDistance und Popups modifiziert.
//
//	Revision 1.69  2012/03/01 11:15:22  wolf
//	* utf8->ascii
//
//	Revision 1.68  2012/03/01 10:45:10  wolf
//	+ clickDistance
//
//	Revision 1.67  2012/02/29 23:58:35  wolf
//	* Vorbereitung editierbare Marker.
//
//	Revision 1.66  2012/02/28 10:12:39  wolf
//	+ tooltip: wrap: <br/> erlaubt.
//
//	Revision 1.65  2012/02/26 20:08:28  wolf
//	+ closeOnClick
//
//	Revision 1.62  2012/02/25 13:05:40  wolf
//	+ tooltip-Size durch Formatierung
//
//	Revision 1.60  2012/02/12 23:37:01  wolf
//	+ createEditPopup()
//
//	Revision 1.59  2012/02/12 19:19:50  wolf
//	* tileSize -> blockSize
//	+ destroyMarker(m)
//	+ destroyMarkers()
//	+ !blockSize -> no cache, destroy before add.
//
//	Revision 1.58  2012/02/09 23:58:25  wolf
//	*** empty log message ***
//
//	Revision 1.57  2012/02/09 23:53:57  wolf
//	+ tooltip
//
//	Revision 1.56  2012/01/15 02:08:59  wolf
//	+ updateSize()
//
//	Revision 1.55  2011/09/17 11:23:49  wolf
//	* OpenLayers.Lang.en war undefiniert.
//
//	Revision 1.53  2011/06/07 08:06:27  wolf
//	+ formatValue
//
//	Revision 1.52  2011/05/30 18:21:48  wolf
//	* bessere Anzeige von XmlHttpRequest-Fehlern
//
//	Revision 1.51  2011/05/27 09:06:50  wolf
//	*** empty log message ***
//
//	Revision 1.50  2010/12/20 19:48:30  wolf
//	+ createOsmLinks + parameter id
//
//	Revision 1.47  2010/11/25 11:59:54  wolf
//	+ filter
//
//	Revision 1.42  2010/09/18 17:56:31  wolf
//	+ selectmarker
//	+ delayedPopup
//
//	Revision 1.40  2010/09/15 08:23:15  wolf
//	+ restrictMapExtent
//
//	Revision 1.39  2010/09/06 16:26:29  wolf
//	+ Nachladen nur wenn Layer sichtbar
//
//	Revision 1.37  2010/09/02 11:20:41  wolf
//	+ kein click bei Shift-Taste
//
//	Revision 1.34  2010/08/30 12:55:17  wolf
//	+ popupOnHover
//
//	Revision 1.33  2010/08/30 09:28:30  wolf
//	+ zoomSteps
//
//	Revision 1.29  2010/08/15 12:48:46  wolf
//	+ busyMarker
//
//	Revision 1.26  2010/08/15 06:47:18  wolf
//	* Quickfix: this.zindex
//
//	Revision 1.22  2010/05/20 11:53:58  wolf
//	* autoid=string
//
//	Revision 1.21  2010/04/20 09:22:48  wolf
//	+ Icons einblenden und ausblenden
//
//	Revision 1.20  2010/04/20 06:52:30  wolf
//	+ _cref, _crefdel, _csize
//
//	Revision 1.17  2010/04/07 18:03:59  wolf
//	+ ClusterMarker
//
//	Revision 1.16  2010/03/02 18:36:44  wolf
//	+ Klassen fuer MarkerIcons
//
//	Revision 1.15  2010/03/02 01:56:55  wolf
//	+ Entries w/o coordinates
//
//	Revision 1.14  2010/02/22 21:33:59  wolf
//	+ clusterLimit Default=10
//
//	Revision 1.13  2010/02/22 18:30:55  wolf
//	+ clusterLimit
//
//	Revision 1.9  2010/02/20 16:36:34  wolf
//	+overlap handling
//
//	Revision 1.4  2010/01/26 20:52:19  wolf
//	* ueberzaehliges "," vor "}" in Obektdefinition getilgt.
//
//	Revision 1.1  2010/01/21 10:29:17  wolf
//	Initial Revision
//
//--------------------------------------------------------------------------------

if (!OpenLayers.Lang.en)
	OpenLayers.Lang.en = {};
if (!OpenLayers.Lang.en.errorLoadingCSV)
	OpenLayers.Lang.en.errorLoadingCSV = 'Error loading CSV file "${url}": ${phase}';

OpenLayers.Layer.PopupMarker = OpenLayers.Class(OpenLayers.Layer.Markers,{

	popupOnHover: true,
	popupOnClick: true,
	restrictMapExtent: false,
	location: null,
	fieldSeparator: "\t",
	defaultIcon: null,
	popupClass:OpenLayers.Popup.AnchoredBubble,
	createIconFromData: null,
	createUrlForBounds: null,
	editUrl: null,
	requestUser: null,
	requestPassword: null,
	requestAsync: true,
	clickHandler: null,
	opacity: null,
	minZoom: 10,
	lastZoom: -1,
	blockSize: 0.1,
	clusterSize: 0,
	clusterSort: null,
	clusterLimit: 10,
	zindex: null,
	cloudImage: null,
	zoomSteps: null,
	hideMarkerBelowMinZoom: false,
	region: null,			// XXX experimental
	maxTooltipWidth: null,
	closeOnClick: false,		// close by click into popup
	clickDistance: 0,		// open by click near to marker
	fieldTitles: null,
	fieldTypes: {},
	fieldValues: {},
	enableUpdate: false,
	enableCreate: false,
	enableDelete: false,
	enableLocate: false,
	locateId: null,

	labelEdit: 'Bearbeiten',
	labelDelete: 'Löschen',
	labelConfirmDelete: 'Marker permanent löschen?',
	labelLocate: 'Verschieben',
	locateMarker: null,

	//---------------------------------------------------------
	//	Init
	//---------------------------------------------------------

	initialize: function(name, options) {

		OpenLayers.Layer.Markers.prototype.initialize.apply(this,arguments);

		this.erase();

		this.loadBounds		= null;
		this.loadedBounds	= null;
		this.loadingUrl		= null;
		this.nextId		= 0;

		if (this.opacity ) this.setOpacity(opacity);
		if (this.minZoom) this.zoomSteps = 1<<this.minZoom;

		this.currentMarker = null;
	},

	destroy: function () {

		if (this.clickHandler) this.clickHandler.destroy();
		this.erase();
	},

	afterAdd: function() {

		if (this.location) this.request(this.location);

		if (this.enableCreate || this.clickDistance>0 || this.enableLocate) {
			this.clickHandler = new OpenLayers.Handler.Click (this,
				{'click': this.click}, {'single': true});
			this.clickHandler.activate();
		}
	},

	//---------------------------------------------------------
	//	click to create marker
	//---------------------------------------------------------

	click: function(ev) {

		if (this.locateMarker) {

			var marker = this.locateMarker;

			this.map.div.style.cursor = null;
			this.locateMarker = null;
			this.setVisibility(true);

			if (ev.shiftKey || ev.ctrlKey) return;

			var lonLat=this.map.getLonLatFromViewPortPx(ev.xy);
			//marker.moveTo (this.map.getLayerPxFromLonLat(lonLat));

			lonLat.transform(this.map.getProjectionObject(),this.map.displayProjection);
			marker.data.lat = lonLat.lat;
			marker.data.lon = lonLat.lon;

			var postData = OpenLayers.Util.getParameterString (marker.data);
			this.updateMarkerOnServer (marker, postData);

			return;
		}

		if (!this.visibility) return;

		if (this.clickDistance>0 && !ev.ctrlKey && !ev.shiftKey && ev.xy && this.markers) {

			if (this.currentPopup) {
				this.destroyPopup();
			} else if (this.popupOnClick && (this.map.getZoom() >= this.minZoom || !this.hideMarkerBelowMinZoom)) {
				var marker = this.findNearestMarker (ev.xy, this.clickDistance);
				if (marker) this.markerClick.apply (marker, [ev]);
			}
		}

		if (ev.ctrlKey && this.enableCreate && this.lastZoom >= this.minZoom) {

			if (this.currentPopup) {
				this.destroyPopup();
				return false;
			}

			var lonlat = this.map.getLonLatFromViewPortPx(ev.xy).
				transform(this.map.getProjectionObject(), this.map.displayProjection);

			var data = { id: -++this.nextId, lat: lonlat.lat, lon: lonlat.lon};
			var marker = this.createMarker (data);

			marker.temporary = true;

			this.createEditPopup (marker, true);
		}
	},

	findNearestMarker: function (center, maxDistance) {

		if (!center || !this.markers) return null;

		if (!maxDistance) maxDistance = 1e10;

		var result = null
		var dist   = maxDistance * maxDistance + 1;

		for (var i in this.markers) {
			var marker = this.markers[i];
			var icon   = marker.icon;
			if (!icon) continue;
			var px	= icon.px;
			if (!px) continue;
			var dx	= px.x - center.x;
			var dy	= px.y - center.y;
			var d2	= dx*dx + dy*dy;
			if (d2 >= dist) continue;
			result	= marker;
			dist	= d2;
		}
		return result;
	},

	//---------------------------------------------------------
	//	Reload Marker on move or zoom
	//---------------------------------------------------------

	moveTo: function (bounds, zoomChanged, dragging) {

		OpenLayers.Layer.Markers.prototype.moveTo.apply(this,arguments);

		//---------------------------------------------------------
		//	but not while dragging or invisible
		//---------------------------------------------------------

		if (dragging || !this.visibility) return;

		//---------------------------------------------------------
		//	XXX QUICKFIX WILL BE REMOVED XXX
		//---------------------------------------------------------

		if (this.zindex && this.div.style.zIndex!=this.zindex)
			this.div.style.zIndex=this.zindex

		//---------------------------------------------------------
		//	Change visibility of marker
		//---------------------------------------------------------

		if ((this.lastZoom>=this.minZoom) != (this.map.zoom>=this.minZoom)) {
			this.lastZoom = this.map.zoom;
			if (!this.blockSize && this.lastZoom < this.minZoom && this.hideMarkerBelowMinZoom)
				this.erase();
			if (this.location && this.createUrlForBounds) {
				if (this.map.zoom >= this.minZoom) {
					for (var i=0; i<this.markers.length; i++) {
						this.markers[i].display(this.markers[i].data._csize<=0);
					}
				} else {
					for (var i=0; i<this.markers.length; i++) {
						this.markers[i].display(this.markers[i].data._csize>0);
					}
				}
			}
			if (!this.location && this.createUrlForBounds && this.hideMarkerBelowMinZoom) {
				for (var i=0; i<this.markers.length; i++) {
					this.markers[i].display(this.map.zoom >= this.minZoom);
				}
			}
		}

		//---------------------------------------------------------
		//	Transform center and border to geogr. Coordinates
		//---------------------------------------------------------

		if (this.map.zoom >= this.minZoom && this.createUrlForBounds) {

			this.loadBounds = bounds.clone().
				transform(this.map.getProjectionObject(), this.map.displayProjection);

			this.loadNext();
		}

		//---------------------------------------------------------
		//	delayed Popup
		//---------------------------------------------------------

		var marker = this.delayedPopupMarker;
		if (marker) {
			this.delayedPopupMarker=null;
			this.createPopup(marker);
			this.currentMarker=marker;
		}
	},

	//---------------------------------------------------------
	//	Load next
	//---------------------------------------------------------

	getUnknownArea: function (bounds) {

		if (!this.blockSize) return bounds;

		var l0 = Math.floor (bounds.left  / this.blockSize);
		var r0 = Math.ceil  (bounds.right / this.blockSize);
		var b0 = Math.floor (bounds.bottom/ this.blockSize);
		var t0 = Math.ceil  (bounds.top   / this.blockSize);
		var l=r0;
		var r=l0;
		var t=b0;
		var b=t0;
		for (var y=b0; y<t0; y++) {
			for (var x=l0; x<r0; x++) {
				var id = y+":"+x;
				if (this.loadedAreas[id]) continue;
				this.loadedAreas[id]=true;
				if (x< l) l=x;
				if (x>=r) r=x+1;
				if (y< b) b=y;
				if (y>=t) t=y+1;
			}
		}

		if (l>=r || b>=t) return null;
		return new OpenLayers.Bounds (l*this.blockSize,b*this.blockSize,r*this.blockSize,t*this.blockSize);
	},

	loadNext: function () {

		if (this.loadBounds==this.loadedBounds) return;
		if (this.loadingUrl) return;
		this.loadedBounds = this.loadBounds;
		var area = this.getUnknownArea (this.loadedBounds);
		if (area) this.request (this.createUrlForBounds(area));
	},

	//---------------------------------------------------------
	//	Download CSV
	//---------------------------------------------------------

	request: function (url) {

		if(this.loadingUrl) return false;
		this.loadingUrl=url;

		OpenLayers.Request.GET({
			url:this.loadingUrl,
			success:this.requestSuccess,
			failure:this.requestFailure,
			scope:this
		});
		this.events.triggerEvent("loadstart");
	},

	//---------------------------------------------------------
	//	Success downloading CSV
	//---------------------------------------------------------

	requestSuccess: function(request) {

		if (request.responseText==null || request.responseText=="")
			alert ('"' + this.loadingUrl + '" returns' +
				(request.getResponseHeader ?
				' content type "'+request.getResponseHeader('Content-Type')+'" with' : '') +
				' no content.');
		var objects = this.parseCSV (request.responseText);
		if (!this.blockSize) this.erase (true);
		for (var i=0; objects.length>i; i++) {
			this.createMarker (objects[i]);
		}
		if (this.loadingUrl==this.location && !map.getCenter()) {
			var extent = this.getBounds();
			if (extent) {
				this.map.zoomToExtent(extent);
				if (this.restrictMapExtent) {
					extent.extend(this.map.restrictedExtent);
					this.map.restrictedExtent=extent;
				}
			}
		}
		if (!map.getCenter()) this.map.zoomToMaxExtent();
		this.events.triggerEvent("loadend");
		this.loadingUrl = null;
		if (this.visibility) this.loadNext();
	},

	//---------------------------------------------------------
	//	Error downloading of CSV
	//---------------------------------------------------------

	requestFailure: function(request) {

		OpenLayers.Console.userError(OpenLayers.i18n("errorLoadingCSV",{
			'url':    this.loadingUrl,
			'phase': 'request failed'
		}));
		if (!map.getCenter()) this.map.zoomToMaxExtent();
		this.events.triggerEvent("loadend");
		this.loadingUrl = null;
		this.loadNext();
	},

	//---------------------------------------------------------
	//	createObject
	//---------------------------------------------------------

	getMarkerByDataId: function (id) {

		for (var i=0; i<this.markers.length; i++) {
			if (this.markers[i].data.id==id) return this.markers[i];
		}
		return null;
	},

	createMarker: function (data, isnew) {

		if (!data) return;
		if (this.filter && !this.filter(data)) return;
		if (!data.id) data.id = ++this.nextId + "";
		if (this.getMarkerByDataId(data.id)) return null;

		if (!data.lat && data.point) data.lat=data.point.split(',')[0];
		if (!data.lon && data.point) data.lon=data.point.split(',')[1];
		var lon = parseFloat (data.lon);
		var lat = parseFloat (data.lat);

		if (isNaN(lon) || isNaN(lat)) {
			if (data.location) {
				if (!this.locations[data.location]) this.locations[data.location] = [];
				this.locations[data.location].push(data);
			}
			return null;
		}

		var lonLat=new OpenLayers.LonLat(lon, lat).
			transform(this.map.displayProjection, this.map.getProjectionObject());

		var icon = this.createIconFromData ? this.createIconFromData(data) : this.icon?this.icon.clone():null;

		var marker = new OpenLayers.Marker (lonLat, icon);

		marker.icon.imageDiv.firstChild.className='olPopupMarker';
		marker.icon.imageDiv.className='olPopupMarker';
		marker.layer=this;
		marker.data =data;

		//---------------------------------------------------------
		//	tooltip
		//---------------------------------------------------------

		if (this.createTooltipFromData) {

			this.setTooltip (marker);

		} else if (this.popupOnHover) {

			marker.events.register('mouseover', marker, this.markerMouseOver);
			marker.events.register('mouseout', marker, this.markerMouseOut);
		}

		if (this.popupOnClick) {
			marker.events.register('click', marker, this.markerClick);
		}

		this.addMarker (marker);
		return marker;
	},

	updateMarker: function (marker, busy) {

		this.setIcon (marker, this.createIconFromData (marker.data, busy));
		this.setTooltip (marker);
	},

	setIcon: function (marker, icon) {

		marker.icon.url   = icon.url;
		marker.icon.size  = icon.size;
		marker.icon.offset= icon.offset;
		marker.icon.draw();
	},

	setTooltip: function (marker) {

		var html = this.createTooltipFromData (marker.data);
		if (!html) return;

		if (this.maxTooltipWidth != null)
			html = this.wrap (html, this.maxTooltipWidth,
				{displayClass: 'olPopupMarkerTooltip'});

		var size = OpenLayers.Util.getRenderedDimensions (
			html, null,
			{displayClass: 'olPopupMarkerTooltip'});

		var tooltipDiv = marker.tooltipDiv;
		if (!tooltipDiv) {

			tooltipDiv=document.createElement("div");
			tooltipDiv.style.position = "absolute";
			tooltipDiv.className	 = 'olPopupMarkerTooltip tooltip';

			marker.tooltipDiv = tooltipDiv;
			marker.icon.imageDiv.appendChild (tooltipDiv);
		}

		tooltipDiv.style.width   = size.w + 'px';
		tooltipDiv.style.height  = size.h + 'px';
		tooltipDiv.innerHTML = html;
	},

	wrap: function (html, width, options) {

		var result = [];

		var blocks = OpenLayers.String.trim (html.replace (/<br\/?>/,'\n')).split ('\n');
		while (blocks.length >= 1) {

			var words = OpenLayers.String.trim (blocks.shift()).split(' ');
			while (words.length >= 1) {

				var line = words.shift();
				while (words.length >= 1) {

					var word = OpenLayers.String.trim (words[0]);
					if (word=='') continue;
					var probe = line + '&nbsp;' + word;
					var size = OpenLayers.Util.getRenderedDimensions (
	                                        probe, null, options);
					if (size.w > width) break;
					line = probe;
					words.shift();
				}

				result.push (line);
			}
		}

		return result.join ('<br/>');
	},

	//---------------------------------------------------------
	//	destroyMarker
	//---------------------------------------------------------

	destroyMarker: function (marker) {

		if (this.currentMarker==marker)
			this.destroyPopup();

		if(this.markers && this.markers.length) {
			OpenLayers.Util.removeItem (this.markers, marker);
			marker.destroy();
		}
	},

	erase: function (keepCurrent) {

		if (!keepCurrent) this.destroyPopup();

		if (this.markers!=null) {
			for (var index in this.markers) {
				var marker = this.markers[index];
				if (marker != this.currentMarker)
					marker.destroy();
			}
		}
		this.markers = [];
		this.loadedAreas= {};
		this.locations	= [];

		if (this.currentMarker) this.markers.push (this.currentMarker);
	},

	//---------------------------------------------------------
	//	markerClick
	//---------------------------------------------------------

	markerClick: function (ev) {

		if (ev.shiftKey && !ev.ctrlKey) return false;

		var layer = this.layer;

		if (layer.clickDistance>0 && layer.currentPopup) {
			layer.destroyPopup();
			layer.currentMarker=null;
		} else if (layer.currentMarker==this) {
			layer.destroyPopup();
			layer.currentMarker=null;
		} else if (!ev.shiftKey) {
			layer.createPopup(this);
			layer.currentMarker=this;
		} else if (layer.enableUpdate) {
			layer.createEditPopup (this, false);
		}
	},

	markerMouseOver: function (ev) {

		if (ev.shiftKey) return false;
		if (!this.layer.currentMarker)
			this.layer.createPopup(this, true);
	},

	markerMouseOut: function (ev) {

		if (!this.layer.currentMarker)
			this.layer.destroyPopup();
	},

	//---------------------------------------------------------
	//	selectMarker
	//---------------------------------------------------------

	selectMarker: function (marker, options) {

		if (typeof (marker) != 'object') marker=this.getMarkerByDataId(marker);

		if (!marker) return null;

		if (this.currentMarker==marker) {
			this.destroyPopup();
			this.currentMarker=null;
			return false;
		} else {
			if (options && options.pan) {
				this.destroyPopup ();
				this.delayedPopupMarker = marker;
				this.map.panTo (marker.lonlat);
				if (this.map.panTween && this.map.panTween.playing) return true;
			}
			this.delayedPopupMarker = null;
			this.createPopup(marker);
			this.currentMarker=marker;
			return true;
		}
	},

	//---------------------------------------------------------
	//	Popup - r/o
	//---------------------------------------------------------

	createPopup: function (marker, nopan) {

		this.destroyPopup ();

		//---------------------------------------------------------
		//	check for overlapping icons
		//---------------------------------------------------------

		var cluster = [];
		if (this.clusterSize>0) {
			var limit = this.clusterSize/Math.pow(2,this.map.zoom)*156543;
			for (var i=0; i<this.markers.length; i++) {
				var member=this.markers[i];
				if (Math.abs(marker.lonlat.lat-member.lonlat.lat)>limit) continue;
				if (Math.abs(marker.lonlat.lon-member.lonlat.lon)>limit) continue;
				cluster.push (member.data);
				if (member.data.location && this.locations[member.data.location]) {
					for (var j=0; j<this.locations[member.data.location].length; j++) {
						cluster.push (this.locations[member.data.location][j]);
					}
				}
			}
			if (this.clusterSort) cluster.sort(this.clusterSort);
		}
		//---------------------------------------------------------
		//	create popup
		//---------------------------------------------------------

		this.currentPopup = new OpenLayers.Popup.FramedCloud (null,
			marker.lonlat,
			null, //size
			(cluster.length>=2 ? this.createHtmlFromList(cluster) : this.createHtmlFromData(marker.data)),
			marker.icon,
			true,
			function (e) {this.layer.destroyPopup();}
		);

		this.currentPopup.layer = this;
		if (this.cloudImage) this.currentPopup.imageSrc = this.cloudImage;

		if (nopan)
			this.currentPopup.panMapIfOutOfView=false;
		this.map.addPopup(this.currentPopup);
		this.currentPopup.div.control = this.currentPopup;

		if (this.closeOnClick) this.currentPopup.div.onclick = function () {
			this.control.layer.destroyPopup();
			return false;
		};

		//---------------------------------------------------------
		//	editbutton
		//---------------------------------------------------------

		if (this.enableUpdate || this.enableDelete || this.enableLocate) {

			var div = this.currentPopup.div.firstChild.firstChild;
			var buttons = div.getElementsByTagName('button');

			if (!buttons.length) {

				if (this.enableUpdate) {
					var button = document.createElement ('button');
					button.innerHTML = this.labelEdit;
					button.className = 'edit';
					div.appendChild (button);
				}

				if (this.enableDelete) {
					var button = document.createElement ('button');
					button.innerHTML = this.labelDelete;
					button.className = 'delete';
					div.appendChild (button);
				}

				if (this.enableLocate) {
					var button = document.createElement ('button');
					button.innerHTML = this.labelLocate;
					button.className = 'locate';
					div.appendChild (button);
				}

				this.currentPopup.updateSize();
				buttons = div.getElementsByTagName('button');
			}

			for (var i=0; i<buttons.length; i++) {

				var button = buttons[i];
				button.marker = marker;

				switch (button.className) {

				case 'edit':
					button.onclick = function () {
						this.marker.layer.createEditPopup (this.marker);
					};
					break;

				case 'delete':
					button.onclick = this.deleteButtonOnClick;
					break;

				case 'locate':
					button.onclick = this.locateButtonOnClick;
					break;
				}
			}
		}
	},

	//---------------------------------------------------------
	//	Popup - edit
	//---------------------------------------------------------

	createEditPopup: function (marker, isnew) {

		this.destroyPopup ();

		this.currentMarker = marker;

		//---------------------------------------------------------
		//	create popup
		//---------------------------------------------------------

		this.currentPopup = new OpenLayers.Popup.FramedCloud (null,
			marker.lonlat,
			null, //size
			this.createForm (marker.data),
			marker.icon,
			true,
			function (e) {this.layer.destroyPopup();}
		);

		this.currentPopup.layer = this;
		if (this.cloudImage) this.currentPopup.imageSrc = this.cloudImage;

		this.map.addPopup(this.currentPopup);
		this.currentPopup.div.control = this.currentPopup;

		//---------------------------------------------------------
		//	onsubmit + focus
		//---------------------------------------------------------

		var div = this.currentPopup.div.firstChild.firstChild;
		var form = div.getElementsByTagName('form')[0];
		if (!form) alert ('No <form> found.');

		this.fillForm (form, marker.data);

		form.marker = marker;
		form.onsubmit= this.formOnSubmit;
		form.onreset = this.formOnReset;
		form.elements[0].focus();
	},

	//---------------------------------------------------------
	//	form.submit
	//---------------------------------------------------------

	formOnSubmit: function () {

		var layer = this.marker.layer;

		//-------------------------------------------------
		//	Extrakt values
		//-------------------------------------------------

		var newData = {
			id:	this.marker.data.id,
			lat:	this.marker.data.lat,
			lon:	this.marker.data.lon
		};

		var inputs = this.getElementsByTagName('input');
		for (var i=0; i<inputs.length; i++) {

			var input = inputs[i];
			var value = input.value;

			switch (input.type) {
			case 'checkbox':
				if (!input.checked) value = '';
				break;
			case 'radio':
				if (!input.checked) continue;
				break;
			default:
				value = OpenLayers.String.trim(value);
			}
			newData[input.name]=value;
		}

		var selects = this.getElementsByTagName('select');
		for (var i=0; i<selects.length; i++) {

			var select = selects[i];
			var value = select.selectedIndex>=0 ? select.options[select.selectedIndex].value : '';
			newData[select.name]=value;
		}

		var textareas = this.getElementsByTagName('textarea');
		for (var i=0; i<textareas.length; i++) {

			var textarea = textareas[i];
			var value    = OpenLayers.String.trim(textarea.value);
			newData[textarea.name]=value;
		}

		//-------------------------------------------------
		//	Check data
		//-------------------------------------------------

		var result = layer.checkData (newData);
		if (result) {
			alert (result);
			return false;
		}

		delete this.marker.temporary;
		layer.destroyPopup();
		layer.setTooltip (this.marker);
		layer.updateMarker(this.marker, true);

		//-------------------------------------------------
		//	Update on server
		//-------------------------------------------------

		var postData = OpenLayers.Util.getParameterString (newData);
		layer.updateMarkerOnServer (this.marker, postData);
	},

	formOnReset: function () {
		this.marker.layer.destroyPopup();
	},

	//---------------------------------------------------------
	//	deleteButtonOnClick
	//---------------------------------------------------------

	deleteButtonOnClick: function () {

		var marker = this.marker;
		var layer  = marker.layer;

		if (!confirm (layer.labelConfirmDelete))
			return false;

		layer.destroyPopup();

		//-------------------------------------------------
		//	Update on server
		//-------------------------------------------------

		var postData = OpenLayers.Util.getParameterString ({COMMAND: 'DELETE', id: marker.data.id});
		layer.updateMarkerOnServer (marker, postData);
	},

	//---------------------------------------------------------
	//	locateButtonOnClick
	//---------------------------------------------------------

	locateButtonOnClick: function () {

		var marker = this.marker;
		var layer  = marker.layer;

		layer.locateMarker = marker;
		layer.map.div.style.cursor = 'crosshair';
		layer.destroyPopup();
		layer.setVisibility(false);
	},

	//---------------------------------------------------------
	//	callback to Server to create, modify or delete
	//---------------------------------------------------------

	updateMarkerOnServer: function (marker, postData) {

		OpenLayers.Request.POST({

			url: this.editUrl || this.createUrlForBounds({left:'',right:'',top:'',bottom:''}),

			data: postData,

			user: this.requestUser,
			password: this.requestPassword,
			async: this.requestAsync,

			headers: {'Content-Type': 'application/x-www-form-urlencoded'},

			success: function (request) {

				var lines = request.responseText.split ('\n');
				lines.pop();

				if (lines.length<2) {
					this.layer.destroyMarker (this);
					return;
				}

				var names = OpenLayers.String.trim(lines.shift()).split(this.layer.fieldSeparator);
				var values= OpenLayers.String.trim(lines.shift()).split(this.layer.fieldSeparator);
				this.data = {};
				for (var i in names) {
					this.data[names[i]] = values[i];
				}
				this.layer.updateMarker (this);
			},

			failure: function (request) {

				alert ('failure:\n' + request.responseText);

				if (this.data && this.data.id>0) {
					this.layer.updateMarker (this);
				} else {
					this.layer.destroyMarker (this);
				}
			},

			scope: marker
		});
	},

	//---------------------------------------------------------
	//	Popups
	//---------------------------------------------------------

	destroyPopup: function () {

		if (!this.currentPopup) return false;
		if (this.currentPopup.div)
			this.currentPopup.div.control=null;
		this.currentPopup.destroy();
		this.currentPopup=null;

		if (this.currentMarker && this.currentMarker.temporary) {
			this.destroyMarker (this.currentMarker);
		}
		this.currentMarker=null;
		return true;
	},

	//---------------------------------------------------------
	//	Parse CSV, get fieldnames from first line
	//---------------------------------------------------------

	parseCSV: function (text) {

		var lines=text.split('\n');
		var names = OpenLayers.String.trim(lines.shift()).split(this.fieldSeparator);
		if (names.length<2) {
			OpenLayers.Console.userError (OpenLayers.i18n ("errorLoadingCSV", {
				'url':   this.loadingUrl,
				'phase': 'not a CSV file'
			}));
		}

		if (!this.fieldTitles) {
			this.fieldTitles = {};
			for (var i in names) {
				var name = names[i];
				this.fieldTitles[name]=name;
			}
		}

		var result=[];
		for (var lineno=0;lines.length>lineno;lineno++) {
			var object = new Object();
			var values = OpenLayers.String.trim(lines[lineno]).split(this.fieldSeparator);
			if (values.length<=1) continue;
			for (var col=0; values.length>col && names.length>col; col++) {
				object[names[col]] = values[col];
			}
			result.push(object);
		}
		return result;
	},

	//---------------------------------------------------------
	//	Gen HTML code for Popup
	//---------------------------------------------------------

	createHtmlFromData: function (data) {

		if (data._csize) {
			var icon = '<img src="'+this.getIconUrl(data)+'" alt=""/>';
			return '<div>'+icon+'&nbsp;Dieses Icon ist in der Übersichtsdarstellung Platzhalter für '+data._csize+' Knoten in der nahen Umgebung. Diese werden ab Zoomstufe '+this.minZoom+' nachgeladen und angezeigt.</div>\n';
		}

		var result = [];

		var rows = [];
		for (var tag in data) {
			if (data[tag] == '') continue;
			var title = this.fieldTitles[tag] || tag;
			var value = data[tag] || '';
			if (this.fieldValues[tag] && this.fieldValues[tag][value])
				value = this.fieldValues[tag][value];
			rows.push ('<tr><th scope="row">' + this.html(title) + ':</th><td>'
				+ this.formatValue(value).replace(/\034/g,'<br/>') + '</td></tr>')
		}

		if (rows.length>=1)
		result.push ('<table>\n' + rows.join('\n') + '\n</table>');

		if (this.osmlinks) {
			osmlinks = this.createOsmLinks(data);
			if (osmlinks) result.push ('<p>' + osmlinks + '</p>');
		}

		return result.join('\n');
	},

	//---------------------------------------------------------
	//	Editform
	//---------------------------------------------------------

	createForm: function (data) {

		var result = [];
		var hidden = [];
		result.push ('<form>');
		result.push ('<table>');

		for (name in this.fieldTitles) {

			if (name=='id' || name=='lat' || name=='lon')
				continue;

			var hName = this.html (name);
			var title = this.fieldTitles[name] || name;
			var valueTitles = this.fieldValues[name];
			var field;

			switch (this.fieldTypes[name]) {

			case 'hidden':
				hidden.push ('<input type="hidden" name="'+this.html(name)+'"/>');
				continue;

			case 'select':
				var options = [];
				for (var value in valueTitles) {
					var hTitle = this.html (valueTitles[value] || value);
					options.push ('<option value="' + this.html(value) + '">' + hTitle + '</option>');
				}
				field = '<select name="' + hName + '">\n' + options.join('\n') + '</select>';
				break;

			case 'radios':
				var choices = [];
				for (var value in valueTitles) {
					var hTitle = this.html (valueTitles[value] || value);
					choices.push ('<label><input type="radio" name="' + hName + '" value="' + this.html(value) + '"/>' + hTitle + '</label> ');
				}
				field = choices.join('\n');
				break;

			case 'textarea':
				field = '<textarea name="'+this.html(name)+'"/></textarea>';
				break;

			case 'checkbox':
				var hTitle = this.html (valueTitles && valueTitles['t'] || '');
				field = '<input type="checkbox" name="'+this.html(name)+'" value="t"/>' + hTitle;
				break;

			case 'password':
				field = '<input type="password" name="'+this.html(name)+'"/>';
				break;

			default:
				field = '<input name="'+this.html(name)+'"/>';
				break;
			}

			result.push ('<tr><th scope="row">'+this.html(title) +':</th><td>'+field+'</td></tr>');
		}

		result.push ('</table>');
		result.push ('<button type="submit">Speichern</button>');
		result.push ('<button type="reset">Verwerfen</button>');
		result.push (hidden.join('')+'</form>');
		return result.join ('\n');
	},

	fillForm: function (form, data) {

		var inputs = form.getElementsByTagName ('input');
		for (var i=0; i<inputs.length; i++) {

			var input = inputs[i];
			var value = data[input.name] || '';
			switch (input.type) {
			case 'radio':
			case 'checkbox':
				if (input.value==value) input.checked=true;
				break;
			default:
				input.value = value;
			}
		}

		var selects = form.getElementsByTagName ('select');
		for (var i=0; i<selects.length; i++) {

			var select = selects[i];
			var value = data[select.name] || '';
			var missing = value != '';
			for (var o in select.options) {
				var option = select.options[o];
				if (option.value == value) {
					option.selected = true;
					missing = false;
				}
			}
			if (missing) {
				var option = document.createElement('option');
				option.value=value;
				option.innerHTML = value;
				select.appendChild (option);
				option.selected=true;
			}
		}

		var textareas = form.getElementsByTagName ('textarea');
		for (var i=0; i<textareas.length; i++) {

			var textarea = textareas[i];
			var value = data[textarea.name] || '';
			textarea.value = value.replace (/\034/g, '\n');
		}
	},

	checkData: function (data) {
		return "checkData() missing.";
	},

	//---------------------------------------------------------
	//	formatting
	//---------------------------------------------------------

	formatValue: function (text) {

		var list=text.split (';');
		var result=[];
		for (var i=0; i<list.length;i++) {
			var value = this.html (OpenLayers.String.trim (list[i]));
			if (value.substr (0,7)=='http://') {
				result.push ('<a target="_blank" href="'+value+'">'+value+'</a>');
				continue;
			}
			result.push (value);
		}
		return result.join ("; ");
	},

	html: function (text) {

		if (text==null) return '';
		return String(text).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
	},

	//---------------------------------------------------------
	//	OSM specific links
	//---------------------------------------------------------

	createOsmLinks: function (data, id) {

		if (!id) id=data.id;
		if (!id) return '';

		var tid = id.match (/^([nwr]?)([1-9][0-9]*)$/);

		if (!tid) return;

		var type;
		switch (tid[1]) {
		case '':
		case 'n':
			type = 'node'; break;
		case 'w':
			type = 'way'; break;
		case 'r':
			type = 'relation'; break;
		default:
			return '';
		}

		var id=tid[2];

		var l=parseFloat(data.lon)-0.0003;
		var b=parseFloat(data.lat)-0.0005;
		var r=parseFloat(data.lon)+0.0003;
		var t=parseFloat(data.lat)+0.0005;

		if (data.bbox) {
			var lbrt = data.bbox.split(',');
			l = parseFloat(lbrt[0])-0.0001;
			b = parseFloat(lbrt[1])-0.0001;
			r = parseFloat(lbrt[2])+0.0001;
			t = parseFloat(lbrt[3])+0.0001;
		}

		return '<a target="_blank" href="http://www.openstreetmap.org/browse/'+type+'/'+id+'">'+type+' '+id+'</a>'+
		' - edit with '+
	'<a target="_blank" href="http://www.openstreetmap.org/edit?'+
		'lat='+data.lat+'&lon='+data.lon+'&zoom=17">potlatch</a>, '+
	'<a target="_blank" href="http://www.openstreetmap.org/edit?editor=potlatch2&'+
		'lat='+data.lat+'&lon='+data.lon+'&zoom=17">potlatch2</a> or '+
	'<a target="josmremote" href="http://127.0.0.1:8111/load_and_zoom'+
		'?left='+l+'&bottom='+b+'&right='+r+'&top='+t+
		'&select='+type+''+id+'">josm</a>';
	},

	//---------------------------------------------------------
	//	Combine entries to list
	//---------------------------------------------------------

	createHtmlFromList: function (list) {

		var items = [];
		var clusters = [];
		var nItems=0;
		var limit = this.clusterLimit && this.clusterLimit<list.length ? this.clusterLimit : list.length;
		for (var i=0; i<list.length; i++) {
			if (list[i]._csize || list[i].cluster) {
				clusters.push (this.createHtmlFromData(list[i]));
			} else {
				nItems++;
				if (items.length<limit) items.push (this.createHtmlFromData(list[i]));
			}
		}
		if (nItems>limit) {
			if (limit!=1) items.unshift('Die ersten '+items.length+' von '+nItems+ ' Einträgen:');
		} else if (items.length) {
			if (limit!=1) items.unshift('Alle '+items.length+ ' Einträge:');
		} else {
			items=clusters;
		}
		return items.join('<hr/>\n');
	},

	//---------------------------------------------------------
	//	Bounding box for markers
	//---------------------------------------------------------

	getBounds: function () {

		if (!this.markers || !this.markers.length)
			return null;

		var bounds = new OpenLayers.Bounds ();

		if (this.region) {
			var count=0;
			for (var i in this.markers) {
				if (!this.markers[i].data.region)
					continue;
				if (this.markers[i].data.region.substr(0,length)!=this.region)
					continue;
				bounds.extend (this.markers[i].lonlat);
				count++;
			}
			if (count) return bounds;
		}

		for (var i in this.markers) {
			bounds.extend (this.markers[i].lonlat);
		}
		return bounds;
	},

	CLASS_NAME:"OpenLayers.Layer.PopupMarker"
});

//--------------------------------------------------------------------------------
//	$Id: popupmarker.js,v 1.84 2012/03/21 12:49:43 wolf Exp wolf $
//--------------------------------------------------------------------------------

Netzwolf ist doch hier im deutschsprachigen Unterforum sehr aktiv und gut erreichbar …

Danke, in der UserList gefunden.

Bei mir lag diese Fehlermeldung übrigens an der Verwendung von Google Chrome. Mit Firefox und IE gings sofort.
Aktuell (nach einigen Änderungen [die nicht auf kompatibilität mit Chrome abzielten]) läuft es auch unter Chrome. K.A. Warum
Einzig gespeichert wird unter Chrome noch nicht.
Wichtig war den Dateien auf dem Server auch die nötigen Rechte zu geben.

Bei mir will nur die AutoZoom Funktion nicht:

		createUrlForBounds: function (bounds) {
			return 'poiserver.phtml?db=demo&limit=25'+
				'&lon.ge='+bounds.left+
				'&lon.lt='+bounds.right+
				'&lat.ge='+bounds.bottom+
				'&lat.lt='+bounds.top;
		},

Auch die feste Justierung auf Deutschland stengelt sich. Läuft das bei Dir?
Habe auch keinen Weg gefunden zu schauen, was er bei mir für eine URL aus dem Aufruf erzeugt…

Hallo Netzwolf,
ich geh mal davon aus, dass Du immer noch keine Zeit hast dich gewerblich für ein paar Stunden meinem angepassten POI_EDITOR zu widmen?
Vielleicht kannst Du mir aber schon mal in einer Kleinigkeit helfen?
Innerhalb des Codes wird ja die poiserver.phtml aufgerufen. Leider zu spät um einen darin eingefügten “mysql_num_rows” in den Header des Layers zu übernehmen.
Da ich aber gern in dem LayerSwitcher die Anzahl Datensätze sehen würde, wüsste ich gern ob ich die ‘irgendwie’ vor die header Definition bekomme?
Und das Zweite:
Kann man es so einrichten, dass bei Klick auf den header nicht nur der gewählte Layer ein/ausgeblendet wird, sondern auch der Zoombereich angepasst wird? Ggf auch gern mit einem Extra Text dahinter.

Hallo,

vor 2 Jahren habe ich OSM in meine Homepage nach der Anleitung in OSM-Wiki eingebunden. http://wiki.openstreetmap.org/wiki/DE:Karte_in_Webseite_einbinden Mit Hilfe von Netzwolf konnte ich auch meine Marker setzen und verwenden.
Jetzt möchte ich gerne die Map in meiner Hompage erweitern aber leider reichen dafür meine Programmierkentnisse nicht ganz.
Meine Frage:
In der Suchfunktion der OSM kann ich z.B. ein Stadteil einer Stadt eingeben und erhalte eine Ansicht mit den Stadtteil-Grenzen. In der Kopfzeile steht dann z.B. http://www.openstreetmap.org/relation/56388.
Ich würde gerne die Relationsnummern in Mysql abspeichern un dann gezielt die Map mit dieser Relationsnummer aufrufen. Weder in der HTML-Datei noch in der tom.js habe ich abe eine Möglichkeit gefunden, die Relationsnummern für die Map-Aufrufe einzubinden.

Kann mir bitte jemand helfen?