Ejemplo n.º 1
0
        //static int livingsign = 0;

        /// <summary>
        /// bildet rekursiv den Subdiv-Baum
        /// </summary>
        /// <param name="orgmap"></param>
        /// <param name="parentmap"></param>
        /// <param name="coordbits"></param>
        /// <param name="pointtypes"></param>
        /// <param name="linetypes"></param>
        /// <param name="areatypes"></param>
        /// <param name="level"></param>
        static void buildSubdivmapTree(DetailMap orgmap, DetailMap parentmap, int[] coordbits, IList <SortedSet <int> > pointtypes, IList <SortedSet <int> > linetypes, IList <SortedSet <int> > areatypes, int level = 0)
        {
            if (level >= coordbits.Length)
            {
                return;
            }

            split2Subdivmaps4Bits(orgmap, parentmap, coordbits[level], pointtypes[level], linetypes[level], areatypes[level]);

            //Console.Write(".");
            //if (++livingsign % 100 == 0)
            //   Console.Write(livingsign);

            level++;
            for (int i = 0; i < parentmap.ChildMapCount; i++)
            {
                buildSubdivmapTree(orgmap, parentmap.GetChildMap(i), coordbits, pointtypes, linetypes, areatypes, level);
            }
        }
Ejemplo n.º 2
0
        // from MKGMAP:

        /**
         * Split the area into portions that have the maximum size. There is a maximum limit to the size of a subdivision (16 bits or about 1.4 degrees at the most detailed zoom level).
         *
         * The size depends on the shift level.
         *
         * We are choosing a limit smaller than the real max to allow for uncertainty about what happens with features that extend beyond the box.
         *
         * If the area is already small enough then it will be returned unchanged.
         *
         * @param mapArea The area that needs to be split down.
         * @return An array of map areas.  Each will be below the max size.
         *
         *
         * Die halbe Breite und Höhe einer Subdiv wird jeweils in 16 Bit gespeichert. MKGMAP verwendet sicherheitshalber sogar nur 15 Bit (0x7FFF). Die damit erreichbare
         * max. Breite und Höhe ist zusätzlich abhängig von der Bitanzahl für die Koordinaten
         * (SymbolicScaleAndBitsLevel.Bits(level) -> SubdivInfoBasic.Degree(rawunits, coordbits) -> GarminCoordinate.RawUnits2Degree(rawunits, coordbits)).
         * Schon daraus folgt, dass ein großes Subdiv bei einem größeren Maßstab/Zoom vermutlich in mehrere Subdiv's aufgeteilt werden muss.
         *
         * Weiterhin soll die Anzahl der Objekte in einer Subdiv nicht zu groß werden.
         * MKGMAP:  Wenn
         *                Punktanzahl > MAX_NUM_POINTS (0xFF) ||
         *                Linienanzahl > MAX_NUM_LINES (0xFF) ||
         *                (die Summe der geschätzten Datenbereichsgrößen für Punkte, Linien und Flächen) > MAX_RGN_SIZE (0xFFF8) ||
         *                (geschätzten Datenbereichsgrößen für erw. Punkte) > MAX_XT_POINTS_SIZE (0xFF00) ||
         *                (geschätzten Datenbereichsgrößen für erw. Linien) > MAX_XT_LINES_SIZE (0xFF00) ||
         *                (geschätzten Datenbereichsgrößen für erw. Flächen) > MAX_XT_SHAPES_SIZE (0xFF00) ||
         *                Subdiv > WANTED_MAX_AREA_SIZE (0x3FFF)
         *          dann wir die Subdiv geteilt. Dabei wird je nach dem, welcher Wert größer ist, die Breite oder Höhe halbiert.
         *          Linien und Flächen verteiltt MKGMAP nach der Lage ihrer Mittelpunkte.
         *
         * -> alle Objekte einer Karte für den akt. Maßstab codieren
         *    Karte (mit den Objekten) rekursiv in Teilkarten aufteilen, wenn
         *       die Breite und/oder Höhe zu groß ist ||
         *       Punktanzahl > MAX_NUM_POINTS (0xFF) ||
         *       Linienanzahl > MAX_NUM_LINES (0xFF) ||
         *       (die Summe der Datenbereichsgrößen für Punkte, Linien und Flächen) > MAX_RGN_SIZE (0xFFF8) ||
         *       (Datenbereichsgrößen für erw. Punkte) > MAX_XT_POINTS_SIZE (0xFF00) ||
         *       (Datenbereichsgrößen für erw. Linien) > MAX_XT_LINES_SIZE (0xFF00) ||
         *       (Datenbereichsgrößen für erw. Flächen) > MAX_XT_SHAPES_SIZE (0xFF00) ||
         *       Subdiv > WANTED_MAX_AREA_SIZE (0x3FFF)
         *
         *
         */

        /// <summary>
        /// liefert die Liste der 'obersten' <see cref="DetailMap"/>'s, die jeweils mit den untergeordneten <see cref="DetailMap"/> verbunden sind und jeweils eine Subdiv repräsentieren
        /// </summary>
        /// <param name="orgmap"></param>
        /// <param name="coordbits">Bitanzahl je Ebene</param>
        /// <param name="pointtypes">erlaubte Punkttypen je Ebene</param>
        /// <param name="linetypes">erlaubte Linientypen je Ebene</param>
        /// <param name="areatypes">erlaubte Flächentypen je Ebene</param>
        /// <returns></returns>
        public static List <DetailMap> BuildSubdivmapMapTree(DetailMap orgmap, int[] coordbits, IList <SortedSet <int> > pointtypes, IList <SortedSet <int> > linetypes, IList <SortedSet <int> > areatypes)
        {
            //Console.WriteLine("Subdiv-Baum erzeugen ...");
            //livingsign = 0;

            DetailMap firstlevelmap = orgmap.Copy();

            buildSubdivmapTree(orgmap, firstlevelmap, coordbits, pointtypes, linetypes, areatypes);

            // Die Childs der firstlevelmap bilden die Subdivs der obersten Ebene.
            List <DetailMap> result = new List <DetailMap>();

            for (int i = 0; i < firstlevelmap.ChildMapCount; i++)
            {
                DetailMap sd = firstlevelmap.GetChildMap(i);
                sd.ParentMap = null;
                result.Add(sd);
            }
            //Console.WriteLine();

            return(result);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// erzeugt die Subdiv-Maps mit der gewünschten Bitanzahl mit den Objekten aus der Originalkarte im gewünschten Bereich und verknüpft sie mit der übergeordneten Map
        /// </summary>
        /// <param name="orgmap">Originalkarte mit ALLEN Objekten und max. Auflösung</param>
        /// <param name="parentmap"></param>
        /// <param name="coordbits">Bitanzahl</param>
        /// <param name="pointtypes">erlaubte Punkttypen</param>
        /// <param name="linetypes">erlaubte Linientypen</param>
        /// <param name="areatypes">erlaubte Flächentypen</param>
        static void split2Subdivmaps4Bits(DetailMap orgmap, DetailMap parentmap, int coordbits, SortedSet <int> pointtypes, SortedSet <int> linetypes, SortedSet <int> areatypes)
        {
            coordbits = Math.Max(10, Math.Min(coordbits, 24)); // eingrenzen 10 .. 24

            DetailMap        map4bits   = PrepareMap(orgmap, coordbits, parentmap.DesiredBounds, pointtypes, linetypes, areatypes);
            List <DetailMap> subdivmaps = splitDetailMap(map4bits, coordbits, 0, 0);

            if (subdivmaps == null)
            {
                subdivmaps = new List <DetailMap>()
                {
                    map4bits
                }
            }
            ;

            while (parentmap.ChildMapCount > 0) // ev. vorhandene Childs lösen
            {
                parentmap.GetChildMap(0).ParentMap = null;
            }

            foreach (var item in subdivmaps)
            {
                item.ParentMap = parentmap;
            }
        }

        // größere Werte können Probleme bei der Codierung der Delta-Werte ergeben
        //const int MAX_BOUND4LINE = 0x7FFF; // MKGMAP; etwa 0.703° bei 24 Bit
        //const int MAX_BOUND4AREA = 0xFFFF; // MKGMAP; etwa 1.406° bei 24 Bit
        const int MAX_BOUND4LINE = 0x7FFF;
        const int MAX_BOUND4AREA = 0x3FFF;
        /// <summary>
        /// kleinste Maximalgröße
        /// </summary>
        const int MIN_4MAX_BOUND = 0x7FFF; // MKGMAP 0x8000