Package slash.navigation.kml

Source Code of slash.navigation.kml.KmlFormat

/*
    This file is part of RouteConverter.

    RouteConverter is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    RouteConverter 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with RouteConverter; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

    Copyright (C) 2007 Christian Pesch. All Rights Reserved.
*/

package slash.navigation.kml;

import slash.common.type.CompactCalendar;
import slash.navigation.base.RouteCharacteristics;
import slash.navigation.common.NavigationPosition;

import java.text.ParseException;
import java.util.*;
import java.util.prefs.Preferences;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static java.util.regex.Pattern.DOTALL;
import static slash.common.io.Transfer.parseDouble;
import static slash.common.io.Transfer.trim;
import static slash.common.type.CompactCalendar.*;
import static slash.common.type.HexadecimalNumber.decodeBytes;
import static slash.common.type.ISO8601.parseDate;
import static slash.navigation.base.RouteCharacteristics.*;
import static slash.navigation.common.NavigationConversion.formatElevationAsString;
import static slash.navigation.common.NavigationConversion.formatPositionAsString;
import static slash.navigation.common.PositionParser.parsePositions;

/**
* The base of all Google Earth formats.
*
* @author Christian Pesch
*/

public abstract class KmlFormat extends BaseKmlFormat {
    static final Preferences preferences = Preferences.userNodeForPackage(KmlFormat.class);

    static final String WAYPOINTS = "Waypoints";
    static final String ROUTE = "Route";
    static final String TRACK = "Track";
    static final String SPEED = "Speed [Km/h]";
    static final String MARKS = "Marks [Km]";
    static final String ROUTE_LINE_STYLE = "routeStyle";
    static final String TRACK_LINE_STYLE = "trackStyle";

    public String getExtension() {
        return ".kml";
    }

    public boolean isSupportsMultipleRoutes() {
        return true;
    }

    public boolean isWritingRouteCharacteristics() {
        return true;
    }

    @SuppressWarnings("unchecked")
    public <P extends NavigationPosition> KmlRoute createRoute(RouteCharacteristics characteristics, String name, List<P> positions) {
        return new KmlRoute(this, characteristics, name, null, (List<KmlPosition>) positions);
    }

    protected KmlPosition asKmlPosition(NavigationPosition position) {
        return new KmlPosition(position.getLongitude(), position.getLatitude(), position.getElevation(), null, null, position.getDescription());
    }

    protected List<KmlPosition> asKmlPositions(List<String> strings) {
        StringBuilder buffer = new StringBuilder();
        for (String string : strings) {
            buffer.append(string);
            // to make sure the numbers are separated if they were already parsed by the XML parse
            buffer.append(' ');
        }
        List<KmlPosition> result = new ArrayList<KmlPosition>();
        for (NavigationPosition position : parsePositions(buffer.toString()))
            result.add(asKmlPosition(position));
        return result;
    }

    protected String createDocumentName(KmlRoute route) {
        // some kind of crude workaround since the route carries the name of the
        // plus and divided by a slash the route of the track
        String name = asRouteName(route.getName());
        if (name != null) {
            StringTokenizer tokenizer = new StringTokenizer(name, "/");
            if (tokenizer.hasMoreTokens())
                name = tokenizer.nextToken();
        }
        return name;
    }

    protected String createPlacemarkName(String prefix, KmlRoute route) {
        // some kind of crude workaround since the route carries the name of the
        // plus and divided by a slash the route of the track
        String name = route.getName();
        if (name != null) {
            StringTokenizer tokenizer = new StringTokenizer(name, "/");
            while (tokenizer.hasMoreTokens())
                name = tokenizer.nextToken();

            if (!name.startsWith(prefix))
                name = prefix + ": " + name;
        } else
            name = prefix;
        return name;
    }

    protected String createCoordinates(KmlPosition position, boolean separateWithSpace) {
        return formatPositionAsString(position.getLongitude()) + (separateWithSpace ? " " : ",") +
                formatPositionAsString(position.getLatitude()) + (separateWithSpace ? " " : ",") +
                formatElevationAsString(position.getElevation());
    }

    protected RouteCharacteristics parseCharacteristics(String nameToParse, RouteCharacteristics fallback) {
        RouteCharacteristics result = fallback;
        if (nameToParse != null) {
            int slashIndex = nameToParse.lastIndexOf('/');
            String folder = slashIndex != -1 ? nameToParse.substring(slashIndex + 1) : nameToParse;
            if (folder.startsWith("Waypoint") || nameToParse.contains("Waypoint"))
                result = Waypoints;
            else if (folder.startsWith("Route") || nameToParse.contains("Route"))
                result = Route;
            else if (folder.startsWith("Track") || folder.startsWith("Path") || nameToParse.contains("Track"))
                result = Track;
        }
        return result;
    }

    protected CompactCalendar parseTime(String time) {
        if (time != null) {
            Calendar calendar = parseDate(time);
            if (calendar != null) {
                calendar.setTimeZone(UTC);
                return fromCalendar(calendar);
            }
        }
        return null;
    }

    protected void enrichPosition(KmlPosition position, CompactCalendar time, String name, String description, CompactCalendar startDate) {
        if (!position.hasTime() && time != null)
            position.setTime(time);
        if (!position.hasTime())
            parseTime(position, description, startDate);
        if (!position.hasTime())
            parseTime(position, name, startDate);
        if (position.getDescription() == null)
            position.setDescription(name);

        if (position.getElevation() == null) {
            Double elevation = parseElevation(description);
            if (elevation == null)
                elevation = parseElevation(name);
            position.setElevation(elevation);
        }

        if (position.getSpeed() == null) {
            Double speed = parseSpeed(description);
            position.setSpeed(speed);
        }
    }

    private static final Pattern TAVELLOG_DATE_PATTERN = Pattern.compile(".*Time:.*(\\d{4}/\\d{2}/\\d{2} \\d{2}:\\d{2}:\\d{2}).*");
    private static final String TAVELLOG_DATE ="yyyy/MM/dd HH:mm:ss";
    private static final Pattern NAVIGON6310_TIME_AND_ELEVATION_PATTERN = Pattern.compile(".*(\\d{2}:\\d{2}:\\d{2}),([\\d\\.\\s]+)meter.*");
    private static final String NAVIGON6310_TIME = "HH:mm:ss";
    private static final Pattern BT747_TIME_AND_ELEVATION_PATTERN = Pattern.compile(".*TIME:.*>(\\d{2}-.+-\\d{2} \\d{2}:\\d{2}:\\d{2})<.*>([\\d\\.\\s]+)m<.*");
    private static final String BT747_DATE = "dd-MMMMM-yy HH:mm:ss";
    private static final Pattern QSTARTZ_DATE_AND_SPEED_PATTERN = Pattern.compile(".*Date:\\s*(\\d{4}/\\d{2}/\\d{2}).*Time:\\s*(\\d{2}:\\d{2}:\\d{2}).*Speed:\\s*([\\d\\.]+)\\s*.*", DOTALL);

    void parseTime(NavigationPosition position, String description, CompactCalendar startDate) {
        if (description != null) {
            Matcher tavelLogMatcher = TAVELLOG_DATE_PATTERN.matcher(description);
            if (tavelLogMatcher.matches()) {
                String timeString = tavelLogMatcher.group(1);
                try {
                    Date parsed = createDateFormat(TAVELLOG_DATE).parse(timeString);
                    position.setTime(fromDate(parsed));
                } catch (ParseException e) {
                    // intentionally left empty;
                }
            }
            Matcher navigonMatcher = NAVIGON6310_TIME_AND_ELEVATION_PATTERN.matcher(description);
            if (navigonMatcher.matches()) {
                String timeString = navigonMatcher.group(1);
                try {
                    Date parsed = createDateFormat(NAVIGON6310_TIME).parse(timeString);
                    position.setTime(fromDate(parsed));
                    position.setStartDate(startDate);
                } catch (ParseException e) {
                    // intentionally left empty;
                }
            }
            Matcher bt747Matcher = BT747_TIME_AND_ELEVATION_PATTERN.matcher(description);
            if (bt747Matcher.matches()) {
                String timeString = bt747Matcher.group(1);
                try {
                    Date parsed = createDateFormat(BT747_DATE).parse(timeString);
                    position.setTime(fromDate(parsed));
                } catch (ParseException e) {
                    // intentionally left empty;
                }
            }
            Matcher qstarzMatcher = QSTARTZ_DATE_AND_SPEED_PATTERN.matcher(description);
            if (qstarzMatcher.matches()) {
                String dateString = qstarzMatcher.group(1);
                String timeString = qstarzMatcher.group(2);
                try {
                    Date parsed = createDateFormat(TAVELLOG_DATE).parse(dateString + " " + timeString);
                    position.setTime(fromDate(parsed));
                } catch (ParseException e) {
                    // intentionally left empty;
                }
            }
        }
    }

    private static final Pattern TAVELLOG_SPEED_PATTERN = Pattern.compile(".*Speed:\\s*(\\d+\\.\\d+).*");
    private static final Pattern WBT201LOG_SPEED_PATTERN = Pattern.compile(".*Speed=\\s*(\\d+)\\s*Km.*", DOTALL); // dot captures line terminators, too

    Double parseSpeed(String description) {
        if (description != null) {
            Matcher tavelLogMatcher = TAVELLOG_SPEED_PATTERN.matcher(description);
            if (tavelLogMatcher.matches()) {
                return parseDouble(tavelLogMatcher.group(1));
            }
            Matcher wbt201LogMatcher = WBT201LOG_SPEED_PATTERN.matcher(description);
            if (wbt201LogMatcher.matches()) {
                return parseDouble(wbt201LogMatcher.group(1));
            }
            Matcher qstarzMatcher = QSTARTZ_DATE_AND_SPEED_PATTERN.matcher(description);
            if (qstarzMatcher.matches()) {
                return parseDouble(qstarzMatcher.group(3));
            }
        }
        return null;
    }

    private static final Pattern TAVELLOG_ELEVATION_PATTERN = Pattern.compile(".*Altitude:\\s*(\\d+\\.\\d+).*");

    Double parseElevation(String description) {
        if (description != null) {
            Matcher tavelLogMatcher = TAVELLOG_ELEVATION_PATTERN.matcher(description);
            if (tavelLogMatcher.matches()) {
                return parseDouble(tavelLogMatcher.group(1));
            }
            Matcher navigonMatcher = NAVIGON6310_TIME_AND_ELEVATION_PATTERN.matcher(description);
            if (navigonMatcher.matches()) {
                return parseDouble(navigonMatcher.group(2));
            }
            Matcher bt747Matcher = BT747_TIME_AND_ELEVATION_PATTERN.matcher(description);
            if (bt747Matcher.matches()) {
                return parseDouble(bt747Matcher.group(2));
            }
        }
        return null;
    }

    protected String concatPath(String path, String fragment) {
        path = trim(path);
        fragment = trim(fragment);
        String result = path != null ? path : "";
        if (fragment != null)
            result = result + "/" + fragment;
        return result;
    }

    protected float getLineWidth() {
        return preferences.getFloat("lineWidth", 3.0f);
    }

    protected byte[] getRouteLineColor() {
        String color = preferences.get("routeLineColor", "7FFF0055");
        return decodeBytes(color);
    }

    protected byte[] getTrackLineColor() {
        String color = preferences.get("trackLineColor", "FFFF00FF");
        return decodeBytes(color);
    }

    protected boolean isWriteName() {
        return preferences.getBoolean("writeName", true);
    }

    protected boolean isWriteDesc() {
        return preferences.getBoolean("writeDesc", true);
    }
}
TOP

Related Classes of slash.navigation.kml.KmlFormat

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.