⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 proj.java

📁 openmap java写的开源数字地图程序. 用applet实现,可以像google map 那样放大缩小地图.
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
     * Circles have the same restrictions as <a     * href="#poly_restrictions"> polys </a>.     *      * @param c LatLonPoint center of circle     * @param radians radius in radians or decimal degrees?     * @param radius radius of circle (0 &lt; radius &lt; 180)     * @param nverts number of vertices of the circle poly.     * @param isFilled filled poly?     */    public ArrayList forwardCircle(LatLonPoint c, boolean radians,                                   float radius, int nverts, boolean isFilled) {        // HACK-need better decision for number of vertices.        if (nverts < 3)            nverts = NUM_DEFAULT_CIRCLE_VERTS;        float[] rawllpts = new float[(nverts << 1) + 2];// *2 for        // pairs +2        // connect        GreatCircle.earth_circle(c.radlat_, c.radlon_, (radians) ? radius                : ProjMath.degToRad(radius), nverts, rawllpts);        // connect the vertices.        rawllpts[rawllpts.length - 2] = rawllpts[0];        rawllpts[rawllpts.length - 1] = rawllpts[1];        // forward project the circle-poly        return forwardPoly(rawllpts, LineType.Straight, -1, isFilled);    }    // HACK    protected transient static int XTHRESHOLD = 16384;// half range    protected transient int XSCALE_THRESHOLD = 1000000;// dynamically    // calculated    public ArrayList forwardPoly(float[] rawllpts, int ltype, int nsegs) {        return forwardPoly(rawllpts, ltype, nsegs, false);    }    /**     * Forward project a lat/lon Poly.     * <p>     * Delegates to _forwardPoly(), and may do additional clipping for     * Java XWindows problem. Remember to specify vertices in radians!     *      * @param rawllpts float[] of lat,lon,lat,lon,... in RADIANS!     * @param ltype line type (straight, rhumbline, greatcircle)     * @param nsegs number of segment points (only for greatcircle or     *        rhumbline line types, and if &lt; 1, this value is     *        generated internally)     * @param isFilled filled poly?     * @return ArrayList of x[], y[], x[], y[], ... projected poly     * @see #forwardRaw     * @see LineType#Straight     * @see LineType#Rhumb     * @see LineType#GreatCircle     */    public ArrayList forwardPoly(float[] rawllpts, int ltype, int nsegs,                                 boolean isFilled) {        ArrayList stuff = _forwardPoly(rawllpts, ltype, nsegs, isFilled);        // @HACK: workaround XWindows bug. simple clip to a boundary.        // this is ugly.        if (Environment.doingXWindowsWorkaround && (scale <= XSCALE_THRESHOLD)) {            int i, j, size = stuff.size();            int[] xpts, ypts;            for (i = 0; i < size; i += 2) {                xpts = (int[]) stuff.get(i);                ypts = (int[]) stuff.get(i + 1);                for (j = 0; j < xpts.length; j++) {                    if (xpts[j] <= -XTHRESHOLD) {                        xpts[j] = -XTHRESHOLD;                    } else if (xpts[j] >= XTHRESHOLD) {                        xpts[j] = XTHRESHOLD;                    }                    if (ypts[j] <= -XTHRESHOLD) {                        ypts[j] = -XTHRESHOLD;                    } else if (ypts[j] >= XTHRESHOLD) {                        ypts[j] = XTHRESHOLD;                    }                }                stuff.set(i, xpts);                stuff.set(i + 1, ypts);            }        }        return stuff;    }    /**     * Forward project a lat/lon Poly. Remember to specify vertices in     * radians!     *      * @param rawllpts float[] of lat,lon,lat,lon,... in RADIANS!     * @param ltype line type (straight, rhumbline, greatcircle)     * @param nsegs number of segment points (only for greatcircle or     *        rhumbline line types, and if &lt; 1, this value is     *        generated internally)     * @param isFilled filled poly?     * @return ArrayList of x[], y[], x[], y[], ... projected poly     */    protected abstract ArrayList _forwardPoly(float[] rawllpts, int ltype,                                              int nsegs, boolean isFilled);    /**     * Forward project a rhumbline poly.     * <p>     * Draws rhumb lines between vertices of poly. Remember to specify     * vertices in radians! Check in-code comments for details about     * the algorithm.     *      * @param rawllpts float[] of lat,lon,lat,lon,... in RADIANS!     * @param nsegs number of segments to draw for greatcircle or     *        rhumb lines (if &lt; 1, this value is generated     *        internally).     * @param isFilled filled poly?     * @return ArrayList of x[], y[], x[], y[], ... projected poly     * @see Projection#forwardPoly(float[], int, int, boolean)     */    protected ArrayList forwardRhumbPoly(float[] rawllpts, int nsegs,                                         boolean isFilled) {        // IDEA:        // Rhumblines are straight in the Mercator projection.        // So we can use the Mercator projection to calculate        // vertices along the rhumbline between two points. But        // if there's a better way to calculate loxodromes,        // someone please chime in (openmap@bbn.com)...        //        // ALG:        // Project pairs of vertices through the Mercator        // projection into screen XY space, pick intermediate        // segment points along the straight XY line, then        // convert all vertices back into LatLon space. Pass the        // augmented vertices to _forwardPoly() to be drawn as        // straight segments.        //        // WARNING:        // The algorithm fixes the Cylindrical-wrapping        // problem, and thus duplicates some code in        // Cylindrical._forwardPoly()        //        if (this instanceof Mercator) {// simple            return _forwardPoly(rawllpts, LineType.Straight, nsegs, isFilled);        }        int i, n, xp, flag = 0, xadj = 0, totalpts = 0;        Point from = new Point(0, 0);        Point to = new Point(0, 0);        LatLonPoint llp = null;        int len = rawllpts.length;        float[][] augllpts = new float[len >>> 1][0];        // lock access to object global, since this is probably not        // cloned and different layers may be accessing this.        // synchronized (mercator) {        // we now create a clone of the mercator variable in        // makeClone(), so since different objects should be using        // their clone instead of the main projection, the        // synchronization should be unneeded.        // use mercator projection to calculate rhumblines.        // mercator.setParms(        // new LatLonPoint(ctrLat, ctrLon, true),        // scale, width, height);        // Unnecessary to set parameters !! ^^^^^        // project everything through the Mercator projection,        // building up lat/lon points along the original rhumb        // line between vertices.        mercator.forward(rawllpts[0], rawllpts[1], from, true);        xp = from.x;        for (i = 0, n = 2; n < len; i++, n += 2) {            mercator.forward(rawllpts[n], rawllpts[n + 1], to, true);            // segment crosses longitude along screen edge            if (Math.abs(xp - to.x) >= mercator.half_world) {                flag += (xp < to.x) ? -1 : 1;// inc/dec the wrap                                                // count                xadj = flag * mercator.world.x;// adjustment to x                // coordinates                // Debug.output("flag=" + flag + " xadj=" + xadj);            }            xp = to.x;            if (flag != 0) {                to.x += xadj;// adjust x coordinate            }            augllpts[i] = mercator.rhumbProject(from, to, false, nsegs);            totalpts += augllpts[i].length;            from.x = to.x;            from.y = to.y;        }        llp = mercator.inverse(from);        // }// end synchronized around mercator        augllpts[i] = new float[2];        augllpts[i][0] = llp.radlat_;        augllpts[i][1] = llp.radlon_;        totalpts += 2;        // put together all the points        float[] newllpts = new float[totalpts];        int pos = 0;        for (i = 0; i < augllpts.length; i++) {            // Debug.output("copying " + augllpts[i].length + "            // floats");            System.arraycopy(            /* src */augllpts[i], 0,            /* dest */newllpts, pos, augllpts[i].length);            pos += augllpts[i].length;        }        // Debug.output("done copying " + totalpts + " total floats");        // free unused variables        augllpts = null;        // now delegate the work to the regular projection code.        return _forwardPoly(newllpts, LineType.Straight, -1, isFilled);    }    /**     * Forward project a greatcircle poly.     * <p>     * Draws great circle lines between vertices of poly. Remember to     * specify vertices in radians!     *      * @param rawllpts float[] of lat,lon,lat,lon,... in RADIANS!     * @param nsegs number of segments to draw for greatcircle or     *        rhumb lines (if &lt; 1, this value is generated     *        internally).     * @param isFilled filled poly?     * @return ArrayList of x[], y[], x[], y[], ... projected poly     * @see Projection#forwardPoly(float[], int, int, boolean)     */    protected ArrayList forwardGreatPoly(float[] rawllpts, int nsegs,                                         boolean isFilled) {        int i, j, k, totalpts = 0;        Point from = new Point();        Point to = new Point();        int end = rawllpts.length >>> 1;        float[][] augllpts = new float[end][0];        end -= 1;// stop before last segment        // calculate extra vertices between all the original segments.        forward(rawllpts[0], rawllpts[1], from, true);        for (i = 0, j = 0, k = 2; i < end; i++, j += 2, k += 2) {            forward(rawllpts[k], rawllpts[k + 1], to, true);            augllpts[i] = getGreatVertices(rawllpts[j],                    rawllpts[j + 1],                    rawllpts[k],                    rawllpts[k + 1],                    from,                    to,                    false,                    nsegs);            from.x = to.x;            from.y = to.y;            totalpts += augllpts[i].length;        }        augllpts[i] = new float[2];        augllpts[i][0] = rawllpts[j];        augllpts[i][1] = rawllpts[j + 1];        totalpts += 2;        // put together all the points        float[] newllpts = new float[totalpts];        int pos = 0;        for (i = 0; i < augllpts.length; i++) {            System.arraycopy(            /* src */augllpts[i], 0,            /* dest */newllpts, pos, augllpts[i].length);            pos += augllpts[i].length;        }        // free unused variables        augllpts = null;        // now delegate the work to the regular projection code.        return _forwardPoly(newllpts, LineType.Straight, -1, isFilled);    }    /**     * Get the vertices along the great circle between two points.     *      * @param latp previous float latitude     * @param lonp previous float longitude     * @param latn next float latitude     * @param lonn next float longitude     * @param from Point     * @param to Point     * @param include_last include n or n+1 points of the n segments?     * @return float[] lat/lon points in RADIANS!     *      */    private float[] getGreatVertices(float latp, float lonp, float latn,                                     float lonn, Point from, Point to,                                     boolean include_last, int nsegs) {        if (nsegs < 1) {            // calculate pixel distance            int dist = DrawUtil.pixel_distance(from.x, from.y, to.x, to.y);            /*             * determine what would be a decent number of segments to             * draw. HACK: this is hardcoded calculated by what might             * look ok on screen. We also put a cap on the number of             * extra segments we draw.             */            nsegs = dist >> 3;// dist/8            if (nsegs == 0) {                nsegs = 1;            } else if (nsegs > NUM_DEFAULT_GREAT_SEGS) {                nsegs = NUM_DEFAULT_GREAT_SEGS;            }            // Debug.output(            // "("+from.x+","+from.y+")("+to.x+","+to.y+")            // dist="+dist+" nsegs="+nsegs);        }        // both of these return float[] radian coordinates!        return GreatCircle.great_circle(latp,                lonp,                latn,                lonn,                nsegs,                include_last);    }    /**     * Forward projects a raster.     * <p>     * HACK: not implemented yet.     *      * @param llNW LatLonPoint of NorthWest corner of Image     * @param llSE LatLonPoint of SouthEast corner of Image     * @param image raster image     */    public ArrayList forwardRaster(LatLonPoint llNW, LatLonPoint llSE,                                   Image image) {        Debug.error("Proj.forwardRaster(): unimplemented!");        return null;    }    /**     * Check for complicated linetypes.     * <p>     * This depends on the line and this projection.     *      * @param ltype int LineType     * @return boolean     */    public boolean isComplicatedLineType(int ltype) {        switch (ltype) {        case LineType.Straight:            return false;        case LineType.Rhumb:            return (getProjectionType() == Mercator.MercatorType) ? false                    : true;        case LineType.GreatCircle:            return true/*                         * (getProjectionType() ==                         * Gnomonic.GnomonicType) ? false : true                         */;        default:            Debug.error("Proj.isComplicatedLineType: invalid LineType!");            return false;        }    }    /**     * Generates a complicated poly.     *      * @param rawllpts LatLonPoint[]     * @param ltype line type     * @param nsegs number of segments to draw for greatcircle or     *        rhumb lines (if &lt; 1, this value is generated     *        internally).     * @param isFilled filled poly?     * @return ArrayList     * @see Projection#forwardPoly     */    protected ArrayList doPolyDispatch(float[] rawllpts, int ltype, int nsegs,                                       boolean isFilled) {        switch (ltype) {        case LineType.Rhumb:            return forwardRhumbPoly(rawllpts, nsegs, isFilled);        case LineType.GreatCircle:            return forwardGreatPoly(rawllpts, nsegs, isFilled);        case LineType.Straight:            Debug.error("Proj.doPolyDispatch: Bad Dispatch!\n");            return new ArrayList(0);        default:            Debug.error("Proj.doPolyDispatch: Invalid LType!\n");            return new ArrayList(0);        }    }    /**     * Pan the map/projection.     * <p>     * Example pans:     * <ul>     * <li><code>pan(

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -