Ignore:
Timestamp:
2016-03-05T11:40:02+01:00 (8 years ago)
Author:
malcolmh
Message:

[SeaChart] improvements

Location:
applications/editors/josm/plugins/seachart
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/seachart/jrender/src/jrender/Jrender.java

    r32090 r32095  
    2727import javax.imageio.ImageIO;
    2828
    29 import org.apache.batik.dom.GenericDOMImplementation;
    30 import org.apache.batik.svggen.SVGGraphics2D;
    31 import org.w3c.dom.DOMImplementation;
    32 import org.w3c.dom.Document;
    33 
    3429import s57.S57map;
    3530import s57.S57osm;
     
    5651         
    5752          public Context () {
    58                         top = (1.0 - Math.log(Math.tan(map.bounds.maxlat) + 1.0 / Math.cos(map.bounds.maxlat)) / Math.PI) / 2.0 * 256.0 * 4096.0;
    59                         mile = 768 / ((Math.toDegrees(map.bounds.maxlat) - Math.toDegrees(map.bounds.minlat)) * 60);
     53                        top = (1.0 - Math.log(Math.tan(map.bounds.maxlat) + 1.0 / Math.cos(map.bounds.maxlat)) / Math.PI) / 2.0 * 256.0 * 4096.0 * Math.pow(2, (zoom - 12));
     54                        mile = (2 * ((zoom < 12) ? (256 / (int)(Math.pow(2, (11 - zoom)))) : 256) + 256) / ((Math.toDegrees(map.bounds.maxlat) - Math.toDegrees(map.bounds.minlat)) * 60);
    6055          }
    6156         
    6257                public Point2D getPoint(Snode coord) {
    63                         double x = (Math.toDegrees(coord.lon) - Math.toDegrees(map.bounds.minlon)) * 256.0 * 2048.0 / 180.0;
    64                         double y = ((1.0 - Math.log(Math.tan(coord.lat) + 1.0 / Math.cos(coord.lat)) / Math.PI) / 2.0 * 256.0 * 4096.0) - top;
     58                        double x = (Math.toDegrees(coord.lon) - Math.toDegrees(map.bounds.minlon)) * 256.0 * 2048.0 * Math.pow(2, (zoom - 12)) / 180.0;
     59                        double y = ((1.0 - Math.log(Math.tan(coord.lat) + 1.0 / Math.cos(coord.lat)) / Math.PI) / 2.0 * 256.0 * 4096.0 * Math.pow(2, (zoom - 12))) - top;
    6560                        return new Point2D.Double(x, y);
    6661                }
     
    8378        }
    8479       
    85         static final boolean test = true;
    86        
    87         public static void tileMap(String idir, int zoom) throws IOException {
    88                 BufferedImage img;
    89                 context = new Context();
    90 
    91                 int border = 256 / (int)Math.pow(2, (12 - zoom));
    92                 int size = 256;
    93                 for (int i = 0; i < (12 - zoom); i++) size *= 2;
    94                 Rectangle rect = new Rectangle((size + (2 * border)), (size + (2 * border)));
    95                 img = new BufferedImage(rect.width, rect.height, BufferedImage.TYPE_INT_ARGB);
    96                 Renderer.reRender(img.createGraphics(), rect, zoom, 1.0, map, context);
    97                 ByteArrayOutputStream bos = new ByteArrayOutputStream();
    98                 ImageIO.write(img, "png", bos);
    99                 empty = bos.size();
    100 
    101                 if (test) {
    102                         for (int z = 12; z <= 18; z++) {
    103                                 DOMImplementation domImpl = GenericDOMImplementation.getDOMImplementation();
    104                                 Document document = domImpl.createDocument("http://www.w3.org/2000/svg", "svg", null);
    105                                 SVGGraphics2D svgGenerator = new SVGGraphics2D(document);
    106                                 svgGenerator.clearRect(rect.x, rect.y, rect.width, rect.height);
    107                                 svgGenerator.setSVGCanvasSize(rect.getSize());
    108                                 svgGenerator.setClip(rect.x, rect.y, rect.width, rect.height);
    109                                 svgGenerator.translate(-border, -border);
    110                                 Renderer.reRender(svgGenerator, rect, z, 1.0, map, context);
    111                                 svgGenerator.stream(dstdir + "tst_" + z + "-" + xtile + "-" + ytile + ".svg");
    112                         }
    113                 } else {
    114                         tile(zoom, 1, 0, 0);
    115                 }
    116         }
    117        
    118         static void tile(int zoom, int s, int xn, int yn) throws IOException {
    119                 int scale = (int) Math.pow(2, zoom - 12);
    120                 int xdir = (scale * xtile) + xn;
    121                 int ynam = (scale * ytile) + yn;
     80        static void tile(int z, int s, int xn, int yn) throws IOException {
     81                int border = (z < 12) ? (256 / (int)(Math.pow(2, (11 - zoom)))) : 256;
     82                int scale = (int)Math.pow(2, z - 12);
     83                int xdir = (scale > 0) ? (scale * xtile) + xn : xtile;
     84                int ynam = (scale > 0) ? (scale * ytile) + yn : ytile;
    12285                BufferedImage img = new BufferedImage(256, 256, BufferedImage.TYPE_INT_ARGB);
    12386                Graphics2D g2 = img.createGraphics();
    12487                g2.scale(s, s);
    125                 g2.translate(-(256 + (xn * 256 / s)), -(256 + (yn * 256 / s)));
    126                 Renderer.reRender(g2, new Rectangle(256, 256), zoom, 1, map, context);
     88                g2.translate(-(border + (xn * 256 / s)), -(border + (yn * 256 / s)));
     89                Renderer.reRender(g2, new Rectangle(256, 256), z, 1.0 * Math.pow(2, (zoom - 12)), map, context);
    12790                ByteArrayOutputStream bos = new ByteArrayOutputStream();
    12891                ImageIO.write(img, "png", bos);
    12992                if (bos.size() > empty) {
    130                         String dstnam = dstdir + zoom + "/" + xdir + "/" + ynam + ".png";
     93                        String dstnam = dstdir + z + "/" + xdir + "/" + ynam + ".png";
    13194                        deletes.remove(dstnam);
    132                         send.add("put " + dstnam + " tiles/" + zoom + "/" + xdir + "/" + ynam + ".png");
    133                         File ofile = new File(dstdir + "/" + zoom + "/" + xdir + "/");
     95                        send.add("put " + dstnam + " tiles/" + z + "/" + xdir + "/" + ynam + ".png");
     96                        File ofile = new File(dstdir + "/" + z + "/" + xdir + "/");
    13497                        ofile.mkdirs();
    135                         FileOutputStream fos = new FileOutputStream(dstdir + "/" + zoom + "/" + xdir + "/" + ynam + ".png");
     98                        FileOutputStream fos = new FileOutputStream(dstdir + "/" + z + "/" + xdir + "/" + ynam + ".png");
    13699                        bos.writeTo(fos);
    137100                        fos.close();
    138                         if (send.size() > 10) {
    139                                 PrintWriter writer = new PrintWriter(srcdir + zoom + "-" + xdir + "-" + ynam + ".send", "UTF-8");
     101                        if (send.size() > 20) {
     102                                PrintWriter writer = new PrintWriter(srcdir + z + "-" + xdir + "-" + ynam + ".send", "UTF-8");
    140103                                for (String str : send) {
    141104                                        writer.println(str);
     
    145108                        }
    146109                }
    147                 if ((zoom >= 12) && (zoom < 18) && ((zoom < 16) || (bos.size() > empty))) {
     110                if ((z >= 12) && (z < 18) && ((z < 16) || (bos.size() > empty))) {
    148111                        for (int x = 0; x < 2; x++) {
    149112                                for (int y = 0; y < 2; y++) {
    150                                         tile((zoom + 1), (s * 2), (xn * 2 + x), (yn * 2 + y));
     113                                        tile((z + 1), (s * 2), (xn * 2 + x), (yn * 2 + y));
    151114                                }
    152115                        }
     
    181144                send = new ArrayList<String>();
    182145                deletes = new HashMap<String, Boolean>();
    183                 BufferedReader in = new BufferedReader(new FileReader(srcdir + zoom + "-" + xtile + "-" + ytile + ".osm"));
     146                BufferedReader in = new BufferedReader(new FileReader(srcdir + xtile + "-" + ytile + "-" + zoom + ".osm"));
    184147                map = new S57map(true);
    185148                S57osm.OSMmap(in, map, false);
    186149                in.close();
     150                context = new Context();
     151                ByteArrayOutputStream bos = new ByteArrayOutputStream();
     152                ImageIO.write(new BufferedImage(256, 256, BufferedImage.TYPE_INT_ARGB), "png", bos);
     153                empty = bos.size();
    187154                if (zoom == 12) {
    188155                        clean(12, 0, 0);
    189156                }
    190                 tileMap(dstdir, zoom);
    191 //              if ((send.size() + deletes.size()) > 0) {
    192 //                      PrintWriter writer = new PrintWriter(srcdir + zoom + "-" + xtile + "-" + ytile + ".send", "UTF-8");
    193 //                      for (String str : send) {
    194 //                              writer.println(str);
    195 //                      }
    196 //                      for (String del : deletes.keySet()) {
    197 //                              writer.println("rm " + del);
    198 //                      }
    199 //                      writer.close();
    200 //              }
     157                tile(zoom, 1, 0, 0);
     158                if (send.size() > 0) {
     159                        PrintWriter writer = new PrintWriter(srcdir + zoom + "-" + xtile + "-" + ytile + ".send", "UTF-8");
     160                        for (String str : send) {
     161                                writer.println(str);
     162                        }
     163                        writer.close();
     164                }
     165                if (deletes.size() > 0) {
     166                        PrintWriter writer = new PrintWriter(srcdir + zoom + "-" + xtile + "-" + ytile + ".delete", "UTF-8");
     167                        for (String del : deletes.keySet()) {
     168                                writer.println("rm " + del);
     169                        }
     170                        writer.close();
     171                }
    201172                System.exit(0);
    202173        }
  • applications/editors/josm/plugins/seachart/src/render/Rules.java

    r32093 r32095  
    183183                }
    184184                return false;
     185        }
     186       
     187        static boolean hasObject(Obj obj) {
     188                return (feature.objs.containsKey(obj));
    185189        }
    186190       
     
    246250                        if (testObject(Obj.CRANES)) for (Feature f : objects) if (testFeature(f)) ports();
    247251                        if (testObject(Obj.LNDMRK)) for (Feature f : objects) if (testFeature(f)) landmarks();
     252                        if (testObject(Obj.SILTNK)) for (Feature f : objects) if (testFeature(f)) landmarks();
    248253                        if (testObject(Obj.BUISGL)) for (Feature f : objects) if (testFeature(f)) harbours();
    249254                        if (testObject(Obj.MORFAC)) for (Feature f : objects) if (testFeature(f)) moorings();
     
    438443        @SuppressWarnings("unchecked")
    439444        private static void beacons() {
    440                 if ((Renderer.zoom >= 14) || ((Renderer.zoom >= 12) && ((feature.type == Obj.BCNLAT) || (feature.type == Obj.BCNCAR)))) {
     445                if ((Renderer.zoom >= 14) || ((Renderer.zoom >= 12) && ((feature.type == Obj.BCNLAT) || (feature.type == Obj.BCNCAR)))
     446                                || ((Renderer.zoom >= 11) && ((feature.type == Obj.BCNSAW) || hasObject(Obj.RTPBCN)))) {
    441447                        BcnSHP shape = (BcnSHP)getAttEnum(feature.type, Att.BCNSHP);
    442448                        if (shape == BcnSHP.BCN_UNKN)
     
    485491        @SuppressWarnings("unchecked")
    486492        private static void buoys() {
    487                 if ((Renderer.zoom >= 14) || ((Renderer.zoom >= 12) && ((feature.type == Obj.BOYLAT) || (feature.type == Obj.BOYCAR)))) {
     493                if ((Renderer.zoom >= 14) || ((Renderer.zoom >= 12) && ((feature.type == Obj.BOYLAT) || (feature.type == Obj.BOYCAR)))
     494                                || ((Renderer.zoom >= 11) && ((feature.type == Obj.BOYSAW) || hasObject(Obj.RTPBCN)))) {
    488495                        BoySHP shape = (BoySHP) getAttEnum(feature.type, Att.BOYSHP);
    489496                        if (shape == BoySHP.BOY_UNKN) shape = BoySHP.BOY_PILR;
     
    630637        @SuppressWarnings("unchecked")
    631638        private static void floats() {
    632                 if (Renderer.zoom >= 12) {
     639                if ((Renderer.zoom >= 12) || ((Renderer.zoom >= 11) && ((feature.type == Obj.LITVES) || (feature.type == Obj.BOYINB) || hasObject(Obj.RTPBCN)))) {
    633640                        switch (feature.type) {
    634641                        case LITVES:
     
    819826        @SuppressWarnings("unchecked")
    820827        private static void landmarks() {
     828                if (testAttribute(Obj.LNDMRK, Att.CATLMK, CatLMK.LMK_UNKN)
     829                                && (testAttribute(Obj.LNDMRK, Att.CATLMK, FncFNC.FNC_UNKN) || testAttribute(Obj.LNDMRK, Att.CATLMK, FncFNC.FNC_LGHT))
     830                                && hasObject(Obj.LIGHTS))
     831                        lights();
    821832                if (Renderer.zoom >= 12) {
     833                        switch (feature.type) {
     834                        case LNDMRK:
    822835                        ArrayList<CatLMK> cats = (ArrayList<CatLMK>) getAttList(feature.type, Att.CATLMK);
    823836                        Symbol catSym = Landmarks.Shapes.get(cats.get(0));
     
    826839                        if ((fncs.get(0) == FncFNC.FNC_CHCH) && (cats.get(0) == CatLMK.LMK_TOWR))
    827840                                catSym = Landmarks.ChurchTower;
    828                         if ((cats.get(0) == CatLMK.LMK_UNKN) && (fncs.get(0) == FncFNC.FNC_UNKN) && (feature.objs.get(Obj.LIGHTS) != null))
    829                                 catSym = Beacons.LightMajor;
    830841                        if (cats.get(0) == CatLMK.LMK_RADR)
    831842                                fncSym = Landmarks.RadioTV;
    832843                        Renderer.symbol(catSym);
    833844                        Renderer.symbol(fncSym);
     845                        break;
     846                        case SILTNK:
     847                                if (testAttribute(feature.type, Att.CATSIL, CatSIL.SIL_WTRT))
     848                                        Renderer.symbol(Landmarks.WaterTower);
     849                                break;
     850                        default:
     851                                break;
     852                        }
    834853                        if (Renderer.zoom >= 15)
    835854                                addName(15, new Font("Arial", Font.BOLD, 40), new Delta(Handle.BL, AffineTransform.getTranslateInstance(60, -50)));
     
    840859        @SuppressWarnings("unchecked")
    841860        private static void lights() {
     861                boolean ok = false;
    842862                switch (feature.type) {
    843863                case LITMAJ:
     864                case LNDMRK:
    844865                        Renderer.symbol(Beacons.LightMajor);
     866                        ok = true;
    845867                        break;
    846868                case LITMIN:
    847869                case LIGHTS:
    848                         Renderer.symbol(Beacons.LightMinor);
     870                        if (Renderer.zoom >= 14) {
     871                                Renderer.symbol(Beacons.LightMinor);
     872                                ok = true;
     873                        }
    849874                        break;
    850875                case PILPNT:
    851                         if (feature.objs.containsKey(Obj.LIGHTS))
    852                                 Renderer.symbol(Beacons.LightMinor);
    853                         else
    854                                 Renderer.symbol(Harbours.Post);
     876                        if (Renderer.zoom >= 14) {
     877                                if (feature.objs.containsKey(Obj.LIGHTS))
     878                                        Renderer.symbol(Beacons.LightMinor);
     879                                else
     880                                        Renderer.symbol(Harbours.Post);
     881                                ok = true;
     882                        }
    855883                        break;
    856884                default:
    857885                        break;
    858886                }
    859                 if (feature.objs.containsKey(Obj.TOPMAR)) {
    860                         AttMap topmap = feature.objs.get(Obj.TOPMAR).get(0);
    861                         if (topmap.containsKey(Att.TOPSHP)) {
    862                                 Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>)(topmap.get(Att.TOPSHP).val)).get(0)), getScheme(Obj.TOPMAR), Topmarks.LightDelta);
    863                         }
    864                 } else  if (feature.objs.containsKey(Obj.DAYMAR)) {
    865                         AttMap topmap = feature.objs.get(Obj.DAYMAR).get(0);
    866                         if (topmap.containsKey(Att.TOPSHP)) {
    867                                 Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>)(topmap.get(Att.TOPSHP).val)).get(0)), getScheme(Obj.DAYMAR), Topmarks.LightDelta);
    868                         }
    869                 }
    870                 Signals.addSignals();
     887                if (ok) {
     888                        if (feature.objs.containsKey(Obj.TOPMAR)) {
     889                                AttMap topmap = feature.objs.get(Obj.TOPMAR).get(0);
     890                                if (topmap.containsKey(Att.TOPSHP)) {
     891                                        Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>) (topmap.get(Att.TOPSHP).val)).get(0)), getScheme(Obj.TOPMAR), Topmarks.LightDelta);
     892                                }
     893                        } else if (feature.objs.containsKey(Obj.DAYMAR)) {
     894                                AttMap topmap = feature.objs.get(Obj.DAYMAR).get(0);
     895                                if (topmap.containsKey(Att.TOPSHP)) {
     896                                        Renderer.symbol(Topmarks.Shapes.get(((ArrayList<TopSHP>) (topmap.get(Att.TOPSHP).val)).get(0)), getScheme(Obj.DAYMAR), Topmarks.LightDelta);
     897                                }
     898                        }
     899                        Signals.addSignals();
     900                }
    871901        }
    872902
  • applications/editors/josm/plugins/seachart/src/render/Signals.java

    r32093 r32095  
    2828import symbols.Symbols.*;
    2929
    30 public class Signals {
     30public class Signals extends Rules{
    3131
    3232        static final EnumMap<ColCOL, Color> LightColours = new EnumMap<ColCOL, Color>(ColCOL.class);
     
    101101       
    102102        public static void addSignals() {
    103           if (Rules.feature.objs.containsKey(Obj.RADRFL)) reflectors();
    104           if (Rules.feature.objs.containsKey(Obj.FOGSIG)) fogSignals();
    105           if (Rules.feature.objs.containsKey(Obj.RTPBCN)) radarStations();
    106           if (Rules.feature.objs.containsKey(Obj.RADSTA)) radarStations();
    107           if (Rules.feature.objs.containsKey(Obj.RDOSTA)) radioStations();
    108           if (Rules.feature.objs.containsKey(Obj.LIGHTS)) lights();
     103          if (feature.objs.containsKey(Obj.RADRFL)) reflectors();
     104          if (feature.objs.containsKey(Obj.FOGSIG)) fogSignals();
     105          if (feature.objs.containsKey(Obj.RTPBCN)) radarStations();
     106          if (feature.objs.containsKey(Obj.RADSTA)) radarStations();
     107          if (feature.objs.containsKey(Obj.RDOSTA)) radioStations();
     108          if (feature.objs.containsKey(Obj.LIGHTS)) lights();
    109109        }
    110110
    111111        public static void reflectors() {
    112112                if (Renderer.zoom >= 14) {
    113                         switch (Rules.feature.type) {
     113                        switch (feature.type) {
    114114                        case BCNLAT:
    115115                        case BCNCAR:
     
    117117                        case BCNSAW:
    118118                        case BCNSPP:
    119                                 if ((Rules.feature.objs.containsKey(Obj.TOPMAR)) || (Rules.feature.objs.containsKey(Obj.DAYMAR))) {
     119                                if ((feature.objs.containsKey(Obj.TOPMAR)) || (feature.objs.containsKey(Obj.DAYMAR))) {
    120120                                        Renderer.symbol(Topmarks.RadarReflector, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -140)));
    121121                                } else {
     
    126126                        case LITVES:
    127127                        case BOYINB:
    128                                 if ((Rules.feature.objs.containsKey(Obj.TOPMAR)) || (Rules.feature.objs.containsKey(Obj.DAYMAR))) {
     128                                if ((feature.objs.containsKey(Obj.TOPMAR)) || (feature.objs.containsKey(Obj.DAYMAR))) {
    129129                                        Renderer.symbol(Topmarks.RadarReflector, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -110)));
    130130                                } else {
     
    134134                        case LITMAJ:
    135135                        case LITMIN:
    136                                 if ((Rules.feature.objs.containsKey(Obj.TOPMAR)) || (Rules.feature.objs.containsKey(Obj.DAYMAR))) {
     136                                if ((feature.objs.containsKey(Obj.TOPMAR)) || (feature.objs.containsKey(Obj.DAYMAR))) {
    137137                                        Renderer.symbol(Topmarks.RadarReflector, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -90)));
    138138                                } else {
     
    145145                        case BOYSAW:
    146146                        case BOYSPP:
    147                                 if ((Rules.feature.objs.containsKey(Obj.TOPMAR)) || (Rules.feature.objs.containsKey(Obj.DAYMAR))) {
    148                                         if (Rules.testAttribute(Rules.feature.type, Att.BOYSHP, BoySHP.BOY_PILR) || Rules.testAttribute(Rules.feature.type, Att.BOYSHP, BoySHP.BOY_SPAR)) {
     147                                if ((feature.objs.containsKey(Obj.TOPMAR)) || (feature.objs.containsKey(Obj.DAYMAR))) {
     148                                        if (testAttribute(feature.type, Att.BOYSHP, BoySHP.BOY_PILR) || testAttribute(feature.type, Att.BOYSHP, BoySHP.BOY_SPAR)) {
    149149                                                Renderer.symbol(Topmarks.RadarReflector, new Delta(Handle.BC, AffineTransform.getTranslateInstance(50, -160)));
    150150                                        } else {
     
    152152                                        }
    153153                                } else {
    154                                         if (Rules.testAttribute(Rules.feature.type, Att.BOYSHP, BoySHP.BOY_PILR) || Rules.testAttribute(Rules.feature.type, Att.BOYSHP, BoySHP.BOY_SPAR)) {
     154                                        if (testAttribute(feature.type, Att.BOYSHP, BoySHP.BOY_PILR) || testAttribute(feature.type, Att.BOYSHP, BoySHP.BOY_SPAR)) {
    155155                                                Renderer.symbol(Topmarks.RadarReflector, new Delta(Handle.BC, AffineTransform.getTranslateInstance(30, -100)));
    156156                                        } else {
     
    169169                        Renderer.symbol(Beacons.FogSignal);
    170170                if (Renderer.zoom >= 15) {
    171                         AttMap atts = Rules.feature.objs.get(Obj.FOGSIG).get(0);
     171                        AttMap atts = feature.objs.get(Obj.FOGSIG).get(0);
    172172                        if (atts != null) {
    173173                                String str = "";
     
    198198                if (Renderer.zoom >= 15) {
    199199                        String bstr = "";
    200                         CatRTB cat = (CatRTB) Rules.getAttEnum(Obj.RTPBCN, Att.CATRTB);
    201                         String wal = Rules.getAttStr(Obj.RTPBCN, Att.RADWAL);
     200                        CatRTB cat = (CatRTB) getAttEnum(Obj.RTPBCN, Att.CATRTB);
     201                        String wal = getAttStr(Obj.RTPBCN, Att.RADWAL);
    202202                        switch (cat) {
    203203                        case RTB_RAMK:
     
    206206                        case RTB_RACN:
    207207                                bstr += " Racon";
    208                                 String astr = Rules.getAttStr(Obj.RTPBCN, Att.SIGGRP);
     208                                String astr = getAttStr(Obj.RTPBCN, Att.SIGGRP);
    209209                                if (!astr.isEmpty()) {
    210210                                        bstr += "(" + astr + ")";
    211211                                }
    212                                 Double per = (Double) Rules.getAttVal(Obj.RTPBCN, Att.SIGPER);
    213                                 Double mxr = (Double) Rules.getAttVal(Obj.RTPBCN, Att.VALMXR);
     212                                Double per = (Double) getAttVal(Obj.RTPBCN, Att.SIGPER);
     213                                Double mxr = (Double) getAttVal(Obj.RTPBCN, Att.VALMXR);
    214214                                if ((per != null) || (mxr != null)) {
    215215                                        bstr += (astr.isEmpty() ? " " : "");
     
    244244                String bstr = "";
    245245                if (Renderer.zoom >= 11) {
    246                         ArrayList<CatROS> cats = (ArrayList<CatROS>) Rules.getAttList(Obj.RDOSTA, Att.CATROS);
     246                        ArrayList<CatROS> cats = (ArrayList<CatROS>) getAttList(Obj.RDOSTA, Att.CATROS);
    247247                        for (CatROS ros : cats) {
    248248                                switch (ros) {
     
    373373                Enum<ColCOL> col = null;
    374374                Enum<ColCOL> tcol = null;
    375                 ObjTab lights = Rules.feature.objs.get(Obj.LIGHTS);
     375                ObjTab lights = feature.objs.get(Obj.LIGHTS);
    376376                for (AttMap atts : lights.values()) {
    377377                        if (atts.containsKey(Att.COLOUR)) {
     
    392392                }
    393393                Renderer.symbol(Beacons.LightFlare, new Scheme(LightColours.get(col)), new Delta(Handle.BC, AffineTransform.getRotateInstance(Math.toRadians(120))));
     394                if (Renderer.zoom >= 12) {
    394395                        String str = "";
    395396                        if (lights.get(1) != null) {
     
    424425                                                                        double ss2 = 361;
    425426                                                                        Double sdir = null;
    426                                                                         if (satts == atts) continue;
     427                                                                        if (satts == atts)
     428                                                                                continue;
    427429                                                                        if (satts.containsKey(Att.LITRAD)) {
    428430                                                                                srad = (Double) satts.get(Att.LITRAD).val;
     
    444446                                                                                        }
    445447                                                                                }
    446                                                                                 if ((ss1 > 360) || (ss2 > 360)) continue;
     448                                                                                if ((ss1 > 360) || (ss2 > 360))
     449                                                                                        continue;
    447450                                                                                if (sdir != null) {
    448451                                                                                        if (((dir - sdir + 360) % 360) < 8) {
     
    496499                                                Renderer.lightSector(LightColours.get(col1), LightColours.get(col2), radius, s1, s2, dir, (Renderer.zoom >= 15) ? str : "");
    497500                                }
    498                         if (Renderer.zoom >= 15) {
    499                                 class LitSect {
    500                                         boolean dir;
    501                                         LitCHR chr;
    502                                         ColCOL col;
    503                                         String grp;
    504                                         double per;
    505                                         double rng;
    506                                         double hgt;
    507                                 }
    508                                 ArrayList<LitSect> litatts = new ArrayList<>();
    509                                 for (AttMap atts : lights.values()) {
    510                                         LitSect sect = new LitSect();
    511                                         sect.dir = (atts.containsKey(Att.CATLIT) && ((ArrayList<CatLIT>)atts.get(Att.CATLIT).val).contains(CatLIT.LIT_DIR));
    512                                         sect.chr = atts.containsKey(Att.LITCHR) ? ((ArrayList<LitCHR>) atts.get(Att.LITCHR).val).get(0) : LitCHR.CHR_UNKN;
    513                                         switch (sect.chr) {
    514                                         case CHR_AL:
    515                                                 sect.chr = LitCHR.CHR_F;
    516                                                 break;
    517                                         case CHR_ALOC:
    518                                                 sect.chr = LitCHR.CHR_OC;
    519                                                 break;
    520                                         case CHR_ALLFL:
    521                                                 sect.chr = LitCHR.CHR_LFL;
    522                                                 break;
    523                                         case CHR_ALFL:
    524                                                 sect.chr = LitCHR.CHR_FL;
    525                                                 break;
    526                                         case CHR_ALFFL:
    527                                                 sect.chr = LitCHR.CHR_FFL;
    528                                                 break;
    529                                         default:
    530                                                 break;
    531                                         }
    532                                         sect.grp = atts.containsKey(Att.SIGGRP) ? (String) atts.get(Att.SIGGRP).val : "";
    533                                         sect.per = atts.containsKey(Att.SIGPER) ? (Double) atts.get(Att.SIGPER).val : 0.0;
    534                                         sect.rng = atts.containsKey(Att.VALNMR) ? (Double) atts.get(Att.VALNMR).val : 0.0;
    535                                         sect.hgt = atts.containsKey(Att.HEIGHT) ? (Double) atts.get(Att.HEIGHT).val : 0.0;
    536                                         ArrayList<ColCOL> cols = (ArrayList<ColCOL>) (atts.containsKey(Att.COLOUR) ? atts.get(Att.COLOUR).val : new ArrayList<>());
    537                                         sect.col = cols.size() > 0 ? cols.get(0) : ColCOL.COL_UNK;
    538                                         if ((sect.chr != LitCHR.CHR_UNKN) && (sect.col != null))
    539                                                 litatts.add(sect);
    540                                 }
    541                                 ArrayList<ArrayList<LitSect>> groupings = new ArrayList<>();
    542                                 for (LitSect lit : litatts) {
    543                                         boolean found = false;
    544                                         for (ArrayList<LitSect> group : groupings) {
    545                                                 LitSect mem = group.get(0);
    546                                                 if ((lit.dir == mem.dir) && (lit.chr == mem.chr) && (lit.grp.equals(mem.grp)) && (lit.per == mem.per) && (lit.hgt == mem.hgt)) {
    547                                                         group.add(lit);
    548                                                         found = true;
    549                                                 }
    550                                         }
    551                                         if (!found) {
    552                                                 ArrayList<LitSect> tmp = new ArrayList<LitSect>();
    553                                                 tmp.add(lit);
    554                                                 groupings.add(tmp);
    555                                         }
    556                                 }
    557                                 for (boolean moved = true; moved;) {
    558                                         moved = false;
    559                                         for (int i = 0; i < groupings.size() - 1; i++) {
    560                                                 if (groupings.get(i).size() < groupings.get(i + 1).size()) {
    561                                                         ArrayList<LitSect> tmp = groupings.remove(i);
    562                                                         groupings.add(i + 1, tmp);
    563                                                         moved = true;
    564                                                 }
    565                                         }
    566                                 }
    567                                 class ColRng {
    568                                         ColCOL col;
    569                                         double rng;
    570 
    571                                         public ColRng(ColCOL c, double r) {
    572                                                 col = c;
    573                                                 rng = r;
    574                                         }
    575                                 }
    576                                 int y = -30;
    577                                 for (ArrayList<LitSect> group : groupings) {
    578                                         ArrayList<ColRng> colrng = new ArrayList<>();
    579                                         for (LitSect lit : group) {
     501                                if (Renderer.zoom >= 15) {
     502                                        class LitSect {
     503                                                boolean dir;
     504                                                LitCHR chr;
     505                                                ColCOL col;
     506                                                String grp;
     507                                                double per;
     508                                                double rng;
     509                                                double hgt;
     510                                        }
     511                                        ArrayList<LitSect> litatts = new ArrayList<>();
     512                                        for (AttMap atts : lights.values()) {
     513                                                LitSect sect = new LitSect();
     514                                                sect.dir = (atts.containsKey(Att.CATLIT) && ((ArrayList<CatLIT>) atts.get(Att.CATLIT).val).contains(CatLIT.LIT_DIR));
     515                                                sect.chr = atts.containsKey(Att.LITCHR) ? ((ArrayList<LitCHR>) atts.get(Att.LITCHR).val).get(0) : LitCHR.CHR_UNKN;
     516                                                switch (sect.chr) {
     517                                                case CHR_AL:
     518                                                        sect.chr = LitCHR.CHR_F;
     519                                                        break;
     520                                                case CHR_ALOC:
     521                                                        sect.chr = LitCHR.CHR_OC;
     522                                                        break;
     523                                                case CHR_ALLFL:
     524                                                        sect.chr = LitCHR.CHR_LFL;
     525                                                        break;
     526                                                case CHR_ALFL:
     527                                                        sect.chr = LitCHR.CHR_FL;
     528                                                        break;
     529                                                case CHR_ALFFL:
     530                                                        sect.chr = LitCHR.CHR_FFL;
     531                                                        break;
     532                                                default:
     533                                                        break;
     534                                                }
     535                                                sect.grp = atts.containsKey(Att.SIGGRP) ? (String) atts.get(Att.SIGGRP).val : "";
     536                                                sect.per = atts.containsKey(Att.SIGPER) ? (Double) atts.get(Att.SIGPER).val : 0.0;
     537                                                sect.rng = atts.containsKey(Att.VALNMR) ? (Double) atts.get(Att.VALNMR).val : 0.0;
     538                                                sect.hgt = atts.containsKey(Att.HEIGHT) ? (Double) atts.get(Att.HEIGHT).val : 0.0;
     539                                                ArrayList<ColCOL> cols = (ArrayList<ColCOL>) (atts.containsKey(Att.COLOUR) ? atts.get(Att.COLOUR).val : new ArrayList<>());
     540                                                sect.col = cols.size() > 0 ? cols.get(0) : ColCOL.COL_UNK;
     541                                                if ((sect.chr != LitCHR.CHR_UNKN) && (sect.col != null))
     542                                                        litatts.add(sect);
     543                                        }
     544                                        ArrayList<ArrayList<LitSect>> groupings = new ArrayList<>();
     545                                        for (LitSect lit : litatts) {
    580546                                                boolean found = false;
    581                                                 for (ColRng cr : colrng) {
    582                                                         if (cr.col == lit.col) {
    583                                                                 if (lit.rng > cr.rng) {
    584                                                                         cr.rng = lit.rng;
    585                                                                 }
     547                                                for (ArrayList<LitSect> group : groupings) {
     548                                                        LitSect mem = group.get(0);
     549                                                        if ((lit.dir == mem.dir) && (lit.chr == mem.chr) && (lit.grp.equals(mem.grp)) && (lit.per == mem.per) && (lit.hgt == mem.hgt)) {
     550                                                                group.add(lit);
    586551                                                                found = true;
    587552                                                        }
    588553                                                }
    589554                                                if (!found) {
    590                                                         colrng.add(new ColRng(lit.col, lit.rng));
     555                                                        ArrayList<LitSect> tmp = new ArrayList<LitSect>();
     556                                                        tmp.add(lit);
     557                                                        groupings.add(tmp);
    591558                                                }
    592559                                        }
    593560                                        for (boolean moved = true; moved;) {
    594561                                                moved = false;
    595                                                 for (int i = 0; i < colrng.size() - 1; i++) {
    596                                                         if (colrng.get(i).rng < colrng.get(i + 1).rng) {
    597                                                                 ColRng tmp = colrng.remove(i);
    598                                                                 colrng.add(i + 1, tmp);
     562                                                for (int i = 0; i < groupings.size() - 1; i++) {
     563                                                        if (groupings.get(i).size() < groupings.get(i + 1).size()) {
     564                                                                ArrayList<LitSect> tmp = groupings.remove(i);
     565                                                                groupings.add(i + 1, tmp);
    599566                                                                moved = true;
    600567                                                        }
    601568                                                }
    602569                                        }
    603                                         LitSect tmp = group.get(0);
    604                                         str = (tmp.dir) ? "Dir" : "";
    605                                         str += LightCharacters.get(tmp.chr);
    606                                         if (!tmp.grp.isEmpty())
    607                                                 str += "(" + tmp.grp + ")";
    608                                         else
    609                                                 str += ".";
    610                                         for (ColRng cr : colrng) {
    611                                                 str += LightLetters.get(cr.col);
    612                                         }
    613                                         if ((tmp.per > 0) || (tmp.hgt > 0) || (colrng.get(0).rng > 0))
    614                                                 str += ".";
    615                                         if (tmp.per > 0)
    616                                                 str += df.format(tmp.per) + "s";
    617                                         if (tmp.hgt > 0)
    618                                                 str += df.format(tmp.hgt) + "m";
    619                                         if (colrng.get(0).rng > 0)
    620                                                 str += df.format(colrng.get(0).rng) + ((colrng.size() > 1) ? ((colrng.size() > 2) ? ("-" + df.format(colrng.get(colrng.size() - 1).rng)) : ("/" + df.format(colrng.get(1).rng))) : "") + "M";
    621                                         Renderer.labelText(str, new Font("Arial", Font.PLAIN, 40), Color.black, new Delta(Handle.TL, AffineTransform.getTranslateInstance(60, y)));
    622                                         y += 40;
    623                                         str = "";
    624                                 }
    625                         }
    626                 } else {
    627                         if (Renderer.zoom >= 15) {
    628                                 AttMap atts = lights.get(0);
    629                                 ArrayList<CatLIT> cats = new ArrayList<>();
    630                                 if (atts.containsKey(Att.CATLIT)) {
    631                                         cats = (ArrayList<CatLIT>) atts.get(Att.CATLIT).val;
    632                                 }
    633                                 str = (cats.contains(CatLIT.LIT_DIR)) ? "Dir" : "";
    634                                 str += (atts.containsKey(Att.MLTYLT)) ? atts.get(Att.MLTYLT).val : "";
    635                                 if (atts.containsKey(Att.LITCHR)) {
    636                                         LitCHR chr = ((ArrayList<LitCHR>) atts.get(Att.LITCHR).val).get(0);
    637                                         if (atts.containsKey(Att.SIGGRP)) {
    638                                                 String grp = (String) atts.get(Att.SIGGRP).val;
    639                                                 switch (chr) {
    640                                                 case CHR_QLFL:
    641                                                         str += String.format("Q(%s)+LFl", grp);
    642                                                         break;
    643                                                 case CHR_VQLFL:
    644                                                         str += String.format("VQ(%s)+LFl", grp);
    645                                                         break;
    646                                                 case CHR_UQLFL:
    647                                                         str += String.format("UQ(%s)+LFl", grp);
    648                                                         break;
    649                                                 default:
    650                                                         str += String.format("%s(%s)", LightCharacters.get(chr), grp);
    651                                                         break;
    652                                                 }
    653                                         } else {
    654                                                 str += LightCharacters.get(chr);
    655                                         }
    656                                 }
    657                                 if (atts.containsKey(Att.COLOUR)) {
    658                                         ArrayList<ColCOL> cols = (ArrayList<ColCOL>) atts.get(Att.COLOUR).val;
    659                                         if (!((cols.size() == 1) && (cols.get(0) == ColCOL.COL_WHT))) {
    660                                                 if (!str.isEmpty() && !str.endsWith(")")) {
     570                                        class ColRng {
     571                                                ColCOL col;
     572                                                double rng;
     573
     574                                                public ColRng(ColCOL c, double r) {
     575                                                        col = c;
     576                                                        rng = r;
     577                                                }
     578                                        }
     579                                        int y = -30;
     580                                        for (ArrayList<LitSect> group : groupings) {
     581                                                ArrayList<ColRng> colrng = new ArrayList<>();
     582                                                for (LitSect lit : group) {
     583                                                        boolean found = false;
     584                                                        for (ColRng cr : colrng) {
     585                                                                if (cr.col == lit.col) {
     586                                                                        if (lit.rng > cr.rng) {
     587                                                                                cr.rng = lit.rng;
     588                                                                        }
     589                                                                        found = true;
     590                                                                }
     591                                                        }
     592                                                        if (!found) {
     593                                                                colrng.add(new ColRng(lit.col, lit.rng));
     594                                                        }
     595                                                }
     596                                                for (boolean moved = true; moved;) {
     597                                                        moved = false;
     598                                                        for (int i = 0; i < colrng.size() - 1; i++) {
     599                                                                if (colrng.get(i).rng < colrng.get(i + 1).rng) {
     600                                                                        ColRng tmp = colrng.remove(i);
     601                                                                        colrng.add(i + 1, tmp);
     602                                                                        moved = true;
     603                                                                }
     604                                                        }
     605                                                }
     606                                                LitSect tmp = group.get(0);
     607                                                str = (tmp.dir) ? "Dir" : "";
     608                                                str += LightCharacters.get(tmp.chr);
     609                                                if (!tmp.grp.isEmpty())
     610                                                        str += "(" + tmp.grp + ")";
     611                                                else
    661612                                                        str += ".";
    662                                                 }
    663                                                 for (ColCOL acol : cols) {
    664                                                         str += LightLetters.get(acol);
    665                                                 }
    666                                         }
    667                                 }
    668                                 str += (cats.contains(CatLIT.LIT_VERT)) ? "(vert)" : "";
    669                                 str += (cats.contains(CatLIT.LIT_HORI)) ? "(hor)" : "";
    670                                 str += (!str.isEmpty() && (atts.containsKey(Att.SIGPER) || atts.containsKey(Att.HEIGHT) || atts.containsKey(Att.VALMXR)) && !str.endsWith(")")) ? "." : "";
    671                                 str += (atts.containsKey(Att.SIGPER)) ? df.format(atts.get(Att.SIGPER).val) + "s" : "";
    672                                 str += (atts.containsKey(Att.HEIGHT)) ? df.format(atts.get(Att.HEIGHT).val) + "m" : "";
    673                                 str += (atts.containsKey(Att.VALNMR)) ? df.format(atts.get(Att.VALNMR).val) + "M" : "";
    674                                 str += (cats.contains(CatLIT.LIT_FRNT)) ? "(Front)" : "";
    675                                 str += (cats.contains(CatLIT.LIT_REAR)) ? "(Rear)" : "";
    676                                 str += (cats.contains(CatLIT.LIT_UPPR)) ? "(Upper)" : "";
    677                                 str += (cats.contains(CatLIT.LIT_LOWR)) ? "(Lower)" : "";
    678                                 Renderer.labelText(str, new Font("Arial", Font.PLAIN, 40), Color.black, new Delta(Handle.TL, AffineTransform.getTranslateInstance(60, -30)));
     613                                                for (ColRng cr : colrng) {
     614                                                        str += LightLetters.get(cr.col);
     615                                                }
     616                                                if ((tmp.per > 0) || (tmp.hgt > 0) || (colrng.get(0).rng > 0))
     617                                                        str += ".";
     618                                                if (tmp.per > 0)
     619                                                        str += df.format(tmp.per) + "s";
     620                                                if (tmp.hgt > 0)
     621                                                        str += df.format(tmp.hgt) + "m";
     622                                                if (colrng.get(0).rng > 0)
     623                                                        str += df.format(colrng.get(0).rng) + ((colrng.size() > 1) ? ((colrng.size() > 2) ? ("-" + df.format(colrng.get(colrng.size() - 1).rng)) : ("/" + df.format(colrng.get(1).rng))) : "") + "M";
     624                                                Renderer.labelText(str, new Font("Arial", Font.PLAIN, 40), Color.black, new Delta(Handle.TL, AffineTransform.getTranslateInstance(60, y)));
     625                                                y += 40;
     626                                                str = "";
     627                                        }
     628                                }
     629                        } else {
     630                                if (Renderer.zoom >= 15) {
     631                                        AttMap atts = lights.get(0);
     632                                        ArrayList<CatLIT> cats = new ArrayList<>();
     633                                        if (atts.containsKey(Att.CATLIT)) {
     634                                                cats = (ArrayList<CatLIT>) atts.get(Att.CATLIT).val;
     635                                        }
     636                                        str = (cats.contains(CatLIT.LIT_DIR)) ? "Dir" : "";
     637                                        str += (atts.containsKey(Att.MLTYLT)) ? atts.get(Att.MLTYLT).val : "";
     638                                        if (atts.containsKey(Att.LITCHR)) {
     639                                                LitCHR chr = ((ArrayList<LitCHR>) atts.get(Att.LITCHR).val).get(0);
     640                                                if (atts.containsKey(Att.SIGGRP)) {
     641                                                        String grp = (String) atts.get(Att.SIGGRP).val;
     642                                                        switch (chr) {
     643                                                        case CHR_QLFL:
     644                                                                str += String.format("Q(%s)+LFl", grp);
     645                                                                break;
     646                                                        case CHR_VQLFL:
     647                                                                str += String.format("VQ(%s)+LFl", grp);
     648                                                                break;
     649                                                        case CHR_UQLFL:
     650                                                                str += String.format("UQ(%s)+LFl", grp);
     651                                                                break;
     652                                                        default:
     653                                                                str += String.format("%s(%s)", LightCharacters.get(chr), grp);
     654                                                                break;
     655                                                        }
     656                                                } else {
     657                                                        str += LightCharacters.get(chr);
     658                                                }
     659                                        }
     660                                        if (atts.containsKey(Att.COLOUR)) {
     661                                                ArrayList<ColCOL> cols = (ArrayList<ColCOL>) atts.get(Att.COLOUR).val;
     662                                                if (!((cols.size() == 1) && (cols.get(0) == ColCOL.COL_WHT))) {
     663                                                        if (!str.isEmpty() && !str.endsWith(")")) {
     664                                                                str += ".";
     665                                                        }
     666                                                        for (ColCOL acol : cols) {
     667                                                                str += LightLetters.get(acol);
     668                                                        }
     669                                                }
     670                                        }
     671                                        str += (cats.contains(CatLIT.LIT_VERT)) ? "(vert)" : "";
     672                                        str += (cats.contains(CatLIT.LIT_HORI)) ? "(hor)" : "";
     673                                        str += (!str.isEmpty() && (atts.containsKey(Att.SIGPER) || atts.containsKey(Att.HEIGHT) || atts.containsKey(Att.VALMXR)) && !str.endsWith(")")) ? "." : "";
     674                                        str += (atts.containsKey(Att.SIGPER)) ? df.format(atts.get(Att.SIGPER).val) + "s" : "";
     675                                        str += (atts.containsKey(Att.HEIGHT)) ? df.format(atts.get(Att.HEIGHT).val) + "m" : "";
     676                                        str += (atts.containsKey(Att.VALNMR)) ? df.format(atts.get(Att.VALNMR).val) + "M" : "";
     677                                        str += (cats.contains(CatLIT.LIT_FRNT)) ? "(Front)" : "";
     678                                        str += (cats.contains(CatLIT.LIT_REAR)) ? "(Rear)" : "";
     679                                        str += (cats.contains(CatLIT.LIT_UPPR)) ? "(Upper)" : "";
     680                                        str += (cats.contains(CatLIT.LIT_LOWR)) ? "(Lower)" : "";
     681                                        Renderer.labelText(str, new Font("Arial", Font.PLAIN, 40), Color.black, new Delta(Handle.TL, AffineTransform.getTranslateInstance(60, -30)));
     682                                }
    679683                        }
    680684                }
  • applications/editors/josm/plugins/seachart/src/s57/S57val.java

    r32082 r32095  
    216216 }
    217217 public enum CatLMK { LMK_UNKN, LMK_CARN, LMK_CMTY, LMK_CHMY, LMK_DISH, LMK_FLAG, LMK_FLAR, LMK_MAST, LMK_WNDS, LMK_MNMT, LMK_CLMN, LMK_MEML, LMK_OBLK, LMK_STAT, LMK_CROS,
    218   LMK_DOME, LMK_RADR, LMK_TOWR, LMK_WNDM, LMK_WNDG, LMK_SPIR, LMK_BLDR, LMK_MNRT, LMK_WTRT }
     218  LMK_DOME, LMK_RADR, LMK_TOWR, LMK_WNDM, LMK_WNDG, LMK_SPIR, LMK_BLDR }
    219219 private static final EnumMap<CatLMK, S57enum> Catlmk = new EnumMap<>(CatLMK.class); static {Catlmk.put(CatLMK.LMK_UNKN, new S57enum(0, ""));
    220220  Catlmk.put(CatLMK.LMK_CARN, new S57enum(1, "cairn")); Catlmk.put(CatLMK.LMK_CMTY, new S57enum(2, "cemetery")); Catlmk.put(CatLMK.LMK_CHMY, new S57enum(3, "chimney"));
  • applications/editors/josm/plugins/seachart/src/seachart/ChartImage.java

    r32082 r32095  
    7171                g2.setPaint(Color.black);
    7272                g2.setFont(new Font("Arial", Font.BOLD, 20));
    73                 g2.drawString(("Z" + zoom), (rect.x + rect.width - 40), (rect.y + rect.height - 10));
     73                Rectangle crect = g2.getClipBounds();
     74                if ((crect.y + crect.height) < (rect.y + rect.height - 10)) {
     75                        g2.drawString(("Z" + zoom), (crect.x + crect.width - 40), (crect.y + crect.height - 10));
     76                } else {
     77                        g2.drawString(("Z" + zoom), (rect.x + rect.width - 40), (rect.y + rect.height - 10));
     78                }
    7479        }
    7580
  • applications/editors/josm/plugins/seachart/src/symbols/Landmarks.java

    r30894 r32095  
    196196                Shapes.put(CatLMK.LMK_RADR, Landmarks.Mast); Shapes.put(CatLMK.LMK_TOWR, Landmarks.LandTower); Shapes.put(CatLMK.LMK_WNDM, Landmarks.Windmill);
    197197                Shapes.put(CatLMK.LMK_WNDG, Landmarks.WindMotor); Shapes.put(CatLMK.LMK_SPIR, Landmarks.Spire); Shapes.put(CatLMK.LMK_BLDR, Beacons.Cairn);
    198                 Shapes.put(CatLMK.LMK_MNRT, Landmarks.Minaret); Shapes.put(CatLMK.LMK_WTRT, Landmarks.WaterTower);
    199198        }
    200199
Note: See TracChangeset for help on using the changeset viewer.