com.scalakml.io.KmlFromXml.scala Maven / Gradle / Ivy
The newest version!
/*
* Copyright (c) 2013, Ringo Wathelet
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* - Neither the name of "scalakml" nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.scalakml.io
import com.scalakml.gx._
import com.scalakml.kml._
import scala.xml._
import com.scalaxal.io.XalFromXml._
import scala.language.postfixOps
import scala.language.implicitConversions
import scala.collection.mutable
/**
* @author Ringo Wathelet
* Date: 12/12/12
* Version: 1
*
* Reference: OGC 07-147r2 Version: 2.2.0, Category: OGC Standard, Editor: Tim Wilson, at
* http://www.opengeospatial.org/standards/kml
* also
* Google developers KML Reference, at
* https://developers.google.com/kml/documentation/kmlreference
*
*/
/**
* the creation of a kml root element object from an xml node sequence
*/
trait KmlExtractor {
def makeKml(nodeSeq: NodeSeq): Option[Kml]
}
/** Factory for creating kml objects instances from scala xml NodeSeq */
object KmlFromXml extends KmlExtractor {
import FeatureTypes._
import GeometryTypes._
import ContainerTypes._
import KmlObjectTypes._
import UpdateOptionTypes._
import TourPrimitiveTypes._
/**
* creates a Kml root element from the XML NodeSeq, e.g. ...
* The Kml consists of 0 or 1 Feature type object, and 0 or 1 NetworkLinkControl
* The Kml can also have a hint attribute used as a signal to Google Earth to display the file as celestial data.
*
* @param nodeSeq the xml NodeSeq
* @return a Kml Option
*/
def makeKml(nodeSeq: NodeSeq): Option[Kml] = {
if (nodeSeq.isEmpty) None
else
(nodeSeq \\ "kml") match {
case x if x.isEmpty => None
case x => Some(new Kml(makeNetworkLinkControl(x \ "NetworkLinkControl"), makeMainFeature(x), makeHint(x)))
}
}
/**
* Creates a NetworkLinkControl from the NodeSeq.
*
* @param nodeSeq the scala xml NodeSeq, e.g. ...
* @return an NetworkLinkControl object
*/
def makeNetworkLinkControl(nodeSeq: NodeSeq): Option[NetworkLinkControl] = {
if (nodeSeq.isEmpty) None
else Some(new NetworkLinkControl(
minRefreshPeriod = getDouble(nodeSeq \ "minRefreshPeriod"),
maxSessionLength = getDouble(nodeSeq \ "maxSessionLength"),
cookie = getString(nodeSeq \ "cookie"),
message = getString(nodeSeq \ "message"),
linkName = getString(nodeSeq \ "linkName"),
linkDescription = getString(nodeSeq \ "linkDescription"),
linkSnippet = makeSnippetFromNode(nodeSeq \ "linkSnippet"),
expires = getString(nodeSeq \ "expires"),
update = makeUpdate(nodeSeq \ "Update"),
abstractView = makeAbstractView(nodeSeq)))
}
/**
* Creates a Hint attribute for the Kml root element from the NodeSeq ...
*
* @param nodeSeq the scala xml NodeSeq
* @return an Hint attribute
*/
def makeHint(nodeSeq: NodeSeq): Option[String] =
if (nodeSeq.isEmpty) None else getString(nodeSeq \ "@hint")
/**
* Creates a "main" feature (for a Kml root element object) from the NodeSeq.
* Returns the first found non empty Feature from amongst:
* Document, Folder, Placemark, NetworkLink, PhotoOverlay, ScreenOverlay, GroundOverlay, Tour
*
* @param nodeSeq the scala xml NodeSeq, e.g. ...
* @return an object that derives from Feature, one of: Document, Folder, Placemark, NetworkLink, PhotoOverlay, ScreenOverlay, GroundOverlay, Tour
*/
def makeMainFeature(nodeSeq: NodeSeq): Option[Feature] = {
if (nodeSeq.isEmpty) None
else {
for (x <- FeatureTypes.values) {
val feature = makeFeature(nodeSeq \ x.toString, x)
if (feature.isDefined) return feature
}
}
None
}
/**
* Creates an Update from the NodeSeq.
*
* @param nodeSeq the scala xml NodeSeq, e.g. ...
* @return an Update object
*/
def makeUpdate(nodeSeq: NodeSeq): Option[Update] = {
if (nodeSeq.isEmpty) None
else Some(new Update(targetHref = getString(nodeSeq \ "targetHref"), updateOption = makeUpdateOptions(nodeSeq)))
}
// TODO this does not check that there must be only one of the different types
/**
* Creates a Update option, one of: Delete, Create or Change from the NodeSeq.
*
* @param nodeSeq the scala xml NodeSeq, e.g. ...
* @return an Update option sequence containing: Delete, Create or Change options
*/
def makeUpdateOptions(nodeSeq: NodeSeq): Seq[UpdateOption] = {
if (nodeSeq.isEmpty) Seq.empty
else {
val theSeq = UpdateOptionTypes.values collect {
case x =>
x match {
case UpdateOptionTypes.Delete => makeDelete(nodeSeq \ x.toString)
case UpdateOptionTypes.Create => makeCreate(nodeSeq \ x.toString)
case UpdateOptionTypes.Change => makeChange(nodeSeq \ x.toString)
case _ => None
}
}
theSeq.flatten.toSeq
}
}
def makeDelete(nodeSeq: NodeSeq): Option[UpdateOption] =
if (nodeSeq.isEmpty) None else Some(new Delete(featureSet = makeFeatureSet(nodeSeq)))
def makeCreate(nodeSeq: NodeSeq): Option[UpdateOption] =
if (nodeSeq.isEmpty) None else Some(new Create(containerSet = makeContainerSet(nodeSeq)))
def makeChange(nodeSeq: NodeSeq): Option[UpdateOption] =
if (nodeSeq.isEmpty) None else Some(new Change(objectChangeSet = makeKmlObjectSet(nodeSeq)))
def makeContainers(nodeSeq: NodeSeq, containerType: ContainerTypes): Seq[Option[Container]] = {
(nodeSeq collect {
case x => makeContainer(x, containerType)
}) filter (_.isDefined)
}
def makeContainer(nodeSeq: NodeSeq, containerType: ContainerTypes): Option[Container] = {
if (nodeSeq.isEmpty) None
else
containerType match {
case ContainerTypes.Document => makeDocument(nodeSeq)
case ContainerTypes.Folder => makeFolder(nodeSeq)
case _ => None
}
}
def makeContainerSet(nodeSeq: NodeSeq): Seq[Container] = {
if (nodeSeq.isEmpty) Seq.empty
else
ContainerTypes.values.flatMap(x => makeContainers(nodeSeq \ x.toString, x)).toSeq.flatten
}
/**
* Creates all features of the given featureType
* @see FeatureTypes
*
* @param nodeSeq the node sequence to create the features from
* @param featureType the type of features to extract from nodeSeq
* @return a sequence of Feature Options of the chosen featureType
*/
def makeFeatures(nodeSeq: NodeSeq, featureType: FeatureTypes): Seq[Option[Feature]] = {
if (nodeSeq.isEmpty) Seq.empty
else (nodeSeq collect { case x => makeFeature(x, featureType) }) filter (_.isDefined)
}
/**
* Creates one feature of the given featureType from the given NodeSeq
*
* @param nodeSeq the node sequence to create the feature from
* @return a Feature Option
*/
def makeFeature(nodeSeq: NodeSeq, featureType: FeatureTypes): Option[Feature] = {
if (nodeSeq.isEmpty) None
else
featureType match {
case FeatureTypes.Placemark => makePlacemark(nodeSeq)
case FeatureTypes.Document => makeDocument(nodeSeq)
case FeatureTypes.Folder => makeFolder(nodeSeq)
case FeatureTypes.NetworkLink => makeNetworkLink(nodeSeq)
case FeatureTypes.PhotoOverlay => makePhotoOverlay(nodeSeq)
case FeatureTypes.ScreenOverlay => makeScreenOverlay(nodeSeq)
case FeatureTypes.GroundOverlay => makeGroundOverlay(nodeSeq)
case FeatureTypes.Tour => makeTour(nodeSeq)
case _ => None
}
}
/**
* Creates all features from the given NodeSeq
*
* @param nodeSeq the node sequence to create the features from
* @return a sequence of Features
*/
def makeFeatureSet(nodeSeq: NodeSeq): Seq[Feature] = {
if (nodeSeq.isEmpty) Seq.empty
else
FeatureTypes.values.flatMap(x => makeFeatures(nodeSeq \ x.toString, x)).toSeq.flatten
}
def makeKmlObjectSet(nodeSeq: NodeSeq): Seq[KmlObject] = {
if (nodeSeq.isEmpty) Seq.empty
else KmlObjectTypes.values.flatMap(x => makeKmlObjects(nodeSeq \ x.toString, x)).toSeq.flatten
}
def makeKmlObjects(nodeSeq: NodeSeq, kmlObjectType: KmlObjectTypes): Seq[Option[KmlObject]] = {
(nodeSeq collect {
case x => makeKmlObject(x, kmlObjectType)
}) filter (_.isDefined)
}
def makeKmlObject(nodeSeq: NodeSeq, kmlObjectType: KmlObjectTypes): Option[KmlObject] = {
if (nodeSeq.isEmpty) None
else
kmlObjectType match {
case KmlObjectTypes.ResourceMap => makeResourceMap(nodeSeq)
case KmlObjectTypes.Alias => makeAlias(nodeSeq)
case KmlObjectTypes.ViewVolume => makeViewVolume(nodeSeq)
case KmlObjectTypes.ImagePyramid => makeImagePyramid(nodeSeq)
case KmlObjectTypes.Pair => makePair(nodeSeq)
case KmlObjectTypes.LineStyle => makeLineStyle(nodeSeq)
case KmlObjectTypes.PolyStyle => makePolyStyle(nodeSeq)
case KmlObjectTypes.IconStyle => makeIconStyle(nodeSeq)
case KmlObjectTypes.LabelStyle => makeLabelStyle(nodeSeq)
case KmlObjectTypes.BalloonStyle => makeBalloonStyle(nodeSeq)
case KmlObjectTypes.ListStyle => makeListStyle(nodeSeq)
case KmlObjectTypes.ItemIcon => makeItemIcon(nodeSeq)
case KmlObjectTypes.Placemark => makePlacemark(nodeSeq)
case KmlObjectTypes.Document => makeDocument(nodeSeq)
case KmlObjectTypes.Folder => makeFolder(nodeSeq)
case KmlObjectTypes.NetworkLink => makeNetworkLink(nodeSeq)
case KmlObjectTypes.PhotoOverlay => makePhotoOverlay(nodeSeq)
case KmlObjectTypes.ScreenOverlay => makeScreenOverlay(nodeSeq)
case KmlObjectTypes.GroundOverlay => makeGroundOverlay(nodeSeq)
case KmlObjectTypes.Tour => makeTour(nodeSeq)
case KmlObjectTypes.Point => makePoint(nodeSeq)
case KmlObjectTypes.LineString => makeLineString(nodeSeq)
case KmlObjectTypes.LinearRing => makeLinearRing(nodeSeq)
case KmlObjectTypes.Polygon => makePolygon(nodeSeq)
case KmlObjectTypes.MultiGeometry => makeMultiGeometry(nodeSeq)
case KmlObjectTypes.Model => makeModel(nodeSeq)
case KmlObjectTypes.Camera => makeCamera(nodeSeq)
case KmlObjectTypes.LookAt => makeLookAt(nodeSeq)
case KmlObjectTypes.Data => makeData(nodeSeq)
case KmlObjectTypes.SchemaData => makeSchemaData(nodeSeq)
case KmlObjectTypes.Style => makeStyle(nodeSeq)
case KmlObjectTypes.StyleMap => makeStyleMap(nodeSeq)
case KmlObjectTypes.TimeStamp => makeTimeStamp(nodeSeq)
case KmlObjectTypes.TimeSpan => makeTimeSpan(nodeSeq)
case KmlObjectTypes.Region => makeRegion(nodeSeq)
case KmlObjectTypes.LatLonAltBox => makeLatLonAltBox(nodeSeq)
case KmlObjectTypes.LatLonBox => makeLatLonBox(nodeSeq)
case KmlObjectTypes.Lod => makeCamera(nodeSeq)
case KmlObjectTypes.Icon => makeIcon(nodeSeq)
case KmlObjectTypes.Link => makeLinkFromNode(nodeSeq)
case KmlObjectTypes.Location => makeLocation(nodeSeq)
case KmlObjectTypes.Orientation => makeOrientation(nodeSeq)
case KmlObjectTypes.Scale => makeScale(nodeSeq)
case _ => None
}
}
def makeOrientation(nodeSeq: NodeSeq): Option[Orientation] = {
if (nodeSeq.isEmpty) None
else Some(new Orientation(
id = getString(nodeSeq \ "@id"),
targetId = getString(nodeSeq \ "@targetId"),
heading = getDouble(nodeSeq \ "heading"),
tilt = getDouble(nodeSeq \ "tilt"),
roll = getDouble(nodeSeq \ "roll")))
}
def makeLinkFromNode(nodeSeq: NodeSeq): Option[com.scalakml.kml.Link] = {
if (nodeSeq.isEmpty) None
else Some(new com.scalakml.kml.Link(id = getString(nodeSeq \ "@id"),
targetId = getString(nodeSeq \ "@targetId"),
refreshMode = getString(nodeSeq \ "refreshMode") map(RefreshMode.fromString(_)),
refreshInterval = getDouble(nodeSeq \ "refreshInterval"),
viewRefreshMode = getString(nodeSeq \ "viewRefreshMode") map(ViewRefreshMode.fromString(_)),
viewRefreshTime = getDouble(nodeSeq \ "viewRefreshTime"),
viewBoundScale = getDouble(nodeSeq \ "viewBoundScale"),
viewFormat = getString(nodeSeq \ "viewFormat"),
httpQuery = getString(nodeSeq \ "httpQuery"),
href = getString(nodeSeq \ "href")))
}
def makeLink(nodeSeq: NodeSeq): Option[com.scalakml.kml.Link] = {
if (nodeSeq.isEmpty) None
else {
for (x <- List("Link", "Url")) { // <--- possible labels, "Url" is not part of the formal reference
val link = makeLinkFromNode(nodeSeq \ x)
if (link.isDefined) return link
}
}
None
}
def makeIcon(nodeSeq: NodeSeq): Option[Icon] = {
if (nodeSeq.isEmpty) None
else Some(new Icon(href = getString(nodeSeq \ "href"),
id = getString(nodeSeq \ "@id"),
targetId = getString(nodeSeq \ "@targetId"),
refreshMode = getString(nodeSeq \ "refreshMode") map(RefreshMode.fromString(_)),
refreshInterval = getDouble(nodeSeq \ "refreshInterval"),
viewRefreshMode = getString(nodeSeq \ "viewRefreshMode") map(ViewRefreshMode.fromString(_)),
viewRefreshTime = getDouble(nodeSeq \ "viewRefreshTime"),
viewBoundScale = getDouble(nodeSeq \ "viewBoundScale"),
viewFormat = getString(nodeSeq \ "viewFormat"),
httpQuery = getString(nodeSeq \ "httpQuery")))
}
def makeNetworkLink(nodeSeq: NodeSeq): Option[NetworkLink] = {
if (nodeSeq.isEmpty) None
else Some(new NetworkLink(id = getString(nodeSeq \ "@id"),
targetId = getString(nodeSeq \ "@targetId"),
refreshVisibility = getBoolean(nodeSeq \ "refreshVisibility"),
flyToView = getBoolean(nodeSeq \ "flyToView"),
link = makeLink(nodeSeq),
featurePart = makeFeaturePart(nodeSeq)))
}
def getString(nodeSeq: NodeSeq): Option[String] = {
if (nodeSeq.isEmpty) None
else
nodeSeq.text.trim match {
case text if text.isEmpty => None
case text => Some(text).asInstanceOf[Option[String]]
}
}
def getDouble(nodeSeq: NodeSeq): Option[Double] = {
if (nodeSeq.isEmpty) None
else
nodeSeq.text.trim match {
case text if text.isEmpty => None
case text => try {
Some(text.toDouble).asInstanceOf[Option[Double]]
} catch {
case _: Throwable => None
}
}
}
def getInt(nodeSeq: NodeSeq): Option[Int] = {
if (nodeSeq.isEmpty) None
else
nodeSeq.text.trim match {
case text if text.isEmpty => None
case text => try {
Some(text.toInt).asInstanceOf[Option[Int]]
} catch {
case _: Throwable => None
}
}
}
def getBoolean(nodeSeq: NodeSeq): Option[Boolean] = {
if (nodeSeq.isEmpty) None
else
nodeSeq.text.trim match {
case text if text.isEmpty => None
case text => text.toLowerCase match {
case "1" | "true" => Some(true).asInstanceOf[Option[Boolean]]
case "0" | "false" => Some(false).asInstanceOf[Option[Boolean]]
case _ => None
}
}
}
def makeAtomLink(nodeSeq: NodeSeq): Option[com.scalakml.atom.Link] = {
if (nodeSeq.isEmpty) None
else Some(new com.scalakml.atom.Link(
href = getString(nodeSeq \ "@href"),
rel = getString(nodeSeq \ "@rel"),
typeValue = getString(nodeSeq \ "@type"),
hrefLang = getString(nodeSeq \ "@hrefLang"),
title = getString(nodeSeq \ "@title"),
length = getString(nodeSeq \ "@length")))
}
def makeAtomAuthor(nodeSeq: NodeSeq): Option[com.scalakml.atom.Author] = {
if (nodeSeq.isEmpty) None
else Some(new com.scalakml.atom.Author(
name = getString(nodeSeq \ "name"),
uri = getString(nodeSeq \ "uri"),
email = getString(nodeSeq \ "email")))
}
def makeFeaturePart(nodeSeq: NodeSeq): FeaturePart =
if (nodeSeq.isEmpty) new FeaturePart()
else new FeaturePart(
name = getString(nodeSeq \ "name"),
visibility = getBoolean(nodeSeq \ "visibility"),
open = getBoolean(nodeSeq \ "open"),
atomAuthor = makeAtomAuthor(nodeSeq \ "author"),
atomLink = makeAtomLink(nodeSeq \ "link"),
address = getString(nodeSeq \ "address"),
addressDetails = makeAddressDetails(nodeSeq \ "AddressDetails"), // <---- from com.scalaxal.io.XalFromXml
phoneNumber = getString(nodeSeq \ "phoneNumber"),
extendedData = makeExtendedData(nodeSeq \ "ExtendedData"),
description = getString(nodeSeq \ "description"),
snippet = makeSnippet(nodeSeq),
abstractView = makeAbstractView(nodeSeq),
timePrimitive = makeTimePrimitive(nodeSeq),
styleUrl = getString(nodeSeq \ "styleUrl"),
styleSelector = makeStyleSet(nodeSeq),
region = makeRegion(nodeSeq \ "Region"))
def makeStyle(nodeSeq: NodeSeq): Option[StyleSelector] = {
if (nodeSeq.isEmpty) None
else Some(new Style(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
iconStyle = makeIconStyle(nodeSeq \ "IconStyle"),
labelStyle = makeLabelStyle(nodeSeq \ "LabelStyle"),
lineStyle = makeLineStyle(nodeSeq \ "LineStyle"),
polyStyle = makePolyStyle(nodeSeq \ "PolyStyle"),
balloonStyle = makeBalloonStyle(nodeSeq \ "BalloonStyle"),
listStyle = makeListStyle(nodeSeq \ "ListStyle")))
}
def makeIconStyle(nodeSeq: NodeSeq): Option[IconStyle] = {
if (nodeSeq.isEmpty) None
else Some(new IconStyle(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
scale = getDouble(nodeSeq \ "scale"),
heading = getDouble(nodeSeq \ "heading"),
icon = makeIcon(nodeSeq \ "Icon"),
hotSpot = makeVec2(nodeSeq \ "hotSpot"),
color = makeColor(nodeSeq \ "color"),
colorMode = getString(nodeSeq \ "colorMode") map(ColorMode.fromString(_))))
}
def makeLineStyle(nodeSeq: NodeSeq): Option[LineStyle] = {
if (nodeSeq.isEmpty) None
else Some(new LineStyle(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
width = getDouble(nodeSeq \ "width"),
color = makeColor(nodeSeq \ "color"),
colorMode = getString(nodeSeq \ "colorMode") map(ColorMode.fromString(_))))
}
def makeLabelStyle(nodeSeq: NodeSeq): Option[LabelStyle] = {
if (nodeSeq.isEmpty) None
else Some(new LabelStyle(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
scale = getDouble(nodeSeq \ "scale"),
color = makeColor(nodeSeq \ "color"),
colorMode = getString(nodeSeq \ "colorMode") map(ColorMode.fromString(_))))
}
def makePolyStyle(nodeSeq: NodeSeq): Option[PolyStyle] = {
if (nodeSeq.isEmpty) None
else Some(new PolyStyle(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
fill = getBoolean(nodeSeq \ "fill"),
outline = getBoolean(nodeSeq \ "outline"),
color = makeColor(nodeSeq \ "color"),
colorMode = getString(nodeSeq \ "colorMode") map(ColorMode.fromString(_))))
}
def makeBalloonStyle(nodeSeq: NodeSeq): Option[BalloonStyle] = {
if (nodeSeq.isEmpty) None
else Some(new BalloonStyle(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
bgColor = makeColor(nodeSeq \ "bgColor"),
textColor = makeColor(nodeSeq \ "textColor"),
text = getString(nodeSeq \ "text"),
displayMode = getString(nodeSeq \ "displayMode") map(DisplayMode.fromString(_))))
}
def makeListStyle(nodeSeq: NodeSeq): Option[ListStyle] = {
if (nodeSeq.isEmpty) None
else Some(new ListStyle(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
listItemType = getString(nodeSeq \ "listItemType") map(ListItemType.fromString(_)),
bgColor = makeColor(nodeSeq \ "bgColor"),
itemIcon = makeItemIconSet(nodeSeq \ "ItemIcon"),
maxSnippetLines = getInt(nodeSeq \ "maxSnippetLines")))
}
def makeItemIconSet(nodeSeq: NodeSeq): Seq[ItemIcon] = {
if (nodeSeq.isEmpty) Seq.empty
else nodeSeq collect { case x => makeItemIcon(x) } flatten
}
def makeItemIcon(nodeSeq: NodeSeq): Option[ItemIcon] = {
if (nodeSeq.isEmpty) None
else {
val test =Some(new ItemIcon(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
state = makeItemIconStates(nodeSeq \ "state"),
href = getString(nodeSeq \ "href")))
test
}
}
def makeItemIconStates(nodeSeq: NodeSeq): Seq[ItemIconState] = {
if (nodeSeq.isEmpty) Seq.empty
else
getString(nodeSeq) match {
case Some(modeOption) =>
modeOption match {
case x if x.isEmpty => Seq.empty
case stateString => (stateString split "\\s+").map(x => {ItemIconState.fromString(x.trim)}).toSeq
}
case _ => Seq.empty
}
}
def makeStyleMap(nodeSeq: NodeSeq): Option[StyleSelector] = {
if (nodeSeq.isEmpty) None
else Some(new StyleMap(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
pair = makePairSet(nodeSeq \ "Pair")))
}
// TODO looks like a circular reference
def makePair(nodeSeq: NodeSeq): Option[Pair] = {
if (nodeSeq.isEmpty) None
else Some(new Pair(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
key = getString(nodeSeq \ "key") map(StyleState.fromString(_)),
styleUrl = getString(nodeSeq \ "styleUrl"),
styleSelector = makeStyleSelector(nodeSeq))) // <----
}
def makePairSet(nodeSeq: NodeSeq): Seq[Pair] = {
if (nodeSeq.isEmpty) Seq.empty
else nodeSeq collect { case x => makePair(x) } flatten
}
/**
* Creates a Style or StyleMap from the given NodeSeq
*
* @param nodeSeq the node sequence to create the Style or StyleMap from
* @return a StyleSelector, that is a Style or StyleMap Option
*/
def makeStyleSelector(nodeSeq: NodeSeq): Option[StyleSelector] = {
if (nodeSeq.isEmpty) None
else {
val style = nodeSeq \ "Style"
style match {
case x if x.nonEmpty => makeStyle(style)
case _ =>
val styleMap = nodeSeq \ "StyleMap"
styleMap match {
case x if x.nonEmpty => makeStyleMap(styleMap)
case _ => None
}
}
}
}
def makeStyleSet(nodeSeq: NodeSeq): Seq[StyleSelector] = {
if (nodeSeq.isEmpty) Seq.empty
else {
val styleList = (nodeSeq \ "Style") match {
case s if !s.isEmpty => s collect { case x => makeStyle(x) } flatten
case _ => Seq.empty
}
val styleMapList = (nodeSeq \ "StyleMap") match {
case s if !s.isEmpty => s collect {case x => makeStyleMap(x) } flatten
case _ => Seq.empty
}
styleList ++ styleMapList
}
}
def makeLod(nodeSeq: NodeSeq): Option[Lod] = {
if (nodeSeq.isEmpty) None
else Some(new Lod(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
minLodPixels = getDouble(nodeSeq \ "minLodPixels"),
maxLodPixels = getDouble(nodeSeq \ "maxLodPixels"),
minFadeExtent = getDouble(nodeSeq \ "minFadeExtent"),
maxFadeExtent = getDouble(nodeSeq \ "maxFadeExtent")))
}
def makeRegion(nodeSeq: NodeSeq): Option[Region] = {
if (nodeSeq.isEmpty) None
else Some(new Region(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
latLonAltBox = makeLatLonAltBox(nodeSeq \ "LatLonAltBox"),
lod = makeLod(nodeSeq \ "Lod")))
}
def makeLatLonAltBox(nodeSeq: NodeSeq): Option[LatLonAltBox] = {
if (nodeSeq.isEmpty) None
else Some(new LatLonAltBox(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
minAltitude = getDouble(nodeSeq \ "minAltitude"),
maxAltitude = getDouble(nodeSeq \ "maxAltitude"),
altitudeMode = getString(nodeSeq \ "altitudeMode") map(AltitudeMode.fromString(_)),
north = getDouble(nodeSeq \ "north"),
south = getDouble(nodeSeq \ "south"),
east = getDouble(nodeSeq \ "east"),
west = getDouble(nodeSeq \ "west")))
}
def makeLatLonBox(nodeSeq: NodeSeq): Option[LatLonBox] = {
if (nodeSeq.isEmpty) None
else Some(new LatLonBox(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
rotation = getDouble(nodeSeq \ "rotation"),
north = getDouble(nodeSeq \ "north"),
south = getDouble(nodeSeq \ "south"),
east = getDouble(nodeSeq \ "east"),
west = getDouble(nodeSeq \ "west")))
}
/**
* Creates a snippet from the given snippet NodeSeq
*
* @param nodeSeq the snippet node sequence
* @return a Snippet Option
*/
def makeSnippetFromNode(nodeSeq: NodeSeq): Option[Snippet] = {
if (nodeSeq.isEmpty) None
else Some(new Snippet(
value = getString(nodeSeq).getOrElse(""),
maxLines = getInt(nodeSeq \ "@maxLines").getOrElse(0)))
}
/**
* Creates a snippet from the given parent NodeSeq
*
* @param nodeSeq the parent nodeSeq of snippet or Snippet
* @return a Snippet Option
*/
def makeSnippet(nodeSeq: NodeSeq): Option[Snippet] = {
// pick the first node with something in it
for (x <- List("snippet", "Snippet")) {
// reference 1 is snippet, but reference 2 is Snippet
val node = nodeSeq \ x
if (!node.isEmpty) return makeSnippetFromNode(node)
}
None
}
// TODO how to read other
def makeExtendedData(nodeSeq: NodeSeq): Option[ExtendedData] = {
if (nodeSeq.isEmpty) None
else Some(new ExtendedData(
data = makeDataSet(nodeSeq \ "Data"),
schemaData = makeSchemaDataSet(nodeSeq \ "SchemaData")))
// other: Seq[Any] how to get this from xml
}
def makeData(nodeSeq: NodeSeq): Option[Data] = {
if (nodeSeq.isEmpty) None
else Some(new Data(name = getString(nodeSeq \ "@name"),
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
displayName = getString(nodeSeq \ "displayName"),
value = getString(nodeSeq \ "value")))
}
def makeDataSet(nodeSeq: NodeSeq): Seq[Data] = {
if (nodeSeq.isEmpty) Seq.empty
else nodeSeq collect { case x => makeData(x) } flatten
}
def makeSimpleData(nodeSeq: NodeSeq): Option[SimpleData] = {
if (nodeSeq.isEmpty) None
else Some(new SimpleData(name = getString(nodeSeq \ "@name"),
value = getString(nodeSeq)))
}
def makeSimpleDataSet(nodeSeq: NodeSeq): Seq[SimpleData] = {
if (nodeSeq.isEmpty) Seq.empty
else nodeSeq collect { case x => makeSimpleData(x) } flatten
}
def makeSchemaData(nodeSeq: NodeSeq): Option[SchemaData] = {
if (nodeSeq.isEmpty) None
else Some(new SchemaData(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
schemaUrl = getString(nodeSeq \ "@schemaUrl"),
simpleData = makeSimpleDataSet(nodeSeq \ "SimpleData")))
}
def makeSchemaDataSet(nodeSeq: NodeSeq): Seq[SchemaData] = {
if (nodeSeq.isEmpty) Seq.empty
else nodeSeq collect { case x => makeSchemaData(x) } flatten
}
// either a TimeSpan or a TimeStamp or None
def makeTimePrimitive(nodeSeq: NodeSeq): Option[TimePrimitive] = {
if (nodeSeq.isEmpty) None
else
(nodeSeq \ "TimeSpan") match {
case x if x.nonEmpty => makeTimeSpan(x)
case _ => {
(nodeSeq \ "TimeStamp") match {
case x if x.nonEmpty => makeTimeStamp(x)
case _ => None
}
}
}
}
def makeTimeStamp(nodeSeq: NodeSeq): Option[TimePrimitive] = {
if (nodeSeq.isEmpty) None
else Some(new TimeStamp(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
when = getString(nodeSeq \ "when")))
}
def makeTimeSpan(nodeSeq: NodeSeq): Option[TimePrimitive] = {
if (nodeSeq.isEmpty) None
else Some(new TimeSpan(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
begin = getString(nodeSeq \ "begin"),
end = getString(nodeSeq \ "end")))
}
// either a Camera or a LookAt or None
def makeAbstractView(nodeSeq: NodeSeq): Option[AbstractView] = {
if (nodeSeq.isEmpty) None
else
(nodeSeq \ "Camera") match {
case x if x.nonEmpty => makeCamera(x)
case _ =>
(nodeSeq \ "LookAt") match {
case x if x.nonEmpty => makeLookAt(x)
case _ => None
}
}
}
def makeCamera(nodeSeq: NodeSeq): Option[Camera] = {
if (nodeSeq.isEmpty) None
else Some(new Camera(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
roll = getDouble(nodeSeq \ "roll"),
longitude = getDouble(nodeSeq \ "longitude"),
latitude = getDouble(nodeSeq \ "latitude"),
altitude = getDouble(nodeSeq \ "altitude"),
heading = getDouble(nodeSeq \ "heading"),
tilt = getDouble(nodeSeq \ "tilt"),
altitudeMode = getString(nodeSeq \ "altitudeMode") map(AltitudeMode.fromString(_))))
}
def makeLookAt(nodeSeq: NodeSeq): Option[LookAt] = {
if (nodeSeq.isEmpty) None
else Some(new LookAt(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
range = getDouble(nodeSeq \ "range"),
longitude = getDouble(nodeSeq \ "longitude"),
latitude = getDouble(nodeSeq \ "latitude"),
altitude = getDouble(nodeSeq \ "altitude"),
heading = getDouble(nodeSeq \ "heading"),
tilt = getDouble(nodeSeq \ "tilt"),
altitudeMode = getString(nodeSeq \ "altitudeMode") map(AltitudeMode.fromString(_))))
}
def makePlacemark(nodeSeq: NodeSeq): Option[Placemark] = {
if (nodeSeq.isEmpty) None
else Some(new Placemark(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
geometry = makeGeometry(nodeSeq),
featurePart = makeFeaturePart(nodeSeq)))
}
def makeDocument(nodeSeq: NodeSeq): Option[com.scalakml.kml.Document] = {
if (nodeSeq.isEmpty) None
else Some(new com.scalakml.kml.Document(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
schemas = makeSchemaSet(nodeSeq \ "Schema"),
features = makeFeatureSet(nodeSeq),
featurePart = makeFeaturePart(nodeSeq)))
}
def makeSchemaSet(nodeSeq: NodeSeq): Seq[Schema] = {
if (nodeSeq.isEmpty) Seq.empty
else nodeSeq collect { case x => makeSchema(x) } flatten
}
def makeSchema(nodeSeq: NodeSeq): Option[Schema] = {
if (nodeSeq.isEmpty) None
else Some(new Schema(
simpleField = makeSimpleFieldSet(nodeSeq \ "SimpleField"),
name = getString(nodeSeq \ "@name"),
id = getString(nodeSeq \ "@id")))
}
def makeSimpleField(nodeSeq: NodeSeq): Option[SimpleField] = {
if (nodeSeq.isEmpty) None
else Some(new SimpleField(
name = getString(nodeSeq \ "@name"),
typeValue = getString(nodeSeq \ "@type"),
displayName = getString(nodeSeq \ "displayName")))
}
def makeSimpleFieldSet(nodeSeq: NodeSeq): Seq[SimpleField] = {
if (nodeSeq.isEmpty) Seq.empty
else nodeSeq collect { case x => makeSimpleField(x) } flatten
}
def makeFolder(nodeSeq: NodeSeq): Option[Folder] = {
if (nodeSeq.isEmpty) None
else Some(new Folder(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
features = makeFeatureSet(nodeSeq),
featurePart = makeFeaturePart(nodeSeq)))
}
def makePoint(nodeSeq: NodeSeq): Option[Point] = {
if (nodeSeq.isEmpty) None
else Some(new Point(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
coordinates = makeCoordinate(nodeSeq \ "coordinates"),
extrude = getBoolean(nodeSeq \ "extrude"),
altitudeMode = getString(nodeSeq \ "altitudeMode") map(AltitudeMode.fromString(_))))
}
def makeCoordinate(nodeSeq: NodeSeq): Option[Coordinate] = {
if (nodeSeq.isEmpty) None
else
Coordinate.fromCsString(nodeSeq.text.trim)
}
def makeCoordinates(nodeSeq: NodeSeq): Option[Seq[Coordinate]] = {
if (nodeSeq.isEmpty) None
else
Some((nodeSeq.text.trim split "\\s+").flatMap(x => Coordinate.fromCsString(x)) toSeq)
}
def makeLocation(nodeSeq: NodeSeq): Option[Location] = {
if (nodeSeq.isEmpty) None
else Some(new Location(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
longitude = getDouble(nodeSeq \ "longitude"),
latitude = getDouble(nodeSeq \ "latitude"),
altitude = getDouble(nodeSeq \ "altitude")))
}
def makeLineString(nodeSeq: NodeSeq): Option[LineString] = {
if (nodeSeq.isEmpty) None
else Some(new LineString(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
extrude = getBoolean(nodeSeq \ "extrude"),
tessellate = getBoolean(nodeSeq \ "tessellate"),
altitudeMode = getString(nodeSeq \ "altitudeMode") map(AltitudeMode.fromString(_)),
coordinates = makeCoordinates(nodeSeq \ "coordinates")))
}
def makeLinearRing(nodeSeq: NodeSeq): Option[LinearRing] = {
if (nodeSeq.isEmpty) None
else Some(new LinearRing(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
extrude = getBoolean(nodeSeq \ "extrude"),
tessellate = getBoolean(nodeSeq \ "tessellate"),
altitudeMode = getString(nodeSeq \ "altitudeMode") map(AltitudeMode.fromString(_)),
coordinates = makeCoordinates(nodeSeq \ "coordinates")))
}
def makeBoundary(nodeSeq: NodeSeq): Option[Boundary] = {
if (nodeSeq.isEmpty) None else Some(new Boundary(linearRing = makeLinearRing(nodeSeq \ "LinearRing")))
}
def makeBoundaries(nodeSeq: NodeSeq): Seq[Boundary] = {
if (nodeSeq.isEmpty) Seq.empty
else nodeSeq \ "LinearRing" collect { case x => Some(new Boundary(linearRing = makeLinearRing(x))) } flatten
}
def makePolygon(nodeSeq: NodeSeq): Option[Polygon] = {
if (nodeSeq.isEmpty) None
else Some(new Polygon(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
extrude = getBoolean(nodeSeq \ "extrude"),
tessellate = getBoolean(nodeSeq \ "tessellate"),
altitudeMode = getString(nodeSeq \ "altitudeMode") map(AltitudeMode.fromString(_)),
outerBoundaryIs = makeBoundary(nodeSeq \ "outerBoundaryIs"),
innerBoundaryIs = makeBoundaries(nodeSeq \ "innerBoundaryIs")))
}
def makeMultiGeometry(nodeSeq: NodeSeq): Option[MultiGeometry] = {
if (nodeSeq.isEmpty) None
else Some(new MultiGeometry(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
geometries = makeGeometrySet(nodeSeq)))
}
def makeModel(nodeSeq: NodeSeq): Option[Model] = {
if (nodeSeq.isEmpty) None
else Some(new Model(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
altitudeMode = getString(nodeSeq \ "altitudeMode") map(AltitudeMode.fromString(_)),
location = makeLocation(nodeSeq \ "Location"),
orientation = makeOrientation(nodeSeq \ "Orientation"),
scale = makeScale(nodeSeq \ "Scale"),
link = makeLink(nodeSeq),
resourceMap = makeResourceMap(nodeSeq \ "ResourceMap")))
}
def makeResourceMap(nodeSeq: NodeSeq): Option[ResourceMap] = {
if (nodeSeq.isEmpty) None
else Some(new ResourceMap(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
alias = makeAliasSet(nodeSeq \ "Alias")))
}
def makeAliasSet(nodeSeq: NodeSeq): Seq[Alias] = {
if (nodeSeq.isEmpty) Seq.empty
else nodeSeq collect { case x => makeAlias(x) } flatten
}
def makeAlias(nodeSeq: NodeSeq): Option[Alias] = {
if (nodeSeq.isEmpty) None
else Some(new Alias(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
targetHref = getString(nodeSeq \ "targetHref"),
sourceHref = getString(nodeSeq \ "sourceHref")))
}
def makeScale(nodeSeq: NodeSeq): Option[Scale] = {
if (nodeSeq.isEmpty) None
else Some(new Scale(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
x = getDouble(nodeSeq \ "x"),
y = getDouble(nodeSeq \ "y"),
z = getDouble(nodeSeq \ "z")))
}
def makeGeometry(nodeSeq: NodeSeq, geomType: GeometryTypes): Option[Geometry] = {
if (nodeSeq.isEmpty) None
else
geomType match {
case GeometryTypes.Point => makePoint(nodeSeq)
case GeometryTypes.LineString => makeLineString(nodeSeq)
case GeometryTypes.LinearRing => makeLinearRing(nodeSeq)
case GeometryTypes.Polygon => makePolygon(nodeSeq)
case GeometryTypes.MultiGeometry => makeMultiGeometry(nodeSeq)
case GeometryTypes.Model => makeModel(nodeSeq)
// case GeometryTypes.Track => makeTrack(nodeSeq)
// case GeometryTypes.MultiTrack => makeMultiTrack(nodeSeq)
case _ => None
}
}
def makeGeometry(nodeSeq: NodeSeq): Option[Geometry] = {
if (nodeSeq.isEmpty) None
else {
// just pick the first match
for (x <- GeometryTypes.values) {
val geom = makeGeometry(nodeSeq \ x.toString, x)
if (geom.isDefined) return geom
}
}
None
}
def makeGeometrySet(nodeSeq: NodeSeq): Seq[Geometry] = {
if (nodeSeq.isEmpty) Seq.empty
else
GeometryTypes.values.flatMap(x => makeGeometries(nodeSeq \ x.toString, x)).toSeq.flatten
}
def makeGeometries(nodeSeq: NodeSeq, geometryTypes: GeometryTypes): Seq[Option[Geometry]] = {
if (nodeSeq.isEmpty) Seq.empty
else
(nodeSeq collect {
case x => makeGeometry(x, geometryTypes)
}) filter (_.isDefined)
}
def makeViewVolume(nodeSeq: NodeSeq): Option[ViewVolume] = {
if (nodeSeq.isEmpty) None
else
Some(new ViewVolume(id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
leftFov = getDouble(nodeSeq \ "leftFov"),
rightFov = getDouble(nodeSeq \ "rightFov"),
bottomFov = getDouble(nodeSeq \ "bottomFov"),
topFov = getDouble(nodeSeq \ "topFov"),
near = getDouble(nodeSeq \ "near")))
}
def makeImagePyramid(nodeSeq: NodeSeq): Option[ImagePyramid] = {
if (nodeSeq.isEmpty) None
else
Some(new ImagePyramid(id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
tileSize = getInt(nodeSeq \ "tileSize"),
maxWidth = getInt(nodeSeq \ "maxWidth"),
maxHeight = getInt(nodeSeq \ "maxHeight"),
gridOrigin = getString(nodeSeq \ "gridOrigin") map(GridOrigin.fromString(_))))
}
def makeColor(nodeSeq: NodeSeq): Option[HexColor] = {
if (nodeSeq.isEmpty) None else getString(nodeSeq) map(x => new HexColor(hexString = x))
}
def makePhotoOverlay(nodeSeq: NodeSeq): Option[PhotoOverlay] = {
if (nodeSeq.isEmpty) None
else
Some(new PhotoOverlay(id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
rotation = getDouble(nodeSeq \ "rotation"),
viewVolume = makeViewVolume(nodeSeq \ "ViewVolume"),
imagePyramid = makeImagePyramid(nodeSeq \ "ImagePyramid"),
point = makePoint(nodeSeq \ "Point"),
shape = getString(nodeSeq \ "shape") map(Shape.fromString(_)),
color = makeColor(nodeSeq \ "color"),
drawOrder = getInt(nodeSeq \ "drawOrder"),
icon = makeIcon(nodeSeq \ "Icon"),
featurePart = makeFeaturePart(nodeSeq)))
}
def makeGroundOverlay(nodeSeq: NodeSeq): Option[GroundOverlay] = {
if (nodeSeq.isEmpty) None
else
Some(new GroundOverlay(id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
altitude = getDouble(nodeSeq \ "altitude"),
altitudeMode = getString(nodeSeq \ "altitudeMode") map(AltitudeMode.fromString(_)),
latLonBox = makeLatLonBox(nodeSeq \ "LatLonBox"),
latLonQuad = makeLatLonQuad(nodeSeq \ "LatLonQuad"),
color = makeColor(nodeSeq \ "color"),
drawOrder = getInt(nodeSeq \ "drawOrder"),
icon = makeIcon(nodeSeq \ "Icon"),
featurePart = makeFeaturePart(nodeSeq)))
}
def makeVec2(nodeSeq: NodeSeq): Option[Vec2] = {
if (nodeSeq.isEmpty) None
else Some(new Vec2(
x = getDouble(nodeSeq \ "@x").getOrElse(0.0),
y = getDouble(nodeSeq \ "@y").getOrElse(0.0),
xunits = getString(nodeSeq \ "@xunits") map(Units.fromString(_)) getOrElse(Fraction),
yunits = getString(nodeSeq \ "@yunits") map(Units.fromString(_)) getOrElse(Fraction)))
}
def makeScreenOverlay(nodeSeq: NodeSeq): Option[ScreenOverlay] = {
if (nodeSeq.isEmpty) None
else Some(new ScreenOverlay(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
overlayXY = makeVec2(nodeSeq \ "overlayXY"),
screenXY = makeVec2(nodeSeq \ "screenXY"),
rotationXY = makeVec2(nodeSeq \ "rotationXY"),
size = makeVec2(nodeSeq \ "size"),
rotation = getDouble(nodeSeq \ "rotation"),
color = makeColor(nodeSeq \ "color"),
drawOrder = getInt(nodeSeq \ "drawOrder"),
icon = makeIcon(nodeSeq \ "Icon"),
featurePart = makeFeaturePart(nodeSeq)))
}
//-----------------------------------------------------------------------------------------------
//----------------------------------gx-----------------------------------------------------------
//-----------------------------------------------------------------------------------------------
def makePlaylist(nodeSeq: NodeSeq): Option[Playlist] = {
if (nodeSeq.isEmpty) None
else Some(new Playlist(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
tourPrimitiveGroup = Some(makeTourPrimitiveSet(nodeSeq))))
}
def makeTour(nodeSeq: NodeSeq): Option[Tour] = {
if (nodeSeq.isEmpty) None
else Some(new Tour(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
playlist = makePlaylist(nodeSeq \ "Playlist"),
featurePart = makeFeaturePart(nodeSeq)))
}
def makeTourPrimitiveSet(nodeSeq: NodeSeq): Seq[TourPrimitive] = {
if (nodeSeq.isEmpty) Seq.empty
else
TourPrimitiveTypes.values.flatMap(x => makeTourPrimitives(nodeSeq \ x.toString, x)).toSeq.flatten
}
def makeTourPrimitives(nodeSeq: NodeSeq, tourPrimitiveType: TourPrimitiveTypes): Seq[Option[TourPrimitive]] = {
(nodeSeq collect {
case x => makeTourPrimitive(x, tourPrimitiveType)
}) filter (_.isDefined)
}
def makeTourPrimitive(nodeSeq: NodeSeq, tourPrimitiveType: TourPrimitiveTypes): Option[TourPrimitive] = {
if (nodeSeq.isEmpty) None
else
tourPrimitiveType match {
case TourPrimitiveTypes.AnimatedUpdate => makeAnimatedUpdate(nodeSeq)
case TourPrimitiveTypes.FlyTo => makeFlyTo(nodeSeq)
case TourPrimitiveTypes.SoundCue => makeSoundCue(nodeSeq)
case TourPrimitiveTypes.Wait => makeWait(nodeSeq)
case TourPrimitiveTypes.TourControl => makeTourControl(nodeSeq)
case _ => None
}
}
def makeAnimatedUpdate(nodeSeq: NodeSeq): Option[AnimatedUpdate] = {
if (nodeSeq.isEmpty) None
else Some(new AnimatedUpdate(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
duration = getDouble(nodeSeq \ "duration"),
update = makeUpdate(nodeSeq \ "Update")))
}
def makeFlyTo(nodeSeq: NodeSeq): Option[FlyTo] = {
if (nodeSeq.isEmpty) None
else Some(new FlyTo(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
duration = getDouble(nodeSeq \ "duration"),
flyToMode = getString(nodeSeq \ "flyToMode") map(FlyToMode.fromString(_)),
abstractView = makeAbstractView(nodeSeq)))
}
def makeSoundCue(nodeSeq: NodeSeq): Option[SoundCue] = {
if (nodeSeq.isEmpty) None
else Some(new SoundCue(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
href = getString(nodeSeq \ "href")))
}
def makeWait(nodeSeq: NodeSeq): Option[Wait] = {
if (nodeSeq.isEmpty) None
else Some(new Wait(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
duration = getDouble(nodeSeq \ "duration")))
}
def makeTourControl(nodeSeq: NodeSeq): Option[TourControl] = {
if (nodeSeq.isEmpty) None
else Some(new TourControl(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
playMode = getString(nodeSeq \ "playMode") map(PlayMode.fromString(_))))
}
def makeLatLonQuad(nodeSeq: NodeSeq): Option[LatLonQuad] = {
if (nodeSeq.isEmpty) None
else Some(new LatLonQuad(
id = getString(nodeSeq \ "@id"), targetId = getString(nodeSeq \ "@targetId"),
coordinates = makeCoordinates(nodeSeq)))
}
}