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 Vec2Type createVec2Type(double x, double y, UnitsEnumType unitX, UnitsEnumType unitY) { ObjectFactory objectFactory = new ObjectFactory(); Vec2Type vec2Type = objectFactory.createVec2Type(); vec2Type.setX(x); vec2Type.setY(y); vec2Type.setXunits(unitX); vec2Type.setYunits(unitY); return vec2Type; }
private StyleType createLineStyle(String styleName, double width, byte[] color) { ObjectFactory objectFactory = new ObjectFactory(); StyleType styleType = objectFactory.createStyleType(); styleType.setId(styleName); LineStyleType lineStyleType = objectFactory.createLineStyleType(); styleType.setLineStyle(lineStyleType); lineStyleType.setColor(color); lineStyleType.setWidth(width); return styleType; }
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 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; }
private ScreenOverlayType createScreenOverlayImage( String name, String url, Vec2Type overlayXY, Vec2Type screenXY, Vec2Type size) { ObjectFactory objectFactory = new ObjectFactory(); ScreenOverlayType screenOverlayType = objectFactory.createScreenOverlayType(); screenOverlayType.setName(name); screenOverlayType.setOverlayXY(overlayXY); screenOverlayType.setScreenXY(screenXY); screenOverlayType.setSize(size); LinkType icon = objectFactory.createLinkType(); icon.setHref(url); screenOverlayType.setIcon(icon); return screenOverlayType; }
private FolderType createSpeed(KmlRoute route, int startIndex, int endIndex) { ObjectFactory objectFactory = new ObjectFactory(); FolderType folderType = objectFactory.createFolderType(); folderType.setName(SPEED); folderType.setVisibility(FALSE); folderType.setOpen(FALSE); folderType.getAbstractFeatureGroup().add(objectFactory.createScreenOverlay(createSpeedbar())); int segmentIndex = 0; List<String> coordinates = new ArrayList<>(); Integer previousSpeedClass = null; Double previousSpeed = null; KmlPosition previous = null; List<KmlPosition> positions = route.getPositions(); // since the speed of a position is the average speed of the previous segment for (int i = startIndex; i < endIndex; i++) { KmlPosition position = positions.get(i); Double speed = null; if (position.hasSpeed()) speed = position.getSpeed(); else if (previous != null) speed = previous.calculateSpeed(position); if (speed == null) speed = previousSpeed; if (speed == null) continue; coordinates.add(createCoordinates(position, false)); int speedClass = getSpeedClass(speed); if (previousSpeedClass != null && previousSpeedClass != speedClass) { PlacemarkType placemarkType = createSpeedSegment(++segmentIndex, previousSpeedClass, coordinates); folderType.getAbstractFeatureGroup().add(objectFactory.createPlacemark(placemarkType)); coordinates.clear(); coordinates.add(createCoordinates(position, false)); } previousSpeedClass = speedClass; previousSpeed = speed; previous = position; } return segmentIndex > 0 ? folderType : null; }
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 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 KmlType createKmlType(List<KmlRoute> routes) { ObjectFactory objectFactory = new ObjectFactory(); KmlType kmlType = objectFactory.createKmlType(); DocumentType documentType = objectFactory.createDocumentType(); kmlType.setAbstractFeatureGroup(objectFactory.createDocument(documentType)); /* might make sense for Waypoint lists with one position lists in the file if(routes.size() == 1) { KmlRoute route = routes.get(0); documentType.setName(createDocumentName(route)); documentType.setDescription(asDescription(route.getDescription())); } */ documentType.setOpen(TRUE); if (hasCharacteristics(routes, Route)) documentType .getAbstractStyleSelectorGroup() .add( objectFactory.createStyle( createLineStyle(ROUTE_LINE_STYLE, getLineWidth(), getRouteLineColor()))); if (hasCharacteristics(routes, Track)) { documentType .getAbstractStyleSelectorGroup() .add( objectFactory.createStyle( createLineStyle(TRACK_LINE_STYLE, getLineWidth(), getTrackLineColor()))); if (isWriteSpeed()) for (StyleType style : createSpeedTrackColors(getSpeedLineWidth())) documentType.getAbstractStyleSelectorGroup().add(objectFactory.createStyle(style)); } for (KmlRoute route : routes) { switch (route.getCharacteristics()) { case Waypoints: FolderType wayPoints = createWayPoints(route, 0, route.getPositionCount()); documentType.getAbstractFeatureGroup().add(objectFactory.createFolder(wayPoints)); break; case Route: FolderType routeFolder = objectFactory.createFolderType(); routeFolder.setName(createPlacemarkName(ROUTE, route)); documentType.getAbstractFeatureGroup().add(objectFactory.createFolder(routeFolder)); PlacemarkType routePlacemarks = createRoute(route); routeFolder.getAbstractFeatureGroup().add(objectFactory.createPlacemark(routePlacemarks)); if (isWriteMarks()) routeFolder .getAbstractFeatureGroup() .add(objectFactory.createFolder(createMarks(route, 0, route.getPositionCount()))); break; case Track: FolderType trackFolder = objectFactory.createFolderType(); trackFolder.setName(createPlacemarkName(TRACK, route)); documentType.getAbstractFeatureGroup().add(objectFactory.createFolder(trackFolder)); PlacemarkType track = createTrack(route, 0, route.getPositionCount()); trackFolder.getAbstractFeatureGroup().add(objectFactory.createPlacemark(track)); if (isWriteSpeed()) { FolderType speed = createSpeed(route, 0, route.getPositionCount()); if (speed != null) trackFolder.getAbstractFeatureGroup().add(objectFactory.createFolder(speed)); } if (isWriteMarks()) trackFolder .getAbstractFeatureGroup() .add(objectFactory.createFolder(createMarks(route, 0, route.getPositionCount()))); break; default: throw new IllegalArgumentException( "Unknown RouteCharacteristics " + route.getCharacteristics()); } } return kmlType; }
protected KmlType createKmlType(KmlRoute route, int startIndex, int endIndex) { ObjectFactory objectFactory = new ObjectFactory(); KmlType kmlType = objectFactory.createKmlType(); DocumentType documentType = objectFactory.createDocumentType(); kmlType.setAbstractFeatureGroup(objectFactory.createDocument(documentType)); documentType.setName(createDocumentName(route)); documentType.setDescription(asDescription(route.getDescription())); documentType.setOpen(TRUE); if (hasCharacteristics(singletonList(route), Route)) documentType .getAbstractStyleSelectorGroup() .add( objectFactory.createStyle( createLineStyle(ROUTE_LINE_STYLE, getLineWidth(), getRouteLineColor()))); if (hasCharacteristics(singletonList(route), Track)) { documentType .getAbstractStyleSelectorGroup() .add( objectFactory.createStyle( createLineStyle(TRACK_LINE_STYLE, getLineWidth(), getTrackLineColor()))); if (isWriteSpeed()) for (StyleType style : createSpeedTrackColors(getSpeedLineWidth())) documentType.getAbstractStyleSelectorGroup().add(objectFactory.createStyle(style)); } FolderType folderType = createWayPoints(route, startIndex, endIndex); documentType.getAbstractFeatureGroup().add(objectFactory.createFolder(folderType)); PlacemarkType placemarkTrack = createTrack(route, startIndex, endIndex); documentType.getAbstractFeatureGroup().add(objectFactory.createPlacemark(placemarkTrack)); if (hasCharacteristics(singletonList(route), Track)) { FolderType speed = createSpeed(route, startIndex, endIndex); if (speed != null) documentType.getAbstractFeatureGroup().add(objectFactory.createFolder(speed)); } if (!route.getCharacteristics().equals(Waypoints) && isWriteMarks()) { FolderType marks = createMarks(route, startIndex, endIndex); documentType.getAbstractFeatureGroup().add(objectFactory.createFolder(marks)); } return kmlType; }
private FolderType createMarks(KmlRoute route, int startIndex, int endIndex) { ObjectFactory objectFactory = new ObjectFactory(); FolderType marks = objectFactory.createFolderType(); marks.setName(MARKS); marks.setVisibility(FALSE); marks.setOpen(FALSE); double currentDistance = 0, previousDistance = 0; int currentKiloMeter = 1; List<KmlPosition> positions = route.getPositions(); for (int i = startIndex + 1; i < endIndex; i++) { KmlPosition previousPosition = positions.get(i - 1); KmlPosition currentPosition = positions.get(i); Double distance = currentPosition.calculateDistance(previousPosition); if (isEmpty(distance)) continue; currentDistance += distance; if (currentDistance >= METERS_BETWEEN_MARKS) { // calculate the point at the kilometer mark that's between the current position and the // previous one. // it is possible, that there's more than one point to create // see: http://www.movable-type.co.uk/scripts/latlong.html and // http://williams.best.vwh.net/avform.htm#LL KmlPosition intermediate = new KmlPosition( previousPosition.getLongitude(), previousPosition.getLatitude(), null, null, null, null); // remaining distance between the last point and the mark double remainingDistance = METERS_BETWEEN_MARKS - (previousDistance % METERS_BETWEEN_MARKS); do { double angle = toRadians(intermediate.calculateAngle(currentPosition)); double latitude1 = toRadians(intermediate.getLatitude()); double longitude1 = toRadians(intermediate.getLongitude()); double latitude2 = asin( sin(latitude1) * cos(remainingDistance / EARTH_RADIUS) + cos(latitude1) * sin(remainingDistance / EARTH_RADIUS) * cos(angle)); double longitude2 = longitude1 + atan2( sin(angle) * sin(remainingDistance / EARTH_RADIUS) * cos(latitude1), cos(remainingDistance / EARTH_RADIUS) - sin(latitude1) * sin(latitude2)); intermediate.setLatitude(toDegrees(latitude2)); intermediate.setLongitude(toDegrees(longitude2)); PlacemarkType placeMark = createMark( currentKiloMeter++, intermediate.getLongitude(), intermediate.getLatitude()); marks.getAbstractFeatureGroup().add(objectFactory.createPlacemark(placeMark)); remainingDistance = METERS_BETWEEN_MARKS; } while (toDouble(intermediate.calculateDistance(currentPosition)) > METERS_BETWEEN_MARKS); currentDistance = currentDistance % METERS_BETWEEN_MARKS; } previousDistance = currentDistance; } return marks; }