I am working on an application that will make a KML file with PHP. Typically I have done this with single points and had no or little problem, but for polygons I'm having one heck of a hard time getting them to stylize.
What I am attempting to do is colorize a polygon shape based on a dynamic style from PHP; however, I can't even get a hard-coded style to work first. The structure of the KML is shown after the code sample I'm having problems with.
What should the proper style dom syntax look like if all I want to do is setup a polygon color style and a certain width.
Thanks for your help
Here is the initial code:
// Creates the Document.
$dom = new DOMDocument('1.0', 'UTF-8');
$kmlfile = $dom->createElementNS('http://earth.google.com/kml/2.1', 'kml');
$parentnode = $dom->appendChild($kmlfile);
$dfnode = $dom->createElement('Document');
$documentnode = $parentnode->appendChild($dfnode);
$gpsStyleNode = $dom->createElement('Style');
$gpsStyleNode->setAttribute('id', 'style_gps');
$gpsIconstyleNode = $dom->createElement('IconStyle');
$gpsIconstyleNode->setAttribute('id', 'icon_gps');
$gpsIconstyleNode->setAttribute('scale', '0.6');
$gpsIconstyleNode->setAttribute('color', 'ff0000ff');
$gpsIconNode = $dom->createElement('Icon');
$gpsHref = $dom->createElement('href', 'http://maps.google.com/mapfiles/kml/shapes/cross-hairs.png');
$gpsIconNode->appendChild($gpsHref);
$gpsIconstyleNode->appendChild($gpsIconNode);
$gpsStyleNode->appendChild($gpsIconstyleNode);
$gpslinetyleNode = $dom->createElement('PolyStyle');
$gpsStyleNode->appendChild($gpslinetyleNode);
$gpslinetyleNode->setAttribute('id', 'Icon_gps2');
$gpslinetyleNode->setAttribute('color', 'ff0000ff');
$gpslinetyleNode->setAttribute('width', '20');
$documentnode->appendChild($gpsStyleNode);
KML Output
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
<Placemark id="12">
<name>PolygonName</name>
<description>test</description>
<styleUrl>Icon_gps2</styleUrl>
<Polygon>
<extrude>1</extrude>
<altitudeMode>relativeToGround</altitudeMode>
<outerBoundaryIs>
<LinearRing>
<coordinates>
(Dynamic Coords pulled from DB in proper format)
</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
</Placemark>
</kml>
EDIT to add Polygon Code
$placeobject = $dom->createElement('Placemark');
$placeNode = $nDoc->appendChild($placeobject);
$placeobject->setAttribute('id',$tmpid);
$placename = $dom->createElement('name','PolygonName');
$placeNode->appendChild($placename);
$placedesc = $dom->createElement('description', 'test');
$placeNode->appendChild($placedesc);
$stylenode =$dom->createElement('styleUrl','line_gps');
$placeNode->appendChild($stylenode);
$linenode = $dom->createElement('Polygon');
$placeNode->appendChild($linenode);
$lineextrude = $dom->createElement('extrude', '1');
$linenode->appendChild($lineextrude);
$linealtitude = $dom->createElement('altitudeMode', 'relativeToGround');
$linenode->appendChild($linealtitude);
$outerboundnode = $dom->createElement('outerBoundaryIs');
$linenode = $linenode->appendChild($outerboundnode);
$ringtype =$dom->createElement('LinearRing');
$linenode = $linenode->appendChild($ringtype);
$coordnode = $dom->createElement('coordinates',$locationstring);
$ringtype->appendChild($coordnode);
Your are setting attributes(color,scale,width) which are expected as elements.
Furthermore width applies to LineStyle and not to PolyStyle
$dom = new DOMDocument('1.0', 'UTF-8');
$nKml = $dom->appendChild($dom->createElementNS('http://earth.google.com/kml/2.1', 'kml'));
$nDoc = $nKml->appendChild($dom->createElement('Document'));
$idSuffix='_gps';
//Style
$nStyle = $nDoc->appendChild($dom->createElement('Style'));
$nStyle->setAttribute('id', 'style'.$idSuffix);
//IconStyle
$nIconStyle = $nStyle->appendChild($dom->createElement('IconStyle'));
$nIconStyle->setAttribute('id', 'icon'.$idSuffix);
//color
$nIconStyleColor=$nIconStyle->appendChild($dom->createElement('color'));
$nIconStyleColor->appendChild($dom->createTextNode('ff0000ff'));
//Icon
$nIconStyleIcon=$nIconStyle->appendChild($dom->createElement('Icon'));
//href
$nIconStyleHref=$nIconStyleIcon->appendChild($dom->createElement('href'));
$nIconStyleHref->appendChild($dom->createTextNode('http://maps.google.com/../cross-hairs.png'));
//PolyStyle
$nPolyStyle = $nStyle->appendChild($dom->createElement('PolyStyle'));
$nPolyStyle->setAttribute('id', 'poly'.$idSuffix);
//color
$nPolyStyleColor=$nPolyStyle->appendChild($dom->createElement('color'));
$nPolyStyleColor->appendChild($dom->createTextNode('ff0000ff'));
//LineStyle
$nLineStyle = $nStyle->appendChild($dom->createElement('LineStyle'));
$nLineStyle->setAttribute('id', 'line'.$idSuffix);
//width
$nLineStyleWidth=$nLineStyle->appendChild($dom->createElement('width'));
$nLineStyleWidth->appendChild($dom->createTextNode('20'));
$nLineStyleColor=$nLineStyle->appendChild($dom->createElement('color'));
$nLineStyleColor->appendChild($dom->createTextNode('ff0000ff'));
result:
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.1">
<Document>
<Style id="style_gps">
<IconStyle id="icon_gps">
<color>ff0000ff</color>
<Icon>
<href>http://maps.google.com/../cross-hairs.png</href>
</Icon>
</IconStyle>
<PolyStyle id="poly_gps">
<color>ff0000ff</color>
</PolyStyle>
<LineStyle id="line_gps">
<width>20</width>
<color>ff0000ff</color>
</LineStyle>
</Style>
</Document>
</kml>
Related
Is there a why to do this? I'm new on create DomDocument. Thank you
<!DOCTYPE Data SYSTEM "http://data.data.org/schemas/data/1.234.1/data.dtd"> <Data payloadID = "123123123131231232323" timestamp = "2015-06-10T12:59:09-07:00">
$aribaXML = new DOMImplementation;
$dtd = $aribaXML->createDocumentType('cXML', '', 'http://xml.cxml.org/schemas/cXML/1.2.014/cXML.dtd');
$dom = $aribaXML->createDocument('', '', $dtd);
Here are two ways in DOM to create a new document in PHP. If you don't need the DTD you can directly create an instance of the DOMDocument class.
$document = new DOMDocument('1.0', "UTF-8");
$document->appendChild(
$cXML = $document->createElement('cXML')
);
echo $document->saveXML();
Output:
<?xml version="1.0" encoding="UTF-8"?>
<cXML/>
For a document with a DTD your approach was correct.
$implementation = new DOMImplementation;
$dtd = $implementation->createDocumentType(
'cXML', '', 'http://xml.cxml.org/schemas/cXML/1.2.014/cXML.dtd'
);
$document = $implementation->createDocument("", "cXML", $dtd);
$document->encoding = 'UTF-8';
$cXML = $document->documentElement;
echo $document->saveXML();
Output:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE cXML SYSTEM "http://xml.cxml.org/schemas/cXML/1.2.014/cXML.dtd">
After the initial bootstrap you use methods of the $document to create nodes and append them.
// set an attribute on the document element
$cXML->setAttribute('version', '1.1.007');
// xml:lang is a namespaced attribute in a reserved namespace
$cXML->setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:lang', 'en-US');
// nested elements
// create a node, store it for the next call and append it
$cXML->appendChild(
$header = $document->createElement('Header')
);
$header->appendChild(
$from = $document->createElement('From')
);
$from->appendChild(
$credential = $document->createElement('Credential')
);
// "Identity" has only a text node so we don't need to store it for later
$credential->appendChild(
$document->createElement('Identity')
)->textContent = '83528721';
// format serialized XML string
$document->formatOutput = TRUE;
echo $document->saveXML();
Output:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE cXML SYSTEM "http://xml.cxml.org/schemas/cXML/1.2.014/cXML.dtd">
<cXML version="1.1.007" xml:lang="en-US">
<Header>
<From>
<Credential>
<Identity>83528721</Identity>
</Credential>
</From>
</Header>
</cXML>
$xml = new DomDocument('1.0');
$xml->formatOutput = true;
$works = $xml->createElement("works");
$xml->appendChild($works);
$work = $xml->createElement("work");
$work->setAttribute("id",1);
$works->appendChild($work);
$xml->save("storage/document.xml") or die("Error, Unable to create XML File");
I have the following PHP code from which I need to generate XML.
$hparams["SiteName"]="";
$hparams["AccountCode"]="";
$hparams["UserName"]='xxxx';
$hparams["Password"]='xxxx';
$client_header = new SoapHeader('url','AuthenticationData',$hparams,false);
$cliente = new SoapClient($wsdl); $cliente->__setSoapHeaders(array($client_header));
$opta=array();
$opta["Search"]["request"]["Origin"]="MAA";
$opta["Search"]["request"]["Destination"]="BOM";
$opta["Search"]["request"]["DepartureDate"]="2014-05-20T00:00:00";
$opta["Search"]["request"]["ReturnDate"]="2014-05-22T00:00:00";
$opta["Search"]["request"]["Type"]="OneWay";
$opta["Search"]["request"]["CabinClass"]="All";
$opta["Search"]["request"]["PreferredCarrier"]="";
$opta["Search"]["request"]["AdultCount"]="1";
$opta["Search"]["request"]["ChildCount"]="0";
$opta["Search"]["request"]["InfantCount"]="0";
$opta["Search"]["request"]["SeniorCount"]="0";
$opta["Search"]["request"]["IsDirectFlight"]="true";
$opta["Search"]["request"]["PromotionalPlanType"]="Normal";
$h=array();
$h= (array)$cliente->__call('Search',$opta);
How can I generate an XML of the above variables in PHP ?
The format should be
<xml>
<credential>
<Sitename>sitename</Sitename>
<AccountCode>ACC Code</AccountCode>
</credentials>
<Data>
<Origin>MAA</Origin>
<Destination>BOM</Destination>
</Data>
</xml>
Any help would be appreciate.
Thank you.
<?php
ini_set('error_reporting', E_ALL);
$dom = new DomDocument('1.0'); // making xml
$credentials = $dom->appendChild($dom->createElement('Credentials')); // adding root element <credentials>
$sitename = $credentials->appendChild($dom->createElement('Sitename')); // adding element <sitename> in <credentials>
$accountcode = $credentials->appendChild($dom->createElement('AccountCode')); // adding element <accountcode> in <credentials>
$sitename->appendChild($dom->createTextNode('sitename')); // adding text in <sitename>
$accountcode->appendChild($dom->createTextNode('ACC Code')); // adding text in <accountcode>
$data = $dom->appendChild($dom->createElement('Data'));
$origin = $data->appendChild($dom->createElement('Origin'));
$destination = $data->appendChild($dom->createElement('Destination'));
$origin->appendChild($dom->createTextNode('MAA'));
$destination->appendChild($dom->createTextNode('BOM'));
$dom->formatOutput = true; // generating xml
// generating XML as string or file
$test1 = $dom->saveXML();
$dom->save('test1.xml');
?>
I think you could write loop by yourself ;)
P.S. PHP 5+
First of all, your xml is not well structured.
It should be like:
<xml>
<credentials>
<Sitename>sitename</Sitename>
<AccountCode>ACC Code</AccountCode>
<Data>
<Origin>MAA</Origin>
<Destination>BOM</Destination>
</Data>
</credentials>
<credentials>
...
</credentials>
</xml>
Iterate the obtained result, and by concating , form the needed xml.
I have a small requirement where I need to create a XML file on the fly. It was no problem for me to create a normal xml file which would be looking like this:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<item>
<name></name>
</item>
</root>
But my requirement is such that I need to create a XML file whose output is:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<item>
<name url = "C:\htdocs\proj1\source_file1"/>
<name url = "C:\htdocs\proj1\source_file2"/>
<name url = "C:\htdocs\proj1\source_file3"/>
</item>
</root>
I have tried in this fashion:
<?php
$domtree = new DOMDocument('1.0', 'UTF-8');
$domtree->formatOutput = true;
$xmlRoot = $domtree->createElement("root");
$xmlRoot = $domtree->appendChild($xmlRoot);
$item = $domtree->createElement("item");
$item = $xmlRoot->appendChild($item);
$name= $domtree->createElement("name");
$name = $item->appendChild($name);
$sav_xml = $domtree->saveXML();
$handle = fopen("new.xml", "w");
fwrite($handle, $sav_xml);
fclose($handle);
?>
But I wanted to append/add the url="path" to my elements. I have tried declaring variables with url and path but this throws me errors like:
Uncaught exception 'DOMException' with message 'Invalid Character Error'
Any ideas how to approach this problem!
Thanks
You just have to declare that attributes via php DOM:
...
$name= $domtree->createElement("name");
$urlAttribute = $domtree->createAttribute('url');
$urlAttribute->value = 'C:\htdocs\proj1\source_file1';
$name->appendChild($urlAttribute);
$item->appendChild($name);
...
Link to DOMDocument docs
Is there a way to parse google maps *.kml file with simple_xml_load_file("*.kml") ?
I need to save in my database name and coordinates of each polygons registered in my KML file.
On my PHP script, simple_xml_load_file("*.kml") return false, so I can't read it.
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
<Document>
<Schema>
...
</Schema>
<Style id="FEATURES">
...
</Style>
<Folder>
<Placemark>
<name>
name
</name>
<Polygon>
<LinearRing>
<coordinates>
coordinates
</coordinates>
</LinearRing>
</Polygon>
</Placemark>
<Placemark>
...
</Placemark>
</Folder>
</Document>
</kml>
I need "name" and "coordinates" values for each "Placemark".
The xml structure is exactly that xml you sent:
For example:
<Document>
<Placemark>
<name>356HH</name>
<description>
</description>
<Polygon><outerBoundaryIs><LinearRing><coordinates>some cordinates here</coordinates></LinearRing></innerBoundaryIs></Polygon>
<Style><LineStyle><color>ff0000ff</color></LineStyle> <PolyStyle><fill>0</fill></PolyStyle></Style>
</Placemark>
<Placemark>
</document>
And it's my php code:
<?php
$completeurl = "2.xml";
$xml = simplexml_load_file($completeurl);
$placemarks = $xml->Document->Placemark;
$con=mysqli_connect("localhost","root","","j3");
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$query = '';
$run='';
for ($i = 0; $i < sizeof($placemarks); $i++) {
$coordinates = $placemarks[$i]->name;
$cor_d = explode(' ', $placemarks[$i]->Polygon->outerBoundaryIs->LinearRing->coordinates);
$qtmp=array();
foreach($cor_d as $value){
$tmp = explode(',',$value);
$ttmp=$tmp[1];
$tmp[1]=$tmp[0];
$tmp[0]=$ttmp;
$qtmp[]= '(' . $tmp[0] . ',' .$tmp[1].')';
}
$cor_d = json_encode($qtmp);
$query .='\''.$coordinates.'\', \''.$cor_d.'\'';
$run .="INSERT INTO jos_rpl_addon_zipinfo (name, boundary) VALUES (".$query." );";
//echo $run;
//break;
}
mysqli_query($con,$run);
//echo $run;
mysqli_close($con);
?>
The first line:
<?xml version="1.0" encoding="UTF-8"?>
Tells PHP that this is a document encoded in UTF-8, but your error says it is not encoded as UTF-8. Is this a doc you created with a text editor? If so, you can usually use your editor to save it out in UTF-8. Or you can probably use PHP to detect the encoding and change that first line.
If the XML strucutre is as what you have posted, you can try :-
$xml = simplexml_load_file(...);
$childs = $xml->Document->Folder->children();
foreach ($childs as $child)
{
// child object is same as -> Placemark
}
Example :-
SimpleXMLElement Object
(
[name] =>
name
[Polygon] => SimpleXMLElement Object
(
[LinearRing] => SimpleXMLElement Object
(
[coordinates] =>
coordinates
)
)
)
here i am creating xml file dynamically at run time but i m getting error
XML Parsing Error: junk after document element
Location: http://localhost/tam/imagedata.php?imageid=8
Line Number 9, Column 1:
^
$id=$_GET['imageid'];
$dom = new DomDocument('1.0');
$query="select * from tbl_image_gallery where imageId='$id'";
$select=mysql_query($query);
while($res=mysql_fetch_array($select))
{
$content = $dom->appendChild($dom->createElement('content'));
$image = $content->appendChild($dom->createElement('image'));
$small_image_path = $image->appendChild($dom->createElement('small_image_path'));
$small_image_path->appendChild($dom->createTextNode("load/images/small/".$res['image']));
$big_image_path = $image->appendChild($dom->createElement('big_image_path'));
$big_image_path->appendChild($dom->createTextNode("load/images/big/".$res['image']));
$description = $image->appendChild($dom->createElement('description'));
$description->appendChild($dom->createTextNode($res['description']));
$dom->formatOutput = true;
}
echo $test1 = $dom->saveXML();
and xml format is
<?xml version="1.0"?>
<content>
<image>
<small_image_path>load/images/small/1.jpg</small_image_path>
<big_image_path>load/images/big/1.jpg</big_image_path>
<description>hgjghj</description>
</image>
<image><small_image_path>load/images/small/2.jpg</small_image_path><big_image_path>load/images/big/2.jpg</big_image_path><description>fgsdfg</description></image><image><small_image_path>load/images/small/3.jpg</small_image_path><big_image_path>load/images/big/3.jpg</big_image_path><description>sdfgsdfg</description></image><image><small_image_path>load/images/small/4.jpg</small_image_path><big_image_path>load/images/big/4.jpg</big_image_path><description>gsbhsg</description></image><image><small_image_path>load/images/small/4.jpg</small_image_path><big_image_path>load/images/big/4.jpg</big_image_path><description>gsbhsg</description></image><image><small_image_path>load/images/small/avatar.jpg</small_image_path><big_image_path>load/images/big/avatar.jpg</big_image_path><description></description></image></content>
Can it be that you are posting html code into the description field?
Could be usefull to add a CDataSection instead of a TextNode
$cdata = $dom->createCDATASection($res['description']);
$image->appendChild($cdata);