Search in sources :

Example 6 with MapPoint

use of uk.me.parabola.mkgmap.general.MapPoint in project mkgmap by openstreetmap.

the class Locator method findCityByIsIn.

private MapPoint findCityByIsIn(MapPoint place) {
    if (locationAutofill.contains("is_in") == false) {
        return null;
    }
    String isIn = place.getIsIn();
    if (isIn == null) {
        return null;
    }
    String[] cityList = isIn.split(",");
    // Go through the isIn string and check if we find a city with this name
    // Lets hope we find the next bigger city
    double minDist = Double.MAX_VALUE;
    Collection<MapPoint> nextCityList = null;
    for (String cityCandidate : cityList) {
        cityCandidate = cityCandidate.trim();
        Collection<MapPoint> candidateCityList = cityMap.get(cityCandidate);
        if (candidateCityList.isEmpty() == false) {
            if (nextCityList == null) {
                nextCityList = new ArrayList<MapPoint>(candidateCityList.size());
            }
            nextCityList.addAll(candidateCityList);
        }
    }
    if (nextCityList == null) {
        // no city name found in the is_in tag
        return null;
    }
    MapPoint nearbyCity = null;
    for (MapPoint nextCity : nextCityList) {
        double dist = place.getLocation().distance(nextCity.getLocation());
        if (dist < minDist) {
            minDist = dist;
            nearbyCity = nextCity;
        }
    }
    // otherwise don't use it but issue a warning
    if (minDist > MAX_CITY_DIST) {
        log.warn("is_in of", place.getName(), "is far away from", nearbyCity.getName(), (minDist / 1000.0), "km is_in", place.getIsIn());
        log.warn("Number of cities with this name:", nextCityList.size());
    }
    return nearbyCity;
}
Also used : MapPoint(uk.me.parabola.mkgmap.general.MapPoint)

Example 7 with MapPoint

use of uk.me.parabola.mkgmap.general.MapPoint in project mkgmap by openstreetmap.

the class MapArea method split.

/**
 * Split this area into several pieces. All the map elements are reallocated
 * to the appropriate subarea.  Usually this instance would now be thrown
 * away and the new sub areas used instead.
 * <p>
 * This code is dealing with a lot of factors that govern the splitting, eg:
 *  splitPolygonsIntoArea,
 *  tooSmallToDivide,
 *  item.minResolution vs. areaResolution,
 *  number/size of items and the limits of a subDivision,
 *  items that exceed maximum subDivision on their own,
 *  items that extend up to 50% outside the current area,
 *  items bigger than this.
 *
 * @param nx The number of pieces in the x (longitude) direction.
 * @param ny The number of pieces in the y direction.
 * @param bounds the bounding box that is used to create the areas.
 * @param tooSmallToDivide the area is small and data overflows; split into overflow areas
 *
 * @return An array of the new MapArea's or null if can't split.
 */
public MapArea[] split(int nx, int ny, Area bounds, boolean tooSmallToDivide) {
    int resolutionShift = MAX_RESOLUTION - areaResolution;
    Area[] areas = bounds.split(nx, ny, resolutionShift);
    if (areas == null) {
        // Failed to split!
        if (log.isDebugEnabled()) {
            // see what is here
            for (MapLine e : this.lines) if (e.getMinResolution() <= areaResolution)
                log.debug("line. locn=", e.getPoints().get(0).toOSMURL(), " type=", uk.me.parabola.mkgmap.reader.osm.GType.formatType(e.getType()), " name=", e.getName(), " min=", e.getMinResolution(), " max=", e.getMaxResolution());
            for (MapShape e : this.shapes) if (e.getMinResolution() <= areaResolution)
                log.debug("shape. locn=", e.getPoints().get(0).toOSMURL(), " type=", uk.me.parabola.mkgmap.reader.osm.GType.formatType(e.getType()), " name=", e.getName(), " min=", e.getMinResolution(), " max=", e.getMaxResolution(), " full=", e.getFullArea(), " calc=", uk.me.parabola.mkgmap.filters.ShapeMergeFilter.calcAreaSizeTestVal(e.getPoints()));
        // the main culprits are lots of bits of sea and coastline in an overview map (res 12)
        }
        return null;
    }
    MapArea[] mapAreas = new MapArea[nx * ny];
    log.info("Splitting area " + bounds + " into " + nx + "x" + ny + " pieces at resolution " + areaResolution, tooSmallToDivide);
    List<MapArea> addedAreas = new ArrayList<>();
    for (int i = 0; i < mapAreas.length; i++) {
        mapAreas[i] = new MapArea(areas[i], areaResolution, splitPolygonsIntoArea);
        if (log.isDebugEnabled())
            log.debug("area before", mapAreas[i].getBounds());
    }
    int xbaseHp = areas[0].getMinLong() << Coord.DELTA_SHIFT;
    int ybaseHp = areas[0].getMinLat() << Coord.DELTA_SHIFT;
    int dxHp = areas[0].getWidth() << Coord.DELTA_SHIFT;
    int dyHp = areas[0].getHeight() << Coord.DELTA_SHIFT;
    // Some of the work done by PolygonSubdivSizeSplitterFilter now done here
    final int maxSize = Math.min((1 << 24) - 1, Math.max(MapSplitter.MAX_DIVISION_SIZE << (MAX_RESOLUTION - areaResolution), 0x8000));
    /**
     * These constants control when an item (shape unless splitPolygonsIntoArea or line) is shifted into its own MapArea/SubDivision.
     * Generally, an item is allowed into the MapArea chosen by centre provided it is no bigger than the MapArea.
     * This means that there could be big items near the edges of the MapArea that stick out by almost half, so must
     * ensure that this doesn't cause the mapArea to exceed subDivision size limits.
     * When the MapArea get small, we don't want to shift lots if items into their own areas;
     * The *2 of LARGE_OBJECT_DIM is to keep to the same behaviour as earlier versions.
     */
    final int maxWidth = Math.max(Math.min(areas[0].getWidth(), maxSize / 2), LARGE_OBJECT_DIM * 2);
    final int maxHeight = Math.max(Math.min(areas[0].getHeight(), maxSize / 2), LARGE_OBJECT_DIM * 2);
    // and don't have a good tooSmallToDivide strategy when not splitPolygonsIntoArea.
    if (tooSmallToDivide) {
        distShapesIntoNewAreas(addedAreas, mapAreas[0]);
    } else {
        for (MapShape e : this.shapes) {
            Area shapeBounds = e.getBounds();
            if (splitPolygonsIntoArea || shapeBounds.getMaxDimension() > maxSize) {
                splitIntoAreas(mapAreas, e);
                continue;
            }
            int areaIndex = pickArea(mapAreas, e, xbaseHp, ybaseHp, nx, ny, dxHp, dyHp);
            if ((shapeBounds.getHeight() > maxHeight || shapeBounds.getWidth() > maxWidth) && !areas[areaIndex].contains(shapeBounds)) {
                // use splitIntoAreas to deal with overflow
                MapArea largeObjectArea = new MapArea(shapeBounds, areaResolution, true);
                largeObjectArea.addShape(e);
                addedAreas.add(largeObjectArea);
                continue;
            }
            mapAreas[areaIndex].addShape(e);
        }
    }
    if (tooSmallToDivide) {
        distPointsIntoNewAreas(addedAreas, mapAreas[0]);
    } else {
        for (MapPoint p : this.points) {
            int areaIndex = pickArea(mapAreas, p, xbaseHp, ybaseHp, nx, ny, dxHp, dyHp);
            mapAreas[areaIndex].addPoint(p);
        }
    }
    if (tooSmallToDivide) {
        distLinesIntoNewAreas(addedAreas, mapAreas[0]);
    } else {
        for (MapLine l : this.lines) {
            // Drop any zero sized lines.
            if (l instanceof MapRoad == false && l.getRect().height <= 0 && l.getRect().width <= 0)
                continue;
            Area lineBounds = l.getBounds();
            int areaIndex = pickArea(mapAreas, l, xbaseHp, ybaseHp, nx, ny, dxHp, dyHp);
            if ((lineBounds.getHeight() > maxHeight || lineBounds.getWidth() > maxWidth) && !areas[areaIndex].contains(lineBounds)) {
                MapArea largeObjectArea = new MapArea(lineBounds, areaResolution, false);
                largeObjectArea.addLine(l);
                addedAreas.add(largeObjectArea);
                continue;
            }
            mapAreas[areaIndex].addLine(l);
        }
    }
    if (!addedAreas.isEmpty()) {
        // combine list and array
        int pos = mapAreas.length;
        mapAreas = Arrays.copyOf(mapAreas, mapAreas.length + addedAreas.size());
        for (MapArea ma : addedAreas) {
            if (// distShapesIntoNewAreas etc didn't know how big it was going to be
            ma.getBounds() == null)
                // so set to bounds of all elements
                ma.setBounds(ma.getFullBounds());
            mapAreas[pos++] = ma;
        }
    }
    return mapAreas;
}
Also used : Area(uk.me.parabola.imgfmt.app.Area) MapLine(uk.me.parabola.mkgmap.general.MapLine) MapPoint(uk.me.parabola.mkgmap.general.MapPoint) ArrayList(java.util.ArrayList) MapRoad(uk.me.parabola.mkgmap.general.MapRoad) MapShape(uk.me.parabola.mkgmap.general.MapShape) MapPoint(uk.me.parabola.mkgmap.general.MapPoint)

Example 8 with MapPoint

use of uk.me.parabola.mkgmap.general.MapPoint in project mkgmap by openstreetmap.

the class MapBuilder method normalizeCountries.

/**
 * Process the country names of all elements and normalize them
 * so that one consistent country name is used for the same country
 * instead of different spellings.
 * @param src the source of elements
 */
private void normalizeCountries(MapDataSource src) {
    for (MapPoint p : src.getPoints()) {
        String countryStr = p.getCountry();
        if (countryStr != null) {
            countryStr = locator.normalizeCountry(countryStr);
            p.setCountry(countryStr);
        }
    }
    for (MapLine l : src.getLines()) {
        String countryStr = l.getCountry();
        if (countryStr != null) {
            countryStr = locator.normalizeCountry(countryStr);
            l.setCountry(countryStr);
        }
    }
// shapes do not have address information
// untag the following lines if this is wrong
// for (MapShape s : src.getShapes()) {
// String countryStr = s.getCountry();
// if (countryStr != null) {
// countryStr = locator.normalizeCountry(countryStr);
// s.setCountry(countryStr);
// }
// }
}
Also used : MapLine(uk.me.parabola.mkgmap.general.MapLine) MapPoint(uk.me.parabola.mkgmap.general.MapPoint)

Example 9 with MapPoint

use of uk.me.parabola.mkgmap.general.MapPoint in project mkgmap by openstreetmap.

the class MapBuilder method makeSubdivision.

/**
 * Make an individual subdivision for the map.  To do this we need a link
 * to its parent and the zoom level that we are working at.
 *
 * @param map	The map to add this subdivision into.
 * @param parent The parent division.
 * @param ma	 The area of the map that we are fitting into this division.
 * @param z	  The zoom level.
 * @return The new subdivsion.
 */
private Subdivision makeSubdivision(Map map, Subdivision parent, MapArea ma, Zoom z) {
    List<MapPoint> points = ma.getPoints();
    List<MapLine> lines = ma.getLines();
    List<MapShape> shapes = ma.getShapes();
    Subdivision div = map.createSubdivision(parent, ma.getFullBounds(), z);
    if (ma.hasPoints())
        div.setHasPoints(true);
    if (ma.hasIndPoints())
        div.setHasIndPoints(true);
    if (ma.hasLines())
        div.setHasPolylines(true);
    if (ma.hasShapes())
        div.setHasPolygons(true);
    div.startDivision();
    processPoints(map, div, points);
    processLines(map, div, lines);
    processShapes(map, div, shapes);
    div.endDivision();
    return div;
}
Also used : MapLine(uk.me.parabola.mkgmap.general.MapLine) MapPoint(uk.me.parabola.mkgmap.general.MapPoint) Subdivision(uk.me.parabola.imgfmt.app.trergn.Subdivision) MapShape(uk.me.parabola.mkgmap.general.MapShape)

Example 10 with MapPoint

use of uk.me.parabola.mkgmap.general.MapPoint in project mkgmap by openstreetmap.

the class MapBuilder method processCities.

/**
 * Processing of Cities
 *
 * Fills the city list in lbl block that is required for find by name
 * It also builds up information that is required to get address info
 * for the POIs
 *
 * @param map The map.
 * @param src The map data.
 */
private void processCities(Map map, MapDataSource src) {
    LBLFile lbl = map.getLblFile();
    if (locationAutofill.isEmpty() == false) {
        // collect the names of the cities
        for (MapPoint p : src.getPoints()) {
            if (p.isCity() && p.getName() != null)
                // Put the city info the map for missing info
                locator.addCityOrPlace(p);
        }
        // Try to fill missing information that include search of next city
        locator.autofillCities();
    }
    for (MapPoint p : src.getPoints()) {
        if (p.isCity() && p.getName() != null) {
            String countryStr = p.getCountry();
            Country thisCountry;
            if (countryStr != null) {
                thisCountry = lbl.createCountry(countryStr, locator.getCountryISOCode(countryStr));
            } else
                thisCountry = getDefaultCountry();
            String regionStr = p.getRegion();
            Region thisRegion;
            if (regionStr != null) {
                thisRegion = lbl.createRegion(thisCountry, regionStr, null);
            } else
                thisRegion = getDefaultRegion(thisCountry);
            City thisCity;
            if (thisRegion != null)
                thisCity = lbl.createCity(thisRegion, p.getName(), true);
            else
                thisCity = lbl.createCity(thisCountry, p.getName(), true);
            cityMap.put(p, thisCity);
        }
    }
}
Also used : MapPoint(uk.me.parabola.mkgmap.general.MapPoint) Country(uk.me.parabola.imgfmt.app.lbl.Country) Region(uk.me.parabola.imgfmt.app.lbl.Region) LBLFile(uk.me.parabola.imgfmt.app.lbl.LBLFile) City(uk.me.parabola.imgfmt.app.lbl.City)

Aggregations

MapPoint (uk.me.parabola.mkgmap.general.MapPoint)20 MapLine (uk.me.parabola.mkgmap.general.MapLine)8 Coord (uk.me.parabola.imgfmt.app.Coord)5 MapShape (uk.me.parabola.mkgmap.general.MapShape)5 LBLFile (uk.me.parabola.imgfmt.app.lbl.LBLFile)4 City (uk.me.parabola.imgfmt.app.lbl.City)3 Point (uk.me.parabola.imgfmt.app.trergn.Point)3 MapExitPoint (uk.me.parabola.mkgmap.general.MapExitPoint)3 MapRoad (uk.me.parabola.mkgmap.general.MapRoad)3 ArrayList (java.util.ArrayList)2 Area (uk.me.parabola.imgfmt.app.Area)2 POIRecord (uk.me.parabola.imgfmt.app.lbl.POIRecord)2 Zip (uk.me.parabola.imgfmt.app.lbl.Zip)2 Test (org.junit.Test)1 Exit (uk.me.parabola.imgfmt.app.Exit)1 Label (uk.me.parabola.imgfmt.app.Label)1 Country (uk.me.parabola.imgfmt.app.lbl.Country)1 Region (uk.me.parabola.imgfmt.app.lbl.Region)1 GeneralRouteRestriction (uk.me.parabola.imgfmt.app.net.GeneralRouteRestriction)1 Numbers (uk.me.parabola.imgfmt.app.net.Numbers)1