/*
* Copyright 2015-2017 WorldWind Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
define([
'../../../util/Color',
'../KmlElements',
'./KmlGeometry',
'../styles/KmlStyle',
'../../../geom/Location',
'../util/NodeTransformers',
'../../../shapes/Path',
'../../../geom/Position',
'../../../shapes/ShapeAttributes',
'../../../shapes/SurfacePolyline',
'../../../util/WWUtil'
], function (Color,
KmlElements,
KmlGeometry,
KmlStyle,
Location,
NodeTransformers,
Path,
Position,
ShapeAttributes,
SurfacePolyline,
WWUtil) {
"use strict";
/**
* Constructs an KmlLineString object. Applications shouldn't use this constructor. It is used by
* {@link KmlFile}. KmlLineString represents one line string.
* @param options {Object}
* @param options.objectNode {Node} Node representing LineString.
* @constructor
* @alias KmlLineString
* @classdesc Class representing LineString element of KmlFile
* @see https://developers.google.com/kml/documentation/kmlreference#linestring
* @augments KmlGeometry
*/
var KmlLineString = function (options) {
KmlGeometry.call(this, options);
this._style = null;
};
KmlLineString.prototype = Object.create(KmlGeometry.prototype);
Object.defineProperties(KmlLineString.prototype, {
/**
* Whether current shape should be extruded.
* @memberof KmlLineString.prototype
* @readonly
* @type {Boolean}
*/
kmlExtrude: {
get: function () {
return this._factory.specific(this, {name: 'extrude', transformer: NodeTransformers.boolean}) || false;
}
},
/**
* Whether tessellation should be used for current node.
* @memberof KmlLineString.prototype
* @readonly
* @type {Boolean}
*/
kmlTessellate: {
get: function () {
return this._factory.specific(this, {name: 'tessellate', transformer: NodeTransformers.boolean}) || false;
}
},
/**
* It represents different modes to count absolute altitude. Possible choices are explained in:
* https://developers.google.com/kml/documentation/kmlreference#point
* @memberof KmlLineString.prototype
* @readonly
* @type {String}
*/
kmlAltitudeMode: {
get: function () {
return this._factory.specific(this, {name: 'altitudeMode', transformer: NodeTransformers.string}) || WorldWind.ABSOLUTE;
}
},
/**
* Positions representing points used by the LineString.
* @memberof KmlLineString.prototype
* @readonly
* @type {Position[]}
*/
kmlPositions: {
get: function () {
return this._factory.specific(this, {name: 'coordinates', transformer: NodeTransformers.positions});
}
},
/**
* Returns average of the positions, which are part of the LineString. It averages also the altitudes.
* @memberof KmlLineString.prototype
* @readonly
* @type {Position}
*/
kmlCenter: {
get: function () {
// TODO choose better approximation than just plain average.
var positions = this.kmlPositions;
var midLatitude = 0;
var midLongitude = 0;
var midAltitude = 0;
positions.forEach(function (position) {
midLatitude += position.latitude;
midLongitude += position.longitude;
midAltitude += position.altitude;
});
return new Position(
midLatitude / this.kmlPositions.length,
midLongitude / this.kmlPositions.length,
midAltitude / this.kmlPositions.length
);
}
}
});
/**
* It creates Path representing this LineString unless already initialized.
* @param styles {Object|null}
* @param styles.normal {KmlStyle} Style applied when item not highlighted
* @param styles.highlight {KmlStyle} Style applied when item is highlighted
*/
KmlLineString.prototype.createPath = function (styles) {
if(this.kmlAltitudeMode == WorldWind.CLAMP_TO_GROUND) {
this._renderable = new SurfacePolyline(this.prepareLocations(), this.prepareAttributes(styles.normal));
} else {
this._renderable = new Path(this.prepareLocations(), this.prepareAttributes(styles.normal));
}
if(styles.highlight) {
this._renderable.highlightAttributes = this.prepareAttributes(styles.highlight);
}
this.moveValidProperties();
};
KmlLineString.prototype.render = function(dc, kmlOptions) {
KmlGeometry.prototype.render.call(this, dc, kmlOptions);
if(kmlOptions.lastStyle && !this._renderable) {
this.createPath(kmlOptions.lastStyle);
dc.redrawRequested = true;
}
if(this._renderable) {
this._renderable.enabled = this.enabled;
this._renderable.render(dc);
}
};
/**
* @inheritDoc
*/
KmlLineString.prototype.prepareAttributes = function (style) {
var shapeOptions = style && style.generate() || {};
shapeOptions._applyLighting = true;
shapeOptions._drawOutline = true;
shapeOptions._drawInterior = true;
shapeOptions._drawVerticals = this.kmlExtrude || false;
shapeOptions._outlineStippleFactor = 0;
shapeOptions._outlineStipplePattern = 61680;
shapeOptions._enableLighting = true;
return new ShapeAttributes(KmlStyle.shapeAttributes(shapeOptions));
};
/**
* Prepare locations representing current Line String.
* @returns {Position[]} Positions representing this LineString.
*/
KmlLineString.prototype.prepareLocations = function () {
return this.kmlPositions;
};
/**
* Moves KML properties from current object into the internal shape representation.
*/
KmlLineString.prototype.moveValidProperties = function () {
this._renderable.extrude = this.kmlExtrude || false;
this._renderable.altitudeMode = this.kmlAltitudeMode || WorldWind.ABSOLUTE;
//noinspection JSUnusedGlobalSymbols
this._renderable.tesselate = this.kmlTesselate || false;
};
/**
* Two line strings are equal when the properties and positions are equal.
* @param toCompare {KmlLineString} LineString to compare to.
* @returns {Boolean} True if the LineStrings are equal.
*/
KmlLineString.prototype.equals = function (toCompare) {
if (!toCompare) {
return false;
}
var positionsEquals = WWUtil.arrayEquals(toCompare.kmlPositions, this.kmlPositions);
return positionsEquals && toCompare.kmlExtrude == this.kmlExtrude && toCompare.kmlTessellate == this.kmlTessellate &&
toCompare.kmlAltitudeMode == this.kmlAltitudeMode;
};
/**
* @inheritDoc
*/
KmlLineString.prototype.getTagNames = function () {
return ['LineString'];
};
KmlElements.addKey(KmlLineString.prototype.getTagNames()[0], KmlLineString);
return KmlLineString;
});