diff --git a/src/GlobWeb.js b/src/GlobWeb.js
index 7a0843c..6bd77a8 100644
--- a/src/GlobWeb.js
+++ b/src/GlobWeb.js
@@ -20,7 +20,7 @@
define( ["./Globe", "./GeoBound",
"./WMSLayer", "./WMTSLayer", "./WCSElevationLayer", "./OSMLayer", "./BingLayer", "./VectorLayer", "./AtmosphereLayer", // Layers
"./Navigation", "./FeatureStyle", "./Stats", "./KMLParser", // Others
- "./PointRenderer", "./LineStringRenderable"], // Renderers
+ "./PointRenderer", "./LineStringRenderable", "./PolygonRenderer" ], // Renderers
function(Globe, GeoBound, WMSLayer, WMTSLayer, WCSElevationLayer, OSMLayer, BingLayer, VectorLayer, AtmosphereLayer, Navigation, FeatureStyle, Stats, KMLParser) {
// Declare GlobWeb
diff --git a/src/KMLParser.js b/src/KMLParser.js
index ae81d6e..d678df2 100644
--- a/src/KMLParser.js
+++ b/src/KMLParser.js
@@ -60,16 +60,16 @@ var KMLParser = (function()
var coords = coordsText.trim().split(/[\s,]+/);
for ( var i = 0; i < coords.length; i += 3 )
{
- coordinates.push( [ parseFloat(coords[i]), parseFloat(coords[i+1]) ] );
+ coordinates.push( [ parseFloat(coords[i]), parseFloat(coords[i+1]), parseFloat(coords[i+2]) ] );
}
return coordinates;
- }
+ };
/*
* Parse KML geometry, return a GeoJSON geometry
* @param node : a candiate node for geoemtry
*/
- var checkAndParseGeometry = function(node)
+ var checkAndParseGeometry = function(node,style)
{
switch ( node.nodeName )
{
@@ -80,7 +80,7 @@ var KMLParser = (function()
var children = node.childNodes;
for (var i = 0; i < children.length; i++)
{
- var geometry = checkAndParseGeometry(children[i]);
+ var geometry = checkAndParseGeometry(children[i],style);
if ( geometry )
{
geoms.push( geometry );
@@ -102,8 +102,18 @@ var KMLParser = (function()
break;
case "Polygon":
{
+ // Take into accout extresion
+ var extrude = node.getElementsByTagName("extrude");
+ if ( extrude.length == 1 )
+ {
+ style.extrude = parseInt( extrude[0].childNodes[0].nodeValue ) != 0;
+ }
+
+ style.fill = true;
+
// TODO : manage holes
- var coordNode = node.firstElementChild.getElementsByTagName("coordinates");
+ var outerBoundary = node.getElementsByTagName("outerBoundaryIs");
+ var coordNode = outerBoundary[0].getElementsByTagName("coordinates");
if ( coordNode.length == 1 )
{
return { type: "Polygon",
@@ -158,7 +168,7 @@ var KMLParser = (function()
break;
case "Style":
{
- var style = parseStyle(child,feature.properties.name);
+ var style = parseStyle(child,feature.properties.name,feature.properties.style);
if ( style )
{
feature.properties.style = style;
@@ -169,7 +179,7 @@ var KMLParser = (function()
// Try with geometry
if ( feature.geometry == null )
{
- feature.geometry = checkAndParseGeometry(child);
+ feature.geometry = checkAndParseGeometry(child,style);
}
}
child = child.nextElementSibling;
@@ -217,6 +227,24 @@ var KMLParser = (function()
}
}
+ /*
+ * Parse poly style
+ */
+ var parsePolyStyle = function(node,style)
+ {
+ var child = node.firstElementChild;
+ while ( child )
+ {
+ switch ( child.nodeName )
+ {
+ case "color":
+ style.fillColor = fromStringToColor( child.childNodes[0].nodeValue );
+ break;
+ }
+ child = child.nextElementSibling;
+ }
+ }
+
/*
* Parse line style
*/
@@ -290,15 +318,15 @@ var KMLParser = (function()
child = child.nextElementSibling;
}
}
-
+
/*
* Parse style
*/
- var parseStyle = function(node)
+ var parseStyle = function(node,parentStyle)
{
var id = '#' + node.getAttribute("id");
- var style = new FeatureStyle();
+ var style = new FeatureStyle(parentStyle);
styles[id] = style;
// Iterate through child to manage all different style element
@@ -307,6 +335,9 @@ var KMLParser = (function()
{
switch ( child.nodeName )
{
+ case "PolyStyle":
+ parsePolyStyle(child,style);
+ break;
case "LineStyle":
parseLineStyle(child,style);
break;
@@ -330,6 +361,9 @@ var KMLParser = (function()
{
switch ( node.nodeName )
{
+ case "Style":
+ parseStyle( node );
+ break
case "Placemark":
parsePlacemark( node );
break
diff --git a/src/PolygonRenderer.js b/src/PolygonRenderer.js
new file mode 100644
index 0000000..a5f78a0
--- /dev/null
+++ b/src/PolygonRenderer.js
@@ -0,0 +1,260 @@
+/***************************************
+ * Copyright 2011, 2012 GlobWeb contributors.
+ *
+ * This file is part of GlobWeb.
+ *
+ * GlobWeb is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GlobWeb is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with If not, see .
+ ***************************************/
+
+define( ['./CoordinateSystem','./VectorRendererManager','./FeatureStyle','./Program','./Triangulator'],
+ function(CoordinateSystem,VectorRendererManager,FeatureStyle,Program,Triangulator) {
+
+/**************************************************************************************************************/
+
+/** @constructor
+ * Basic renderer for polygon
+ */
+
+var PolygonRenderer = function(tileManager)
+{
+ this.renderContext = tileManager.renderContext;
+ var gl = this.renderContext.gl;
+
+ this.renderables = [];
+
+ this.vertexShader = "\
+ attribute vec3 vertex;\n\
+ uniform mat4 viewProjectionMatrix;\n\
+ void main(void) \n\
+ {\n\
+ gl_Position = viewProjectionMatrix * vec4(vertex, 1.0);\n\
+ }\n\
+ ";
+
+var fragmentShader = "\
+ precision lowp float; \n\
+ uniform vec4 u_color;\n\
+ void main(void)\n\
+ {\n\
+ gl_FragColor = u_color;\n\
+ }\n\
+ ";
+
+ this.program = new Program(this.renderContext);
+ this.program.createFromSource(this.vertexShader, fragmentShader);
+}
+
+/**************************************************************************************************************/
+
+/**
+ * Add polygon to renderer
+ */
+PolygonRenderer.prototype.addGeometry = function(geometry, layer, style){
+
+ var gl = this.renderContext.gl;
+
+ // Create renderable
+ var renderable = {
+ geometry : geometry,
+ style : style,
+ layer: layer,
+ vertexBuffer : gl.createBuffer(),
+ indexBuffer : gl.createBuffer(),
+ };
+
+ // Create texture
+ var self = this;
+
+ // Create vertex buffer
+ gl.bindBuffer(gl.ARRAY_BUFFER, renderable.vertexBuffer);
+
+ var coords = geometry['coordinates'][0];
+ var vertices = new Float32Array( style.extrude ? coords.length * 6 : coords.length * 3 );
+
+ // For polygons only
+ for ( var i=0; i < coords.length; i++)
+ {
+ var pos3d = [];
+ CoordinateSystem.fromGeoTo3D(coords[i], pos3d);
+ vertices[i*3] = pos3d[0];
+ vertices[i*3+1] = pos3d[1];
+ vertices[i*3+2] = pos3d[2];
+ }
+
+ if ( style.extrude )
+ {
+ var offset = coords.length * 3;
+ for ( var i=0; i < coords.length; i++)
+ {
+ var pos3d = [];
+ var coordAtZero = [ coords[i][0], coords[i][1], 0.0 ];
+ CoordinateSystem.fromGeoTo3D( coordAtZero, pos3d);
+ vertices[offset] = pos3d[0];
+ vertices[offset+1] = pos3d[1];
+ vertices[offset+2] = pos3d[2];
+ offset += 3;
+ }
+ }
+
+ gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
+ // Create index buffer(make shared ?)
+ var indices = [];
+ indices = Triangulator.process( coords );
+
+ if ( indices == null )
+ {
+ console.error("Triangulation error ! Check if your GeoJSON geometry is valid");
+ return false;
+ }
+
+
+ if ( style.extrude )
+ {
+ var upOffset = 0;
+ var lowOffset = coords.length;
+
+ for ( var i = 0; i < coords.length-1; i++ )
+ {
+ indices.push( upOffset, upOffset + 1, lowOffset );
+ indices.push( upOffset + 1, lowOffset + 1, lowOffset );
+
+ upOffset += 1;
+ lowOffset += 1;
+ }
+ }
+
+ renderable.numTriIndices = indices.length;
+
+ var offset = 0;
+ for ( var i = 0; i < coords.length-1; i++ )
+ {
+ indices.push( offset, offset + 1 );
+ offset += 1;
+ }
+ if ( style.extrude )
+ {
+ var upOffset = 0;
+ var lowOffset = coords.length;
+ for ( var i = 0; i < coords.length-1; i++ )
+ {
+ indices.push( upOffset, lowOffset );
+
+ upOffset += 1;
+ lowOffset += 1;
+ }
+ }
+
+ renderable.numLineIndices = indices.length - renderable.numTriIndices;
+
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, renderable.indexBuffer);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
+
+ this.renderables.push(renderable);
+
+}
+
+/**************************************************************************************************************/
+
+/**
+ * Remove polygon from renderer
+ */
+PolygonRenderer.prototype.removeGeometry = function(geometry,style){
+
+ for ( var i = 0; i 0 )
+ {
+ gl.uniform4f(this.program.uniforms["u_color"], style.strokeColor[0], style.strokeColor[1], style.strokeColor[2], style.strokeColor[3] * renderable.layer._opacity);
+ gl.drawElements( gl.LINES, renderable.numLineIndices, gl.UNSIGNED_SHORT, renderable.numTriIndices * 2);
+ }
+ }
+
+ //gl.enable(gl.DEPTH_TEST);
+ gl.depthFunc(gl.LESS);
+ gl.disable(gl.BLEND);
+}
+
+/**************************************************************************************************************/
+
+// Register the renderer
+VectorRendererManager.registerRenderer({
+ creator: function(globe) {
+ return new PolygonRenderer(globe.tileManager);
+ },
+ canApply: function(type,style) {return (type == "Polygon") && (style.fill == true); }
+});
+
+});
\ No newline at end of file