I want to export telephone poles and cables out of our database into a KML file for Google Earth.
For every node we have an array of poles, the cables are always connected towards the next pole in the array.
An export making simple paths seems to be easy enough. But these paths just show a path, they don't show every waypoint (telephone pole).
This is an example in Google Maps what I want to achieve in .kml
If you want paths and points for each of the poles (aka waypoints) then you need your KML to include not only the line segments separate points for each of the positions of the poles.
Your KML will need to be structured like this where poleSyle will have an IconStyle with the icon you want for the points and lineStyle will be a thick green line
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document>
<Style id="poleStyle">
...
</Style>
<Style id="lineStyle">
...
</Style>
<Placemark>
<styleUrl>#lineStyle</styleUrl>
<LineString>
<coordinates>...</coordinates>
</LineString>
</Placemark>
<Placemark>
<name>pole1</name>
<description>address pole1</description>
<styleUrl>#poleStyle</styleUrl>
<Point>
<coordinates>...</coordinates>
</Point>
</Placemark>
...
</Document>
</kml>
If you don't want or need a unique name or description for every point then you can combine the points in a single Placemark inside a MultiGeometry like this:
<Placemark>
<styleUrl>#poleStyle</styleUrl>
<MultiGeometry>
<Point>
<coordinates>...</coordinates>
</Point>
<Point>
<coordinates>...</coordinates>
</Point>
</MultiGeometry>
</Placemark>
<?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">
<Document>
<Style id="Line1">
<LineStyle>
<color>ffff0000</color>
<width>4</width>
</LineStyle>
</Style>
<Style id="Line2">
<LineStyle>
<color>ff00ff00</color>
<width>4</width>
</LineStyle>
</Style>
<Style id="Poly1">
<PolyStyle>
<color>ff0000ff</color>
</PolyStyle>
</Style>
<Style id="Poly2">
<PolyStyle>
<color>ffffffff</color>
</PolyStyle>
</Style>
<Placemark>
<name>Line 1</name>
<styleUrl>#Line1</styleUrl>
<LineString>
<coordinates>
-112.265654928602,36.09447672602546,2357
-112.2660384528238,36.09342608838671,2357
-112.2668139013453,36.09251058776881,2357
-112.2677826834445,36.09189827357996,2357
-112.2688557510952,36.0913137941187,2357
-112.2694810717219,36.0903677207521,2357
-112.2695268555611,36.08932171487285,2357
-112.2690144567276,36.08850916060472,2357
-112.2681528815339,36.08753813597956,2357
-112.2670588176031,36.08682685262568,2357
-112.2657374587321,36.08646312301303,2357
</coordinates>
<gx:drawOrder>2</gx:drawOrder>
</LineString>
</Placemark>
<Placemark>
<name>Polygon 1</name>
<styleUrl>#Poly1</styleUrl>
<Polygon>
<outerBoundaryIs>
<LinearRing>
<coordinates>
-112.265654928602,36.09447672602546,2357
-112.2660384528238,36.09342608838671,2357
-112.2668139013453,36.09251058776881,2357
-112.2677826834445,36.09189827357996,2357
-112.2688557510952,36.0913137941187,2357
-112.2694810717219,36.0903677207521,2357
-112.2695268555611,36.08932171487285,2357
-112.2690144567276,36.08850916060472,2357
-112.2681528815339,36.08753813597956,2357
-112.2670588176031,36.08682685262568,2357
-112.2657374587321,36.08646312301303,2357
</coordinates>
</LinearRing>
</outerBoundaryIs>
<gx:drawOrder>4</gx:drawOrder>
</Polygon>
</Placemark>
<Placemark>
<name>Line 2</name>
<styleUrl>#Line2</styleUrl>
<LineString>
<coordinates>
-112.265654928602,36.09447672602546,2357
-112.2660384528238,36.09342608838671,2357
-112.2668139013453,36.09251058776881,2357
-112.2677826834445,36.09189827357996,2357
-112.2688557510952,36.0913137941187,2357
-112.2694810717219,36.0903677207521,2357
-112.2695268555611,36.08932171487285,2357
-112.2690144567276,36.08850916060472,2357
-112.2681528815339,36.08753813597956,2357
-112.2670588176031,36.08682685262568,2357
-112.2657374587321,36.08646312301303,2357
</coordinates>
<gx:drawOrder>4</gx:drawOrder>
</LineString>
</Placemark>
<Placemark>
<name>Polygon 2</name>
<styleUrl>#Poly2</styleUrl>
<Polygon>
<outerBoundaryIs>
<LinearRing>
<coordinates>
-112.265654928602,36.09447672602546,2357
-112.2660384528238,36.09342608838671,2357
-112.2668139013453,36.09251058776881,2357
-112.2677826834445,36.09189827357996,2357
-112.2688557510952,36.0913137941187,2357
-112.2694810717219,36.0903677207521,2357
-112.2695268555611,36.08932171487285,2357
-112.2690144567276,36.08850916060472,2357
-112.2681528815339,36.08753813597956,2357
-112.2670588176031,36.08682685262568,2357
-112.2657374587321,36.08646312301303,2357
</coordinates>
</LinearRing>
</outerBoundaryIs>
<gx:drawOrder>8</gx:drawOrder>
</Polygon>
</Placemark>
</Document>
</kml>
So As you can see in the above kml I've tried to use the gx:drawOrder element to sort the line strings & the polygons into drawing layers. BUT... if you load this in the kml interactive sampler or even Google Earth (free desktop edition) the geometry primitives only z order sort among "like primitives". That is, the line strings are sorted only against other line strings and the polygons are only sorted against other polygons.
In this case you can see that both "line 1" and "line 2" have draw orders of < "Polygon 2" & I as such I was expecting "polygon 2" to draw over the top of everything. But that is NOT the case.
In the end I've had to use altitude values to implement the z order that I want, but it's quite an unsatisfactory solution as most people view kml geometry using an isometric projection & the altitude values cause my geometry to skew.
What I'd like to know is this:
Is this the expected behavior of gx:drawOrder? The document around the element is sparse & it even says that it's only applicable to the line string, but according to the xsd is should be applicable to all geometry primitives (which it appears to be... well at least to polygons as well anyway...)
Is there a way to get the gx:drawOrder to be applicable over all
geometry primitives?
Thanks in advance!
The KML documentation only mentions <gx:drawOrder> with respect to line strings not polygons nor does it mention the behavior of drawOrder across different geometries (lines, rings, and polygons). The drawOrder support for Polygons is undocumented but was reported as an issue in the bug tracker.
You would naturally expect the drawOrder to work the same over all geometry primitives, but looks like Google Earth draws the features in groups by type: polygons, then ground overlays, followed by lines and point data where drawOrder is applied only within a group. ScreenOverlays are drawn last so they are always on top.
This means that a polygon with drawOrder=2 overlapping a line with drawOrder=1 still shows the polygon under the line. Also, even if a polygon has a higher value drawOrder and overlaps a GroundOverlay (aka Image Overlay), the polygon is drawn first and hidden under the GroundOverlay.
gx:DrawOrder is not part of the OGC KML 2.2 standard. It's a Google KML Extension so Google defines how it works. Also means Google can change how it works.
So I've been sifting through GE's documentation, and found how to do LineStyle and LineString to style and display a line, but in practice I cannot actually make it work. Here's my KML:
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2"><Document><Style id="thisStyle">
<LineStyle>
<color>500078F0</color>
<colorMode>Normal</colorMode>
<width>5</width>
</LineStyle>
</Style>
<Placemark>
<name>502-2012-11-19 05:27:03</name>
<description>Speed:0</description>
<Point>
<coordinates>-76.0513,42.0894,247</coordinates>
</Point>
</Placemark>
<Placemark>
<name>502-2012-11-19 05:26:46</name>
<description>Speed:0</description>
<Point>
<coordinates>-76.0517,42.0886,287</coordinates>
</Point>
</Placemark>
....
<Placemark>
<name>525-2012-11-19 04:38:25</name>
<description>Speed:0</description>
<Point>
<coordinates>-76.0512,42.0894,178</coordinates>
</Point>
</Placemark>
<styleUrl>#thisStyle</styleUrl>
<LineString>
<tessellate>1</tessellate>
<altitudeMode>clampToGround</altitudeMode>
<coordinates>
-76.0513,42.0894,247
-76.0517,42.0886,287
....
-76.0512,42.0894,178
</coordinates></LineString></Document></kml>
Note: The above places where "..." appears there are about 50 more coordinate sets, I removed them for the sake of brevity, but since all coordinates are produced by a script if one works I know they all will. Can anyone nudge me in the right direction as to why my placemarks all show up, but no lines?
A LineString element is only valid inside a Placemark (or a MultiGeometry inside a Placemark):
<Placemark>
<LineString>
<tessellate>1</tessellate>
<altitudeMode>clampToGround</altitudeMode>
<coordinates>
-76.0513,42.0894,247
-76.0517,42.0886,287
-76.0512,42.0894,178
</coordinates>
</LineString>
</Placemark>
Example on Google Maps with your KML
Example on Google Maps with a Placemark containing the Linestring
You must either inline Style in the Placemark or reference the style in the Placemark using styleUrl element.
The last Placemark in your example needs to be rewritten like this:
<Placemark>
<name>525-2012-11-19 04:38:25</name>
<description>Speed:0</description>
<styleUrl>#thisStyle</styleUrl>
<LineString>
<tessellate>1</tessellate>
<altitudeMode>clampToGround</altitudeMode>
<coordinates>
-76.0513,42.0894,247
-76.0517,42.0886,287
...
-76.0512,42.0894,178
</coordinates>
</LineString>
</Placemark>
If your KML doesn't view correctly then it usually helps to validate the KML. You can use the KML Validator.
If you only have a height above ground level for the starting point of a polygon: Is there a way to create the polygon so that all the following points have the same height relative to sea level? i.e. the polygon will be flat on the horizontal plain regardless of the terrain.
Does anyone have a method of doing this without knowing/obtaining the height above sea level before generating the kml?
Any help would be greatly appreciated.
Create a polygon using relativeToGround altitudeMode, which interprets the altitude as a value in meters above the ground.
Note: you'll need to specify the altitude value for each point. Can't just specify altitude for one and have others use same altitude. If you omit altitude it defaults to "0".
Here's polygon with each point set at 10 meters above ground.
<?xml version="1.0" encoding="utf-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Placemark>
<name>tennis-poly</name>
<Polygon>
<altitudeMode>relativeToGround</altitudeMode>
<outerBoundaryIs>
<LinearRing>
<coordinates>
-122.43193945401,37.801983684521,10
-122.431564131101,37.8020327731402,10
-122.431499536494,37.801715236748,10
-122.43187136387,37.8016634915437,10
-122.43193945401,37.801983684521,10
</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
</Placemark>
</kml>
If want the polygon to be flat on the horizontal plain regardless of the terrain then the altitudeMode must be absolute which is respect to mean sea level. You could skip defining the altitude in the coordinates and specify a single height using a <gx:altitudeOffset>.
<?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">
<Placemark>
<name>tennis-poly</name>
<Polygon>
<altitudeMode>absolute</altitudeMode>
<outerBoundaryIs>
<LinearRing>
<gx:altitudeOffset>50</gx:altitudeOffset>
<coordinates>
-122.43193945401,37.801983684521
-122.431564131101,37.8020327731402
-122.431499536494,37.801715236748
-122.43187136387,37.8016634915437
-122.43193945401,37.801983684521
</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
</Placemark>
</kml>
Your only possible woraround of this would be to get the sea level height of the first point and use that height on the other points as well:
Get altitude by longitude and latitude in Android
How do you links cities with a curve (line) in kml for Google Earth?
First, since you are on SO I'm assuming you are asking from a KML perspective and not just in the desktop application.
You would need to have the coordinates of the two cities. Then you would create a kml document like the following from the docs using your coordinates in the coordinates element (note that you don't need the "LookAt" element, but it will bring your camera to the relevant area):
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document>
<name>LineString.kml</name>
<open>1</open>
<LookAt>
<longitude>-122.36415</longitude>
<latitude>37.824553</latitude>
<altitude>0</altitude>
<range>150</range>
<tilt>50</tilt>
<heading>0</heading>
</LookAt>
<Placemark>
<name>unextruded</name>
<LineString>
<extrude>1</extrude>
<tessellate>1</tessellate>
<coordinates>
-122.364383,37.824664,0 -122.364152,37.824322,0
</coordinates>
</LineString>
</Placemark>
<Placemark>
<name>extruded</name>
<LineString>
<extrude>1</extrude>
<tessellate>1</tessellate>
<altitudeMode>relativeToGround</altitudeMode>
<coordinates>
-122.364167,37.824787,50 -122.363917,37.824423,50
</coordinates>
</LineString>
</Placemark>
</Document>
</kml>
If you don't have the city altitudes then leave them out and be sure to set the altitudeMode element to "clampToGround" and likely the tesselate element to "1" (meaning true). If you forget this your lines may disappear underground.