private PlacemarkType createMark(int kiloMeter, double longitude, double latitude) {
   ObjectFactory objectFactory = new ObjectFactory();
   PlacemarkType placeMark = objectFactory.createPlacemarkType();
   placeMark.setName(kiloMeter + ". Km");
   placeMark.setVisibility(FALSE);
   PointType point = objectFactory.createPointType();
   point
       .getCoordinates()
       .add(formatPositionAsString(longitude) + "," + formatPositionAsString(latitude) + ",0");
   placeMark.setAbstractGeometryGroup(objectFactory.createPoint(point));
   return placeMark;
 }
 private PlacemarkType createRoute(KmlRoute route) {
   ObjectFactory objectFactory = new ObjectFactory();
   PlacemarkType placemarkType = objectFactory.createPlacemarkType();
   placemarkType.setName(ROUTE);
   placemarkType.setDescription(asDescription(route.getDescription()));
   placemarkType.setStyleUrl("#" + ROUTE_LINE_STYLE);
   MultiGeometryType multiGeometryType = objectFactory.createMultiGeometryType();
   placemarkType.setAbstractGeometryGroup(objectFactory.createMultiGeometry(multiGeometryType));
   LineStringType lineStringType = objectFactory.createLineStringType();
   multiGeometryType
       .getAbstractGeometryGroup()
       .add(objectFactory.createLineString(lineStringType));
   List<String> coordinates = lineStringType.getCoordinates();
   for (KmlPosition position : route.getPositions()) {
     coordinates.add(createCoordinates(position, false));
   }
   return placemarkType;
 }
 private PlacemarkType createTrack(KmlRoute route, int startIndex, int endIndex) {
   ObjectFactory objectFactory = new ObjectFactory();
   PlacemarkType placemarkType = objectFactory.createPlacemarkType();
   placemarkType.setName(TRACK);
   placemarkType.setDescription(asDescription(route.getDescription()));
   placemarkType.setStyleUrl("#" + TRACK_LINE_STYLE);
   // create gx:Track if there are at least two positions with a time stamp
   if (containTime(route)) {
     slash.navigation.kml.binding22gx.ObjectFactory gxObjectFactory =
         new slash.navigation.kml.binding22gx.ObjectFactory();
     TrackType trackType = gxObjectFactory.createTrackType();
     List<KmlPosition> positions = route.getPositions();
     for (int i = startIndex; i < endIndex; i++) {
       KmlPosition position = positions.get(i);
       String time = position.hasTime() ? formatDate(position.getTime()) : "";
       trackType.getWhen().add(time);
     }
     for (int i = startIndex; i < endIndex; i++) {
       KmlPosition position = positions.get(i);
       trackType.getCoord().add(createCoordinates(position, true));
     }
     placemarkType.setAbstractGeometryGroup(gxObjectFactory.createTrack(trackType));
   } else {
     LineStringType lineStringType = objectFactory.createLineStringType();
     placemarkType.setAbstractGeometryGroup(objectFactory.createLineString(lineStringType));
     List<String> coordinates = lineStringType.getCoordinates();
     List<KmlPosition> positions = route.getPositions();
     for (int i = startIndex; i < endIndex; i++) {
       KmlPosition position = positions.get(i);
       coordinates.add(createCoordinates(position, false));
     }
   }
   return placemarkType;
 }
 private FolderType createWayPoints(KmlRoute route, int startIndex, int endIndex) {
   ObjectFactory objectFactory = new ObjectFactory();
   FolderType folderType = objectFactory.createFolderType();
   folderType.setName(WAYPOINTS);
   folderType.setDescription(asDescription(route.getDescription()));
   List<KmlPosition> positions = route.getPositions();
   for (int i = startIndex; i < endIndex; i++) {
     KmlPosition position = positions.get(i);
     PlacemarkType placemarkType = objectFactory.createPlacemarkType();
     folderType.getAbstractFeatureGroup().add(objectFactory.createPlacemark(placemarkType));
     placemarkType.setName(asName(isWriteName() ? position.getDescription() : null));
     placemarkType.setDescription(asDesc(isWriteDesc() ? position.getDescription() : null));
     if (position.hasTime()) {
       TimeStampType timeStampType = objectFactory.createTimeStampType();
       timeStampType.setWhen(formatDate(position.getTime()));
       placemarkType.setAbstractTimePrimitiveGroup(objectFactory.createTimeStamp(timeStampType));
     }
     PointType pointType = objectFactory.createPointType();
     placemarkType.setAbstractGeometryGroup(objectFactory.createPoint(pointType));
     pointType.getCoordinates().add(createCoordinates(position, false));
   }
   return folderType;
 }
  private void extractWayPointsAndTracksFromPlacemarks(
      String name,
      String description,
      List<JAXBElement<PlacemarkType>> placemarkTypes,
      ParserContext<KmlRoute> context) {
    List<KmlPosition> waypoints = new ArrayList<>();
    for (JAXBElement<PlacemarkType> placemarkType : placemarkTypes) {
      PlacemarkType placemarkTypeValue = placemarkType.getValue();
      String placemarkName =
          asDescription(
              trim(placemarkTypeValue.getName()), trim(placemarkTypeValue.getDescription()));

      JAXBElement<? extends AbstractGeometryType> abstractGeometryGroup =
          placemarkTypeValue.getAbstractGeometryGroup();
      if (abstractGeometryGroup == null) continue;

      List<KmlPosition> positions = extractPositionsFromGeometry(abstractGeometryGroup);
      if (positions.size() == 1) {
        // all placemarks with one position form one waypoint route
        KmlPosition wayPoint = positions.get(0);
        enrichPosition(
            wayPoint,
            extractTime(placemarkTypeValue.getAbstractTimePrimitiveGroup()),
            placemarkName,
            placemarkTypeValue.getDescription(),
            context.getStartDate());
        waypoints.add(wayPoint);
      } else {
        // each placemark with more than one position is one track
        String routeName = concatPath(name, asName(placemarkName));
        List<String> routeDescription =
            asDescription(
                placemarkTypeValue.getDescription() != null
                    ? placemarkTypeValue.getDescription()
                    : description);
        RouteCharacteristics characteristics = parseCharacteristics(routeName, Track);
        context.appendRoute(
            new KmlRoute(this, characteristics, routeName, routeDescription, positions));
      }
    }
    if (waypoints.size() > 0) {
      RouteCharacteristics characteristics = parseCharacteristics(name, Waypoints);
      context.prependRoute(
          new KmlRoute(this, characteristics, name, asDescription(description), waypoints));
    }
  }
 private PlacemarkType createSpeedSegment(
     int currentSegment, int speedClass, List<String> coordinates) {
   ObjectFactory objectFactory = new ObjectFactory();
   PlacemarkType placemarkType = objectFactory.createPlacemarkType();
   placemarkType.setName("Segment " + currentSegment);
   placemarkType.setDescription(getSpeedDescription(speedClass));
   placemarkType.setStyleUrl('#' + getSpeedColor(speedClass));
   placemarkType.setVisibility(FALSE);
   LineStringType lineStringType = objectFactory.createLineStringType();
   lineStringType.getCoordinates().addAll(coordinates);
   placemarkType.setAbstractGeometryGroup(objectFactory.createLineString(lineStringType));
   return placemarkType;
 }
  protected void extractTracks(KmlType kmlType, ParserContext<KmlRoute> context)
      throws IOException {
    AbstractFeatureType feature = kmlType.getAbstractFeatureGroup().getValue();
    if (feature instanceof AbstractContainerType) {
      AbstractContainerType containerType = (AbstractContainerType) feature;
      List<JAXBElement<? extends AbstractFeatureType>> features = null;
      if (containerType instanceof FolderType)
        features = ((FolderType) containerType).getAbstractFeatureGroup();
      else if (containerType instanceof DocumentType)
        features = ((DocumentType) containerType).getAbstractFeatureGroup();
      extractTracks(
          trim(containerType.getName()), trim(containerType.getDescription()), features, context);
    }

    if (feature instanceof PlacemarkType) {
      PlacemarkType placemarkType = (PlacemarkType) feature;
      String placemarkName =
          asDescription(trim(placemarkType.getName()), trim(placemarkType.getDescription()));

      List<KmlPosition> positions =
          extractPositionsFromGeometry(placemarkType.getAbstractGeometryGroup());
      for (KmlPosition position : positions) {
        enrichPosition(
            position,
            extractTime(placemarkType.getAbstractTimePrimitiveGroup()),
            placemarkName,
            placemarkType.getDescription(),
            context.getStartDate());
      }
      context.appendRoute(new KmlRoute(this, Waypoints, placemarkName, null, positions));
    }

    if (feature instanceof TourType) {
      TourType tourType = (TourType) feature;
      String tourName = asDescription(trim(tourType.getName()), trim(tourType.getDescription()));

      List<KmlPosition> positions =
          extractPositionsFromTour(tourType.getPlaylist().getAbstractTourPrimitiveGroup());
      for (KmlPosition position : positions) {
        enrichPosition(
            position,
            extractTime(tourType.getAbstractTimePrimitiveGroup()),
            tourName,
            tourType.getDescription(),
            context.getStartDate());
      }
      context.appendRoute(new KmlRoute(this, Track, tourName, null, positions));
    }
  }