001/* 002 * Copyright (c) 1998-2010 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: welker $' 006 * '$Date: 2010-05-06 05:21:26 +0000 (Thu, 06 May 2010) $' 007 * '$Revision: 24234 $' 008 * 009 * Permission is hereby granted, without written agreement and without 010 * license or royalty fees, to use, copy, modify, and distribute this 011 * software and its documentation for any purpose, provided that the above 012 * copyright notice and the following two paragraphs appear in all copies 013 * of this software. 014 * 015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 019 * SUCH DAMAGE. 020 * 021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 026 * ENHANCEMENTS, OR MODIFICATIONS. 027 * 028 */ 029 030package org.geon; 031 032import java.awt.Point; 033import java.io.BufferedReader; 034import java.io.BufferedWriter; 035import java.io.File; 036import java.io.FileReader; 037import java.io.FileWriter; 038import java.io.IOException; 039 040import nl.skybound.awt.DoublePolygon; 041import ptolemy.actor.TypedAtomicActor; 042import ptolemy.actor.TypedIOPort; 043import ptolemy.data.ObjectToken; 044import ptolemy.data.StringToken; 045import ptolemy.data.type.BaseType; 046import ptolemy.gui.MessageHandler; 047import ptolemy.kernel.CompositeEntity; 048import ptolemy.kernel.util.IllegalActionException; 049import ptolemy.kernel.util.NameDuplicationException; 050 051////////////////////////////////////////////////////////////////////////// 052//// PointInPolygon 053/** 054 * This actor receives an array of polygon points and populates them in a 055 * polygon object it also receives a classification point. The actor outputs 056 * whether the point is contained in the polygon along with the polygon 057 * coordinates for display purposes. 058 * 059 * @author Efrat Jaeger 060 * @version $Id: PointinPolygon.java 24234 2010-05-06 05:21:26Z welker $ 061 * @since Ptolemy II 3.0.2 062 */ 063public class PointinPolygon extends TypedAtomicActor { 064 065 /** 066 * Construct an actor with the given container and name. 067 * 068 * @param container 069 * The container. 070 * @param name 071 * The name of this actor. 072 * @exception IllegalActionException 073 * If the actor cannot be contained by the proposed 074 * container. 075 * @exception NameDuplicationException 076 * If the container already has an actor with this name. 077 */ 078 public PointinPolygon(CompositeEntity container, String name) 079 throws NameDuplicationException, IllegalActionException { 080 081 super(container, name); 082 083 // Set the type constraint. 084 region = new TypedIOPort(this, "region", false, true); 085 region.setTypeEquals(BaseType.STRING); 086 toBrowser = new TypedIOPort(this, "toBrowser", false, true); 087 toBrowser.setTypeEquals(BaseType.STRING); 088 point = new TypedIOPort(this, "point", true, false); // input point 089 point.setTypeEquals(BaseType.GENERAL); 090 polygonRegions = new TypedIOPort(this, "polygonRegions", true, false); // Polygon 091 // coordinates 092 // and 093 // regions 094 polygonRegions.setTypeEquals(BaseType.GENERAL); 095 096 _attachText("_iconDescription", "<svg>\n" 097 + "<polygon points=\"-15,-2 0,-15 15,-2 11,15 -11,15\" " 098 + "style=\"fill:white\"/>\n" 099 + "<circle cx=\"3\" cy=\"4\" r=\"1\"" 100 + "style=\"fill:black\"/>\n" + "</svg>\n"); 101 102 } 103 104 // ///////////////////////////////////////////////////////////////// 105 // // ports and parameters //// 106 107 /** 108 * A classification point. 109 */ 110 public TypedIOPort point; 111 112 /** 113 * A set of polygons and their region names. 114 */ 115 public TypedIOPort polygonRegions; 116 117 /** 118 * The point's region. 119 */ 120 public TypedIOPort region; 121 122 /** 123 * A URL for display the point in the regions. 124 */ 125 public TypedIOPort toBrowser; 126 127 /** 128 * Receive a set of polygons and a classification point and returns the 129 * point region along with a URL for browser display of the point in the 130 * polygon. 131 * 132 * @exception IllegalActionException 133 * If there's no director. 134 */ 135 public void fire() throws IllegalActionException { 136 super.fire(); 137 int layer = 1; 138 while (true) { 139 if (polygonRegions.hasToken(0) && point.hasToken(0)) { 140 ObjectToken obj1 = (ObjectToken) polygonRegions.get(0); 141 PolygonUtil polygons[] = (PolygonUtil[]) obj1.getValue(); 142 ObjectToken obj2 = (ObjectToken) point.get(0); 143 Point p = (Point) obj2.getValue(); 144 x = p.getX(); 145 y = p.getY(); 146 // System.out.println("pointInPolygon point: {" + x + " , " + y 147 // + "}"); 148 for (int j = 0; j < polygons.length; j++) { 149 DoublePolygon P = polygons[j].getPolygon(); 150 // for (int i=0; i<P.npoints;i++) 151 // System.out.println("{" + P.xpoints[i] + " , " + 152 // P.ypoints[i] + "}"); 153 arrayLen = P.npoints; 154 String _region = polygons[j].getRegion(); 155 // System.out.println("region = " + _region); 156 if (_isPolygonVertex(P, x, y) || _onPolygonEdge(P, x, y) 157 || P.contains(x, y)) { 158 result = _region; // FIX ME!!! TAKE CARE OF MULTIPLE 159 // REGIONS AND NO REGION!!! 160 } 161 } 162 163 // get the working directory. 164 String _keplerPath = System.getProperty("user.dir"); 165 166 String displayFile = _keplerPath + "/lib/testdata/geon/layer" 167 + layer + ".svg"; 168 _addRegionToSVG(displayFile, result); 169 region.broadcast(new StringToken(result)); 170 if (layer == 1 && !result.trim().startsWith("diorite")) // FIX 171 // ME!! 172 // for 173 // now 174 // only 175 // diorite 176 // has a 177 // second 178 // level. 179 layer++; 180 // System.out.println("file to display: " + displayFile); 181 toBrowser.broadcast(new StringToken(displayFile)); // FIX ME!!! 182 // ADD THE 183 // FILE TO 184 // SHOW!!! 185 layer++; 186 if (layer > 2) 187 break; 188 } 189 } 190 } 191 192 /** 193 * Post fire the actor. Return false to indicate that the process has 194 * finished. If it returns true, the process will continue indefinitely. 195 */ 196 public boolean postfire() { 197 return false; 198 } 199 200 // ///////////////////////////////////////////////////////////////// 201 // // private methods //// 202 203 /* 204 * Checking whether the given point is one of the polygon's vertices. 205 */ 206 private boolean _isPolygonVertex(DoublePolygon P, double x, double y) { 207 for (int i = 0; i < arrayLen; i++) { 208 if (P.xpoints[i] == x && P.ypoints[i] == y) 209 return true; 210 } 211 return false; 212 } 213 214 /* 215 * Checking whether the given point is one of the polygon's edges. 216 */ 217 private boolean _onPolygonEdge(DoublePolygon P, double x, double y) { 218 double x1, x2, y1, y2; 219 for (int i = 0; i < arrayLen; i++) { 220 x1 = P.xpoints[i]; 221 x2 = P.xpoints[(i + 1) % arrayLen]; 222 y1 = P.ypoints[i]; 223 y2 = P.ypoints[(i + 1) % arrayLen]; 224 if (((x1 <= x && x <= x2) || (x2 <= x && x <= x1)) && // x and y are 225 // between 226 // x1,x2 and 227 // y1,y2 228 ((y1 <= y && y <= y2) || (y2 <= y && y <= y1))) { 229 if (((y - y1) / (x - x1)) == ((y - y2) / (x - x2))) 230 return true; 231 } 232 } 233 return false; 234 } 235 236 /* 237 * Adding the classification point to the SVG file for display purposes. 238 */ 239 private void _addRegionToSVG(String svgFile, String region) { 240 try { 241 // System.out.println("SVG File: " + svgFile); 242 File svg = new File(svgFile); 243 BufferedReader br = new BufferedReader(new FileReader(svg)); 244 String line; 245 String toFile = ""; 246 String extraLine; 247 if (region.length() > 20) { 248 int tmp = result.indexOf(" ", 15); 249 extraLine = "<text x= '315' y='70' fill='blue' text-anchor='middle' style='font-size: 12pt; font-family: serif; ' >" 250 + region.substring(0, tmp) + "</text>"; 251 extraLine += "<text x= '315' y='90' fill='blue' text-anchor='middle' style='font-size: 12pt; font-family: serif; ' >" 252 + region.substring(tmp + 1) + "</text>"; 253 } else { 254 extraLine = "<text x= '315' y='70' fill='blue' text-anchor='middle' style='font-size: 12pt; font-family: serif; ' >" 255 + region + "</text>"; 256 } 257 // System.out.println("Extra line" + extraLine); 258 while ((line = br.readLine()) != null) { 259 int ind = line.toLowerCase().indexOf("<text"); 260 if (ind != -1) { 261 // System.out.println("Inside extra line"); 262 toFile += line.substring(0, ind) + "\n"; 263 toFile += extraLine + "\n"; 264 toFile += line.substring(ind) + "\n"; 265 } else 266 toFile += line + "\n"; 267 } 268 br.close(); 269 270 // System.out.println(toFile); 271 BufferedWriter out = new BufferedWriter(new FileWriter(svg)); 272 out.write(toFile); 273 out.close(); 274 } catch (IOException e) { 275 MessageHandler.error("Error opening file", e); 276 } 277 } 278 279 // ///////////////////////////////////////////////////////////////// 280 // // private members //// 281 282 private double x, y; 283 private String result, id; 284 private int arrayLen; 285}