Drawing polygons with WKT - XML file using OpenLayers - mysql

I have this XML file created with PHP and Mysql:
How can I use this to draw all the polygons using OpenLayers? I did some research and found examples with WKT, but in those examples they used just one polygon:
var feature = format.readFeature(
'POLYGON((10.689697265625 -25.0927734375, 34.595947265625 ' +
'-20.1708984375, 38.814697265625 -35.6396484375, 13.502197265625 ' +
'-39.1552734375, 10.689697265625 -25.0927734375))');
I want to draw all the polygons to create a thematic map based on the "Area" data.

Just parse your XML and iterate over the marker tags. Something like this:
var xml = new OpenLayers.Format.XML(),
wkt = new OpenLayers.Format.WKT(),
vectorLayer = new OpenLayers.Layer.Vector('features'),
doc, markers, i, feature;
OpenLayers.Request.GET({
url: "features.xml",
success: function(request) {
doc = xml.read(request.responseText);
markers = doc.documentElement.getElementsByTagName('marker');
for (i = 0; i < markers.length; i++) {
feature = wkt.read(markers[i].attributes.geometry.nodeValue);
vectorLayer.addFeatures([feature]);
}
}
});
Edit: If you are using OpenLayers 3, try the following:
var wkt = new ol.format.WKT(),
vectorLayer,
source,
features = [],
feature,
markers;
//make sure that jQuery is included
$.ajax('features.xml').then(function(response) {
var markers = response.getElementsByTagName('marker');
for (var i = 0; i < markers.length; i++) {
feature = wkt.readFeature(markers[i].attributes.geometry.nodeValue);
features.push(feature);
}
source = new ol.source.Vector({
features: features
});
vectorLayer = new ol.layer.Vector({
source: source
});
});

Related

marker.setposition with label

I have the program below that reads aircraft coordinates from a txt file and places a number of markers on Google Maps. Every 2 sec it reads the txt file again and pushes the markers to the new aircraft locations. This works fine with the original markers "moving" to the new positions. What I would like to do is add a label to the marker to show the height of each aircraft. To do this I need to generate the label after the txt file has been read but when I do it doesn't delete the old markers but adds new markers.
The portion of code below is working fine but without a variable labels. The relevant code is where var eplanezero is created. If I move this line of code anywhere within the setInterval(function (){ the eplanezero.setPosition will not function properly. I have tried dozens of various but nothing seems to work. Any thoughts appreciated. Note that this is only a portion of the code.
moveMarker(map, playerIcon, enemyIcon);
}
function moveMarker(map, playerIcon, enemyIcon)
{
var eplanezero = new google.maps.Marker({map: map, icon: enemyIcon, label: "1"});
setInterval(function ()
{
$.post("MISSION_ADMIN_radar.txt", function(dataenemy, status)
{
var latlnge = JSON.stringify(dataenemy);
latlnge = latlnge.replace(/"/g,"");
latlnge = latlnge.replace(/[\\r\\n]/g,"");
CoordsEnemy = latlnge.split(";");
var army = parseFloat(CoordsEnemy[0].substring(0));
if (army == 2)//Own army = 1, Enemy = 2
{
var commaPos = CoordsEnemy[0].indexOf(',');
var hyphenPos = CoordsEnemy[0].indexOf('+');
var lat0 = parseFloat(CoordsEnemy[0].substring(4, commaPos));
var long0 = parseFloat(CoordsEnemy[0].substring(commaPos + 1, CoordsEnemy[0].length));
}
eplanezero.setPosition(new google.maps.LatLng(lat0, long0));
});
}, 2000);
The altitude is obtained from the same array that holds the lat and long. However, to place the variable Alt into the marker, I have to create variable eplanezero in the setInterval function so that it updates it every 2 secs. When I do this, it will not move the marker but adds a new marker, leaving the original marker in the old position.
The revised code is as follows:
function moveMarker(map, playerIcon, enemyIcon)
{
//var eplanezero = new google.maps.Marker({map: map, icon: enemyIcon, label: "1"});
var eplanezero = new google.maps.Marker({map: map, icon: enemyIcon, label: Alt});
setInterval(function ()
{
$.post("MISSION_ADMIN_radar.txt", function(dataenemy, status)
{
var latlnge = JSON.stringify(dataenemy);
latlnge = latlnge.replace(/"/g,"");
latlnge = latlnge.replace(/[\\r\\n]/g,"");
CoordsEnemy = latlnge.split(";");
var army = parseFloat(CoordsEnemy[0].substring(0));
if (army == 2)//Own army = 1, Enemy = 2
{
var commaPos = CoordsEnemy[0].indexOf(',');
var hyphenPos = CoordsEnemy[0].indexOf('+');
var Alt0 = parseFloat(CoordsEnemy[0].substring(hyphenPos + 1 , CoordsEnemy[0].length));
var lat0 = parseFloat(CoordsEnemy[0].substring(4, commaPos));
var long0 = parseFloat(CoordsEnemy[0].substring(commaPos + 1, CoordsEnemy[0].length));
var eplanezero = new google.maps.Marker({map: map, icon: enemyIcon, label: Alt});
}
eplanezero.setPosition(new google.maps.LatLng(lat0, long0));
});
}, 2000);
.setPosition must be a method that looks in the array and checks for previous coordinates. if the array doesn't contain any coordinates it places a new marker at the new coordinates, If the array does contain coordinates it "moves"the marker to the new location. Establishing the array within the loop deletes any previous array and the coordinates and therefore Google Map correctly places a new marker. Only by creating the array outside the loop will the method work correctly. Unfortunately this means that the label or the icon cannot be changed once the array is created.

How to get coordinates from a KML file?

Is there any way to parse a kml file and get the coordinates from it with JavaScript?
I've tried doing it with "getElementsByTagName" (like here) but debugger says it's not a valid function.
Any ideas?
It's not easy but you can import the file xml and the parsing with jquery parseXML
// import the file --- se related function below
var content = getSelectedFileContent(importFilename);
// build an xmlObj for parsing
xmlDocObj = $($.parseXML(content));
function getSelectedFileContent(filename) {
// var importFilename = importAreaBaseURL + filename;
var request = new XMLHttpRequest();
request.open("GET", filename, false);
request.send(null);
return request.responseText;
};
at this point you can easy parse the xml obj for placemark and iterate over them for the tag/value you need via jquery
var placemarks = xmlDocObj.find("Placemark");
placemarks.each(function (index) {
if ($(this).find("Polygon").length > 0) {
tipoGeom = "Polygon";
tmpHtml = $(this).find("Polygon").find("outerBoundaryIs").find("coordinates").html();
gmlll_geom = kmlCoords2gmlll( tmpHtml);
inner = $(this).find("Polygon").find("innerBoundaryIs");
inner.each(function(index,el) {
$(el).find("coordinates").html(); // this are the coordinates for polygion
});
}
});
These are sample parts (an extract of functioning code .... not all you need) this code is just for a suggestion....

How to plot shapefiles on Bing Map

How can I use shapefile(.shp) with bing maps without using any third party reference?
I just want to use bing maps api library to perform this action.
So suggest me how can i achieve this?
I have tried something with bing maps which is described below..
Here is my code :
$.ajax({
type: "POST",
url: "GISFunctions.asmx/GetShapeFileData",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data, textStatus, jqXHR) {
var response = data.d;
for (var i = 0; i < response.length; i++) {
var polygonGeometry = response[i];
var vertices = new Array();
var numCoordinates = polygonGeometry.length;
for (var j = 0; j < numCoordinates; j++) {
var CoOrdinates = polygonGeometry[j];
var x = CoOrdinates[1];
var y = CoOrdinates[0];
vertices[j] = new Microsoft.Maps.Location(x, y);
}
var polygoncolor = new Microsoft.Maps.Color(100, 100, 0, 100);
var polygon = new Microsoft.Maps.Polygon(vertices, { fillColor: polygoncolor, strokeColor: polygoncolor });
// Add the shape to the map
map.entities.push(polygon);
}
},
error: function (xhr, status, error) {
alert(xhr.responseText);
}
});
"GISFunctions.asmx/GetShapeFileData" is my web service method. It fetches data from shapefile. Reads shapefile's records one by one and fetches co-ordinates for each record's polygon.
In above Jquery Ajax function, i have differentiated my data and created array which contains vertices for my polygon and then according to below link, i am trying to map these polygons on Bing Map
http://msdn.microsoft.com/en-us/library/gg427604.aspx
When i go through static data then i can easily plot one polygon on Bing Map.. But when i try to create these polygons dynamically then my above code doesn't work.
It doesn't plot any polygon on map and also don't give my error..
I am new to GIS functions so kindly suggest me right direction..
I wrote a couple blog posts on how to import ShapeFiles into Bing Maps. Try taking a look at these:
http://www.bing.com/blogs/site_blogs/b/maps/archive/2012/09/06/esri-shapefiles-and-bing-maps.aspx
http://www.bing.com/blogs/site_blogs/b/maps/archive/2012/09/12/esri-shapefiles-and-bing-maps-wpf.aspx
http://www.bing.com/blogs/site_blogs/b/maps/archive/2013/06/18/how-to-load-spatial-data-from-sqlite-in-a-windows-store-app.aspx

GeoXml3 parse fusion table layer of kml (points) into Google Maps

I have a kml of points loaded into fusion table layer. I want to parse the data to une map.fitBounds on the layer extent using geoxml3, but thats not functionning. This exactly code below is working with KML polygons but not with KML points layer.
Code:
var queryText = encodeURIComponent("SELECT * FROM 1CNJWjLDYgBkJGZVslJ67Fak4DyqadEFuIabzQ60 ");
var query = new google.visualization.Query('http://www.google.com/fusiontables/gvizdata?tq=' + queryText);
query.send(zoomTo);
}
function zoomTo(response) {
if (!response) {
alert('no response');
return;
}
if (response.isError()) {
alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
FTresponse = response;
//for more information on the response object, see the documentation
//http://code.google.com/apis/visualization/documentation/reference.html#QueryResponse
numRows = response.getDataTable().getNumberOfRows();
numCols = response.getDataTable().getNumberOfColumns();
var geoXml = new geoXML3.parser();
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < numCols; i++){
if (FTresponse.getDataTable().getColumnLabel(i) == 'geometry') {
var ColIndex = i;
}
}
if (!ColIndex){
alert('Geometry column "geometry" not found.')
}
for (var i = 0; i < numRows; i++){
var kml = FTresponse.getDataTable().getValue(i,ColIndex);
geoXml.parseKmlString("<Placemark>"+kml+"</Placemark>");
bounds.union(geoXml.docs[i].bounds);
}
map.fitBounds(bounds);
}
The parse method should not be used for parsing KML strings from FusionTables (the parseKmlString method is for doing that).
var kml = FTresponse.getDataTable().getValue(i,ColIndex);
geoXml.parseKmlString("<Placemark>"+kml+"</Placemark>");
Note: the KML fragments stored in FusionTables do not include the <Placemark> tags which geoxml3 looks for, that is why they are added to the string passed to geoxml3.
The GViz query response has a 500 row limit (that doesn't seem to be documented anywhere I could find, the best I could find was this reference to it, but the documentation has moved since then).
Looks like you are going to run into that limitation with your table, to overcome that use the FusionTables API v1.0, that returns GeoJSON, not KML (so you will no longer need geoxml3).
example that decodes KML "Points" from FusionTables using GViz and geoxml3 (table contains less than 500 points)
example of parsing markers from Fusion Tables using the Fusion Tables API v1.0

How to initialize a google maps on pageinit without repeatingly loading the google map api script

I would like to be able to load the Google.maps API only once for alle my pages.
Then i would like to be able to use geolocation or loading a map into a page anywhere on my web app.
The problem is that I cant figure out to seperate API loading and map initialization.
Which means i need to load the API each time I create a map.
I have referenced most of my code further down in the post but i suppose the following code is the problem.That piece of code takes care of the API Loading but at the same time it takes care of setting the initialize() function as a callback function and calling it.
var script = document.createElement("script");
script.type = "text/javascript";
script.src ="http://maps.googleapis.com/maps/api/js?key=mykey&sensor=false&callback=initialize";
document.body.appendChild(script);
How do i load the api once, lets say in the header, and then create a new map each time I go to specific page. WIthout loading the maps API again. (Note that im using Jquery mobile so my header only gets loaded one time for a session.)
I get this error:
Warning: you have included the Google Maps API multiple times on this page. This may cause unexpected errors.
Ii would like to tell you my setup.
-Im using Google Map APi v3
-I'm loading the API dynamically after the page has loaded.
-I'm using Jquery mobile, which means the page with google maps only gets partially reloaded when you visit it.
-Im using google maps for two things to show the map and for geolocation.
-I'm using the Google map api on several pages.
Im interacting with the map in 3 different places: In a header javascript see code below
A header javascript
A javascript in the body
The DIV in the body that holds the map.
Here is my code for the javascript that handles loading the API, showing the map, markers etc:
<script>
$('.error').hide();
//search criterias
var radius;
var timerange;
var type;
//user position variables
var userposition = false;
var mylatitudedegree = "=55.698";
var mylongitudedegree = "=12.579";
//map variables
var mapready = false;
var map;
var bound;
var markersArray = [];
//array for keeping track of the markers
var markercenter;
//hack
var pageinit = 0;
var initializer = 0;
var triggersearch = 0;
var loadscripts = 0;
var isgooglemapsloaded = false;
$( '#soegsagside' ).live( 'pageinit',function(event)
{
pageinit++;
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(setPosition, function(error) {
alert('Din location er ikke tilgængelig! Error code: ' + error.code);
userposition = false;
}, {
maximumAge : 60000,
timeout : 10000,
enableHighAccuracy : true
});
}
else {
alert("Din browser tillader ikke, at vise din lokation!");
userposition = false;
}
loadScript();
$("#search_filter_button").click(function() {
//hide the "skal udfyldes" labels
$('.error').hide();
// validate and process form here
radius = $("select#choose_radius_select").val();
if (radius == "vælg") {
$("label#radius_error").show();
$("select#choose_radius_select").focus();
return false;
}
timerange = $("select#choose_timerange_select").val();
if (timerange == "vælg") {
$("label#timerange_error").show();
$("select#choose_timerange_select").focus();
return false;
}
type = $("select#vælg_type").val();
if (type == "vælg") {
$("label#select_type_error").show();
$("select#vælg_type").focus();
return false;
}
//------------------post to php script ---------------
var dataString = 'radius=' + radius + '&timerange=' + timerange + '&type=' + type + '&mylatitudedegree=' + mylatitudedegree + '&mylongitudedegree=' + mylongitudedegree;
$.ajax({
type : "POST",
url : "soegsagDB.php",
data : dataString,
success : function(data) {
$('#søgeresultater').html(data);
$('#søgeresultater').trigger('create');
clearOverlays();
createtaskmarkers();
findCenterOfMarkers();
if (userposition) {
usergeoposition = new google.maps.LatLng(mylatitudedegree, mylongitudedegree);
map.setCenter(usergeoposition);
createuserposition(usergeoposition);
} else {
map.setCenter(markercenter);
}
expandMapBoundForMarkers()
}
});
//end of post search query to server
return false;
});
//end of click seach button
});
//end of page ready
function setPosition(position) {
userposition = true;
myposition = position.coords;
mylatitudedegree = position.coords.latitude;
mylongitudedegree = position.coords.longitude;
var milli = new Date();
}
//function for clearing the markerArray
function clearOverlays() {
for (var i = 0; i < markersArray.length; i++) {
markersArray[i].setMap(null);
}
}
//Function for initializing the map, which is called when the map is created
function initialize() {
initializer++;
bound = new google.maps.LatLngBounds();
var mapOptions = {
zoom : 13,
center : new google.maps.LatLng(55, 12),
mapTypeId : google.maps.MapTypeId.ROADMAP
}
//Create a map
map = new google.maps.Map(document.getElementById("map"), mapOptions);
mapready = true;
$("#search_filter_button").trigger('click');//Trigger click on the search button
triggersearch++;
}
//create user positio marker
function createuserposition(usergeoposition) {
var userPositionMarker = new google.maps.Marker({
position : usergeoposition,
map : map,
title : "Din position",
});
markersArray.push(userPositionMarker);
}
function createtaskmarkers() {
//Create the markers of the tasks
//1. find the task <li> that contain the data and loop through each one
//2. for each task collect the dato into variables and create markers and infowindows
//3. calculate center of point
//4. extendt map area to contain all points
var data = $.map($('li'), function(element) {
if (element.hasAttribute("data-latitude")) {
var tempPos = new google.maps.LatLng($(element).attr('data-latitude'), $(element).attr('data-longitude'));
var link = $(element).attr('data-link');
var title = $(element).attr('data-title');
var type = $(element).attr('data-type');
var date = $(element).attr('data-date');
tempMarker = new google.maps.Marker({
position : tempPos,
map : map,
title : title,
});
tempMarker.setIcon('http://maps.google.com/mapfiles/ms/icons/blue-dot.png')
var tempContentString = '<div style="width: 200px; height: 100px;">' + date + '<br></br>' + '<b>' + type + ' , ' + title + '</b>' + '</div>';
//Create infowindow
var tempInfowindow = new google.maps.InfoWindow({
content : tempContentString
});
//add market to markerArray
markersArray.push(tempMarker);
//Create event with infowindow
google.maps.event.addListener(tempMarker, 'click', function() {
tempInfowindow.open(map, this);
});
}
});
}
function findCenterOfMarkers() {
//calculate center of markers and change mapcenter to that
var sumlatitude = 0;
var sumlongitude = 0;
for ( position = 0; position < markersArray.length; position++) {
sumlatitude += markersArray[position].getPosition().lat();
sumlongitude += markersArray[position].getPosition().lat();
}
avglatitude = sumlatitude / markersArray.length;
avglongitude = sumlongitude / markersArray.length;
markercenter = new google.maps.LatLng(avglatitude, avglongitude);
}
function expandMapBoundForMarkers() {
//Extend bounds for map to fit all markers into map
for (var i in markersArray) {
bound.extend(markersArray[i].getPosition());
}
map.fitBounds(bound);
}
//loads the google maps api with KEY and appends the script to the document body
function loadScript() {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://maps.googleapis.com/maps/api/js?key=AIzaSyC8wZ6RmFySy0DnWvrUaA-2OJqcM1_AOIc&sensor=false&callback=initialize";
document.body.appendChild(script);
}
</script>
The only thing in the body of the page that has to do with the maps. Is the DIV that the map is loaded into.
<div id="map" style="width: 80%; height: 280px; margin: auto; background-color: gray">Kortet loader, vent venligst.</div> <!--alternative for full screen style="position:absolute;top:30px;bottom:50px;left:0;right:0;"-->
The API is also loaded in a common header script. Because I in general need to load it on other pages.
<script src='http://maps.google.com/maps/api/js?sensor=false'></script>
<script type="text/javascript">
$(document).ready( function () {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://maps.google.com/maps/api/js?sensor=false&callback=mynamespace.init_google_maps";
document.body.appendChild(script);
$(document).bind('pageinit', function() {
//do stuff here that happens each time a new page is loaded
});
});
});
</script>
the api is loaded once inside .ready(). you can create a new map in the callback that was passed to .bind() which is called each time a new page loads or is inserted. you can initialize the map inside mynamespace. mynamespace is a .js file included on the page