>
> 1.       Python tools feels somehow like a promising way for writing new
> drawing tools. The Python part of the tools look almost understandable for
> non-programmer and I suppose that Python is the most common geospatial
> scripting language at the moment. *However, if I understand right for
> creating new tools Python is not enough but also some java programming is
> needed*. By the way, the Road Arc tools does not work with latest
> snapshots and it makes so bad a jam that only killing the process helps.
> The error from the console window:
>

@Jukka,  I assume you are referring to the following line from Startup.py:

#tools can be defined in java only - as in this orphaned JUMP Note tool

The comment is badly worded.  It should say #tools may also be defined in
java and activated here - as in this orphaned JUMP Note tool  There are
many examples of defining a new drawing tool in jython only.

While I don't currently have my OpenJump development platform up to date, I
did diff the SkyJUMP copies of  two attached files and bring them up to
date with the new Shift key feature of the Road Curve tool (it is maddening
to draw long straight stretch of road without it!).  If one of the
developers has a few minutes, they can see if it fixes the issue.  If it
doesn't we can comment out lines 100 through 109 in startup.py to
deactivate the Road tool.

regards,

Larry Becker

On Tue, Jan 20, 2015 at 6:07 AM, Rahkonen Jukka (MML) <
jukka.rahko...@maanmittauslaitos.fi> wrote:

>  Hi,
>
>
>
> I was searching tools for making some CAD alike drawing and studied what
> we have. I found:
>
> 1.       Some of the Python tools in the standard delivery has CAD-alike
> features (rotated rectangle, Arc tool).
>
> 2.       Peppe has made a CAD tools plugin that adds some CAD tools into
> the default digitizing box.
>
> 3.       Kosmo GIS has a special CAD toolbox with about 15 tools.
>
>
>
> Quick comments:
>
>
>
> 1.       Python tools feels somehow like a promising way for writing new
> drawing tools. The Python part of the tools look almost understandable for
> non-programmer and I suppose that Python is the most common geospatial
> scripting language at the moment. However, if I understand right for
> creating new tools Python is not enough but also some java programming is
> needed. By the way, the Road Arc tools does not work with latest snapshots
> and it makes so bad a jam that only killing the process helps. The error
> from the console window:
>
>
>
> Exception in thread "AWT-EventQueue-0" Traceback (innermost last):
>
>   File
> "C:\oj_test\OJ_18\OpenJUMP-20150116-r4270-PLUS\lib\ext\jython\RoadTool.py",
> line 201, in handleDeActivation
>
> AttributeError: 'NoneType' object has no attribute 'actionPerformed'
>
> Exception in thread "AWT-EventQueue-0" Traceback (innermost last):
>
>
>
> 2.       I would rather place the additional CAD tools to their own tool
> box because they do not behave exactly as the standard tools. Many of the
> OJ keyboard shortcuts stop working when a CAD tools is selected. On the
> other hand, the SHIFT key does not alter the behaviour of CAD tools as
> planned in most cases. The draw vertical/horizontal tool, tools for drawing
> closed linestrings and the annotation layer tool would be nice additions to
> OJ PLUS. Annotation tool might need some revisiting.
>
> 3.       Many of the Kosmo tools are fine. I wonder how difficult it
> would be to adapt some of those for OJ. For example the “Continue lines
> until they cross” tools is simple and clever and I do not remember such
> tool in other open source GIS. “Draw perpendicular” works well also with
> circles and Bezier curves but it would be nice to have a sister tool “Draw
> tangent”.
>
>
>
> None of these CAD tools had a tool for my need. Or perhaps the “Draw with
> commands” tool in Kosmo has but I could not discover the right syntax even
> I found the manual
> http://www.kosmoland.es/public/kosmo/v_2.0/docs/Extension_Herramienta_CAD.pdf.
> What I would like to do feels simple to me:
>
>
>
> -          Draw a point or first vertex to coordinates x/y
>
> -          Draw next point or vertex by angle and distance or to next
> given coordinates
>
>
>
> I know I can workaround the manual feed of coordinates effectively by
> using WKT but not the angle + distance alternative.
>
>
>
> -Jukka Rahkonen-
>
>
>
> ------------------------------------------------------------------------------
> New Year. New Location. New Benefits. New Data Center in Ashburn, VA.
> GigeNET is offering a free month of service with a new server in Ashburn.
> Choose from 2 high performing configs, both with 100TB of bandwidth.
> Higher redundancy.Lower latency.Increased capacity.Completely compliant.
> http://p.sf.net/sfu/gigenet
> _______________________________________________
> Jump-pilot-devel mailing list
> Jump-pilot-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel
>
>
# Copyright (C) 2005 Integrated Systems Analysts, Inc.
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
import org.openjump.util.python.pythonexampleclasses.DrawCustomTool as 
DrawCustomTool
from com.vividsolutions.jts.algorithm.CGAlgorithms import * 
import com.vividsolutions.jts.geom.Coordinate as Coordinate
import com.vividsolutions.jump.geom.CoordUtil as CU
import org.openjump.core.geomutils.GeoUtils as GeoUtils
import javax.swing as swing
import java.util.ArrayList as ArrayList
import com.vividsolutions.jump.geom.Angle as Angle
import org.openjump.core.geomutils.Arc as Arc
#from org.openjump.util.python.JUMP_GIS_Framework import showMessage
#from org.openjump.util.python.JUMP_GIS_Framework import warnUser

_label1 = None
_edit1 = None
_button1 = None
_panel = None
_toolbox = None
_laneWidths = []
_shiftStates = []
_doBackup = 0
_skip = []
_radius = 0
_isActive = 0

def _backup(event):
    global _doBackup
    _doBackup = 1

def _roadDraw(p, final=0, shiftDown=0):
    global _edit1, _laneWidths, _shiftStates, _doBackup, _skip, _radius, 
_roadCenterLine
    roadEdgeLeft = ArrayList()
    roadEdgeRight = ArrayList()
    _roadCenterLine = ArrayList()
    try:
        laneWidth = float(_edit1.text)
    except:
        laneWidth = p[0].distance(p[1])
    roadWidth = laneWidth * 2.0
    if p.size() == 3:
        _laneWidths = [laneWidth, laneWidth]
        _shiftStates = [0, 0]
    _edit1.text = "%f" % laneWidth    
    p.remove(0)
    if len(_laneWidths) < p.size():
        _laneWidths.append(laneWidth)
        _shiftStates.append(shiftDown)
    else:
        _laneWidths[-1] = laneWidth
        _shiftStates[-1] = shiftDown
    #handle the backup button
    for skip in _skip: p.remove(skip)
    skip = 0
    if _doBackup:
        skip = p.size() - 2  #index of prior point
        _skip.append(skip)   #we'll need it next time we get p[]
        _doBackup = 0
        if skip > 1:         #lane width skips can be handled now
            _laneWidths = _laneWidths[:skip] + _laneWidths[skip+1:]
            _shiftStates = _shiftStates[:skip] + _shiftStates[skip+1:]
    if skip > 1:
        p.remove(skip)
    left = 1
    right = 0
    #crank in the initial road rectangle left and right edges
    roadEdgeLeft.add(GeoUtils.perpendicularVector(p[0], p[1], _laneWidths[0], 
left))
    roadEdgeRight.add(GeoUtils.perpendicularVector(p[0], p[1], _laneWidths[0], 
left))
    roadEdgeRight.add(GeoUtils.perpendicularVector(p[0], p[1], _laneWidths[0], 
right))
    roadEdgeLeft.add(GeoUtils.perpendicularVector(p[1], p[0], _laneWidths[1], 
right))
    roadEdgeRight.add(GeoUtils.perpendicularVector(p[1], p[0], _laneWidths[1], 
left))
    _roadCenterLine.add(p[0])
    _roadCenterLine.add(p[1])
    #calculate the left and right edges of the rest of the road
    currPos = 1
    endPos = p.size() - 1 #the last point in the array is the curr mouse pos 
adjusted by constraints
    perp1 = GeoUtils.perpendicularVector(p[1], p[0], roadWidth, right) 
    while currPos < endPos:
        midPt = CU.add( p[currPos], CU.divide(CU.subtract(p[currPos + 1], 
p[currPos]), 2))
        perp2 = GeoUtils.perpendicularVector(midPt, p[currPos], roadWidth, 
right)
        center = GeoUtils.getIntersection(p[currPos], perp1, midPt, perp2)
        if center.z == 0.0:  #check for parallel vectors
            radius = center.distance(p[currPos])
            d = p[currPos].distance(midPt)
            curved = radius / d < 50  #compare to tangent threshold
        else: curved = 0
        if _shiftStates[currPos + 1] == 1: curved = 0
        if curved: #construct a circular curve
            circularArc = (_laneWidths[currPos] == _laneWidths[currPos + 1])
            radius = center.distance(p[currPos])
            toLeft = computeOrientation(p[currPos], perp1, p[currPos + 1]) == 
LEFT
            basePerp = GeoUtils.perpendicularVector(p[currPos], perp1, 
roadWidth, toLeft)
            toLeft = computeOrientation(p[currPos], basePerp, p[currPos + 1]) 
== LEFT 
            radians = Angle.angleBetween(center, p[currPos], p[currPos + 1])
            
            if circularArc:
                #left edge
                if toLeft:
                    angle = -Angle.toDegrees(radians)
                    ratio = (radius - _laneWidths[currPos]) / radius
                else:
                    angle = Angle.toDegrees(radians)
                    ratio = (radius + _laneWidths[currPos]) / radius
                arc = Arc(center, p[currPos], angle)
                arcPts = arc.getCoordinates()
                for pt in arcPts:
                    _roadCenterLine.add(pt)
                start = CU.add(center, CU.multiply(ratio, 
CU.subtract(p[currPos], center)))
                arc = Arc(center, start, angle)
                arcPts = arc.getCoordinates()
                for pt in arcPts:
                    roadEdgeLeft.add(pt)
                #right edge 
                if toLeft:
                    ratio = (radius + _laneWidths[currPos]) / radius
                else:
                    ratio = (radius - _laneWidths[currPos]) / radius
                start = CU.add(center, CU.multiply(ratio, 
CU.subtract(p[currPos], center)))
                arc = Arc(center, start, angle)
                arcPts = arc.getCoordinates()
                for pt in arcPts:
                    roadEdgeRight.add(pt)
                perp1.x = center.x
                perp1.y = center.y
                _radius = radius - _laneWidths[currPos]
            else: #smooth tangent non-circular curve
                #left edge
                if toLeft:
                    angle = -Angle.toDegrees(radians)
                else:
                    angle = Angle.toDegrees(radians)
                start = p[currPos]
                arc = Arc(center, start, angle)
                arcPts = arc.getCoordinates()
                for pt in arcPts:
                    _roadCenterLine.add(pt)
                inc = (_laneWidths[currPos + 1] - _laneWidths[currPos]) / 
(arcPts.size() - 1)
                i = 0
                for pt in arcPts:
                    if toLeft:
                        ratio = (radius - _laneWidths[currPos]  - (i * inc)) / 
radius
                    else:
                        ratio = (radius +  _laneWidths[currPos] + (i * inc)) / 
radius
                    roadEdgeLeft.add(CU.add(center, CU.multiply(ratio, 
CU.subtract(pt, center))))
                    i += 1
                #right edge
                i = 0
                for pt in arcPts:
                    if toLeft:
                        ratio = (radius + _laneWidths[currPos] + (i * inc)) / 
radius
                    else:
                        ratio = (radius - _laneWidths[currPos] - (i * inc)) / 
radius
                    roadEdgeRight.add(CU.add(center, CU.multiply(ratio, 
CU.subtract(pt, center))))
                    i += 1
                perp1.x = center.x
                perp1.y = center.y
                _radius = radius - _laneWidths[currPos]
        else: #construct straight section of road
            if _shiftStates[currPos + 1] == 1: #handle angle instead of curve
                if roadEdgeLeft.size() > 1:
                    p1 = roadEdgeLeft[roadEdgeLeft.size()-2]
                    p2 = roadEdgeLeft[roadEdgeLeft.size()-1]
                    p3 = GeoUtils.perpendicularVector(p[currPos], p[currPos + 
1], _laneWidths[currPos], left)
                    p4 = GeoUtils.perpendicularVector(p[currPos + 1], 
p[currPos], _laneWidths[currPos + 1], right)
                    intxPt = GeoUtils.intersect(p1, p2, p3, p4)
                    if intxPt != None:
                        roadEdgeLeft[roadEdgeLeft.size()-1] = intxPt
                    p1 = roadEdgeRight[roadEdgeRight.size()-2]
                    p2 = roadEdgeRight[roadEdgeRight.size()-1]
                    p3 = GeoUtils.perpendicularVector(p[currPos], p[currPos + 
1], _laneWidths[currPos], right)
                    p4 = GeoUtils.perpendicularVector(p[currPos + 1], 
p[currPos], _laneWidths[currPos + 1], left)
                    intxPt = GeoUtils.intersect(p1, p2, p3, p4)
                    if intxPt != None:
                        roadEdgeRight[roadEdgeRight.size()-1] = intxPt          
          
                roadEdgeLeft.add(GeoUtils.perpendicularVector(p[currPos + 1], 
p[currPos], _laneWidths[currPos + 1], right))
                roadEdgeRight.add(GeoUtils.perpendicularVector(p[currPos + 1], 
p[currPos], _laneWidths[currPos + 1], left))
                perp1 = GeoUtils.perpendicularVector(p[currPos + 1], 
p[currPos], _laneWidths[currPos + 1], right)
                _roadCenterLine.add(p[currPos + 1])
                _radius = 0
            else:
                roadEdgeLeft.add(GeoUtils.perpendicularVector(p[currPos + 1], 
p[currPos], _laneWidths[currPos + 1], right))
                roadEdgeRight.add(GeoUtils.perpendicularVector(p[currPos + 1], 
p[currPos], _laneWidths[currPos + 1], left))
                perp1 = GeoUtils.perpendicularVector(p[currPos + 1], 
p[currPos], _laneWidths[currPos + 1], right)
                _roadCenterLine.add(p[currPos + 1])
                _radius = 0
        currPos += 1
    #if final:   #uncomment to display click point feedback for debugging
    p.clear()    #clear the click point array and replace with road edges
    #the use of prevPt below is used to eliminate duplicate points in output
    if roadEdgeLeft.size() > 0:
        prevPt = roadEdgeLeft[0];
        p.add(prevPt)
    for pt in roadEdgeLeft:
        if prevPt.distance(pt) != 0.0: p.add(pt)
        prevPt = pt;
    #trace right return path back to start
    i = roadEdgeRight.size() - 1
    if i >= 0:
        prevPt = roadEdgeRight[i];
        p.add(prevPt)
    while i >= 0:
        pt = roadEdgeRight[i]
        if prevPt.distance(pt) != 0.0: p.add(pt)
        prevPt = pt;
        i -= 1
        
class ToolListenerFeedback(DrawCustomTool.FeedbackListener):
    def feedbackDraw(self, event):
        global _radius
        if event.shiftDown():
            statMsg = "shift down"
            _roadDraw(event.coords, final=0, shiftDown=1)
        else:
            statMsg = "shift up"
            _roadDraw(event.coords, final=0, shiftDown=0)
        for pt in _roadCenterLine:
            event.coords.add(pt)
        
        panel = event.wc.layerViewPanel
        #statMsg = "Inside radius " + panel.format(_radius)
        event.statusMessage = statMsg
    
class ToolListenerFinal(DrawCustomTool.FinalDrawListener):
    def finalDraw(self, event):
        global _label1, _edit1, _button1, _laneWidths, _skip, _radius
        if event.shiftDown():
            statMsg = "shift down"
            _roadDraw(event.coords, final=1, shiftDown=1)
        else:
            statMsg = "shift up"
            _roadDraw(event.coords, final=1, shiftDown=0)
        
        _edit1.text = ""
        _laneWidths = []
        _skip = []
    def setGUI(self, label1, edit1, panel, toolbox):
        global _label1, _edit1, _panel, _toolbox
        _label1 = label1
        _edit1 = edit1
        _panel = panel
        _toolbox = toolbox
        _radius = 0

class ToolListenerDeActivation(DrawCustomTool.DeActivationListener):
    def handleDeActivation(self, event):
        global _label1, _edit1, _panel, _button1, _toolbox, _isActive
        _label1.text = "Tool input:"
        _edit1.text = ""
        _button1.actionPerformed = None
        _panel.remove(_button1)
        _isActive = 0
        _toolbox.pack()

class ToolListenerActivation(DrawCustomTool.ActivationListener):
    def handleActivation(self, event):
        global _label1, _button1, _doBackup, _isActive      
        _label1.text = "Lane Width"
        if not _isActive:
            _button1 = swing.JButton("Backup")
            _panel.add("East",_button1)
            _button1.actionPerformed = _backup
        _isActive = 1
        _doBackup = 0
  
/*
 * The Unified Mapping Platform (JUMP) is an extensible, interactive GUI 
 * for visualizing and manipulating spatial features with geometry and attributes.
 *
 * Copyright (C) 2003 Vivid Solutions
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 * 
 * For more information, contact:
 *
 * Vivid Solutions
 * Suite #1A
 * 2328 Government Street
 * Victoria BC  V8T 5G5
 * Canada
 *
 * (250)385-6040
 * www.vividsolutions.com
 */

package org.openjump.util.python.pythonexampleclasses;

import java.awt.event.MouseEvent;
import java.awt.geom.GeneralPath;
import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Point2D;
import java.awt.Shape;
import java.util.List;
import java.util.ArrayList;
import java.util.EventObject;
import java.util.EventListener;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import java.util.Iterator;

import org.python.core.Py;
import org.python.core.PyException;
import org.python.core.PyString;

import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.MultiPoint;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.Polygon;
import com.vividsolutions.jts.operation.valid.IsValidOp;
import com.vividsolutions.jump.workbench.WorkbenchContext;
import com.vividsolutions.jump.workbench.ui.EditTransaction;
import com.vividsolutions.jump.workbench.ui.LayerViewPanel;
import com.vividsolutions.jump.workbench.ui.cursortool.editing.*;

public class DrawCustomTool extends ConstrainedNClickTool {
    private FeatureDrawingUtil featureDrawingUtil;
    private int minClicks = 1;
    private int fireClicks = 2;
    private Icon icon = null;
    private String toolName = "Custom Tool";
    private String geoType = "Point";
    private FeedbackListener feedbackListener = null;
    private FinalDrawListener finalGeoListener = null;
    private ActivationListener activationListener = null;
    private DeActivationListener deActivationListener = null;
    private boolean shiftDown = false;
    
    public DrawCustomTool(FeatureDrawingUtil featureDrawingUtil)
    {
    	super();
    	drawClosed = false;
    	this.featureDrawingUtil = featureDrawingUtil;
    }
    
	public void activate(LayerViewPanel layerViewPanel) {
		super.activate(layerViewPanel);
	   	if (activationListener != null){
			WorkbenchContext wc = this.getWorkbench().getContext();
			CustomToolEvent toolEvent = new CustomToolEvent(this, null, wc, shiftDown);	   	 
			activationListener.handleActivation(toolEvent);		
	   	}
	}
	
	public void deactivate() {
		cancelGesture();
		super.deactivate();
	   	if (deActivationListener != null){
			WorkbenchContext wc = this.getWorkbench().getContext();
			CustomToolEvent toolEvent = new CustomToolEvent(this, null, wc, shiftDown);	   	 
			deActivationListener.handleDeActivation(toolEvent);		
	   	}
	}

   public void setFireClicks(int fireClicks)
    {
    	this.fireClicks = fireClicks;
    }
    
    public void setMinClicks(int minClicks)
    {
    	this.minClicks = minClicks;
    }
    
    public void setMaxClicks(int maxClicks)
    {
    	this.n = maxClicks; //number of clicks at which to finish the drawing (stored in super)
    }
    
    public void setIcon(Icon icon)
    {
    	this.icon = icon;
    }
    
    public void setToolName(String toolName)
    {
    	this.toolName = toolName;
    }
    
    public void setGeometryType(String geoType)
    {
    	boolean goodType = (geoType.equalsIgnoreCase("POINT") ||
    			geoType.equalsIgnoreCase("LINESTRING") ||
    			geoType.equalsIgnoreCase("POLYGON"));
    	if (goodType)
    		this.geoType = geoType;
    	else
    		throw new PyException(Py.ValueError, new PyString(geoType + ": invalid geometry type")); 
    }
    
    public void setStrokeWidth(int width)
    {
    	super.setStrokeWidth(width);
    }
    
	public interface FinalDrawListener extends EventListener
	{
	    public void finalDraw(CustomToolEvent event);
	}

	public interface FeedbackListener extends EventListener
	{
	    public void feedbackDraw(CustomToolEvent event);
	}

	public interface ActivationListener extends EventListener
	{
	    public void handleActivation(CustomToolEvent event);
	}
    
	public interface DeActivationListener extends EventListener
	{
	    public void handleDeActivation(CustomToolEvent event);
	}
	
	public void setFeedbackListener(FeedbackListener listener)
    {
    	feedbackListener = listener;
    }

    public void setFinalGeoListener(FinalDrawListener listener)
    {
    	finalGeoListener = listener;
    }

    public void setActivationListener(ActivationListener listener)
    {
    	activationListener = listener;
    }

    public void setDeActivationListener(DeActivationListener listener)
    {
    	deActivationListener = listener;
    }

   public String getName() 
    {
    	//Specify name explicitly, otherwise it will be "Draw Custom"
        return toolName;
    }

    public Icon getIcon() 
    {
    	if (icon == null)
    		return new ImageIcon(getClass().getResource("DrawLine.gif")); 
    	else
    		return icon;
    }

    protected void gestureFinished() throws Exception 
	{
        reportNothingToUndoYet();
        Geometry geo = getFinalGeometry();
        if (geo == null) return;
        execute(featureDrawingUtil.createAddCommand(geo,
                isRollingBackInvalidEdits(), getPanel(), this));
    }

    protected Shape getShape() throws NoninvertibleTransformException
    {
    	List coords = new ArrayList(getCoordinates());

        if (coords.size() >= fireClicks)
        {
        	coords.add(tentativeCoordinate);
        	coords = fireFeedbackEvent(coords);
            Point2D firstPoint = getPanel().getViewport().toViewPoint((Coordinate)coords.get(0));
            GeneralPath path = new GeneralPath();
            path.moveTo((float) firstPoint.getX(), (float) firstPoint.getY());

            for (int i = 1; i < coords.size(); i++) 
            {
                Coordinate nextCoordinate = (Coordinate) coords.get(i);
                Point2D nextPoint = getPanel().getViewport().toViewPoint(nextCoordinate);
                path.lineTo((int) nextPoint.getX(), (int) nextPoint.getY());
            }
            return path;
        }
        else
        {
        	return super.getShape();
        }
    }

    protected Geometry getFinalGeometry() throws NoninvertibleTransformException 
	{
    	boolean goodGeo = true;
    	Geometry geo = null;
    	
        if (getCoordinates().size() < minClicks) 
        {
        	getPanel().getContext().warnUser("Must have at least " + minClicks + " points");
            return null;
        }
    	
    	List coords = fireFinalGeoEvent(getCoordinates());
        IsValidOp isValidOp = null;
        
        if (geoType.equalsIgnoreCase("POINT"))
        {
        	if (coords.size() == 1)
        	{
        		geo = new GeometryFactory().createPoint((Coordinate)coords.get(0));
        		isValidOp = new IsValidOp((Point) geo);
        	}
        	else
        	{
        		geo = new GeometryFactory().createMultiPoint(toArray(coords));
        		isValidOp = new IsValidOp((MultiPoint) geo);
        	}
         }
        
        else if (geoType.equalsIgnoreCase("LINESTRING"))
        {
        	geo = new GeometryFactory().createLineString(toArray(coords));
        	isValidOp = new IsValidOp((LineString) geo);
        }
        
        else if (geoType.equalsIgnoreCase("POLYGON"))
        {
        	geo = new GeometryFactory().createPolygon(
        			new GeometryFactory().createLinearRing(toArray(coords)),
					null);
        	isValidOp = new IsValidOp((Polygon) geo);
        }
        else
        {
        	getPanel().getContext().warnUser(geoType + " not a valid type.");
        	return null;
        }
        
        if (!isValidOp.isValid()) 
        {
        	getPanel().getContext().warnUser(isValidOp.getValidationError().getMessage());
        	if (getWorkbench().getBlackboard().get(EditTransaction.ROLLING_BACK_INVALID_EDITS_KEY, false)) 
        	{
        		return null;
        	}
        }
        
        return geo;
    }

    protected List fireFeedbackEvent(List coordsIn)
    {
    	if (feedbackListener == null)
    	{
    		return fireFinalGeoEvent(coordsIn);
    	}
    	else
    	{
    		ArrayList coords = new ArrayList();
    		
    		for (Iterator i = coordsIn.iterator(); i.hasNext();)
    			coords.add(((Coordinate) i.next()).clone());
    		
    		WorkbenchContext wc = this.getWorkbench().getContext();
    		CustomToolEvent toolEvent = new CustomToolEvent(this, coords, wc, shiftDown);
    		feedbackListener.feedbackDraw(toolEvent);
    		coords = (ArrayList)toolEvent.getCoords();
    		statusMessage = toolEvent.getStatusMessage();
    		return coords;
    	}
    }

    protected List fireFinalGeoEvent(List coordsIn)
    {
    	if (finalGeoListener == null)
    	{
    		return coordsIn;
    	}
    	else
    	{
    		ArrayList coords = new ArrayList();
    		
    		for (Iterator i = coordsIn.iterator(); i.hasNext();)
    			coords.add(((Coordinate) i.next()).clone());
    		WorkbenchContext wc = this.getWorkbench().getContext();
    		CustomToolEvent toolEvent = new CustomToolEvent(this, coords, wc, shiftDown);
    		finalGeoListener.finalDraw(toolEvent);
    		coords = (ArrayList)toolEvent.getCoords();
    		statusMessage = toolEvent.getStatusMessage();
    		return coords;
    	}
    }

    public void mouseMoved(MouseEvent e)
    {
        mouseLocationChanged(e);
        shiftDown = e.isShiftDown();
    }
    
    public class CustomToolEvent extends EventObject
	{
    	private List localCoords;
    	private String statusMessage = "";
    	private WorkbenchContext wc;
    	private boolean shiftDown;
    	
    	CustomToolEvent(Object source, List coords, WorkbenchContext wc, boolean shiftDown)
		{
    		super(source);
    		localCoords = coords;
    		this.wc = wc;
    		this.shiftDown = shiftDown;
		}
    	
    	public WorkbenchContext getWc()
    	{
    		return wc;
    	}

    	public List getCoords()
    	{
    		return localCoords;
    	}
    	
    	public void setCoords(List coords)
    	{
    		localCoords = coords;
    	}
    	
    	public void setStatusMessage(String statusMessage)
    	{
    		this.statusMessage = statusMessage;
    	}
    	
    	public String getStatusMessage()
    	{
    		return statusMessage;
    	}
    	
    	public boolean shiftDown()
    	{
    		return shiftDown;
    	}
	}
}
------------------------------------------------------------------------------
New Year. New Location. New Benefits. New Data Center in Ashburn, VA.
GigeNET is offering a free month of service with a new server in Ashburn.
Choose from 2 high performing configs, both with 100TB of bandwidth.
Higher redundancy.Lower latency.Increased capacity.Completely compliant.
http://p.sf.net/sfu/gigenet
_______________________________________________
Jump-pilot-devel mailing list
Jump-pilot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel

Reply via email to