Changeset 15461 in osm for applications/editors/josm/plugins/czechaddress
- Timestamp:
- 2009-06-01T17:24:35+02:00 (16 years ago)
- Location:
- applications/editors/josm/plugins/czechaddress
- Files:
-
- 2 added
- 1 deleted
- 20 edited
- 2 moved
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/czechaddress
- Property svn:ignore
-
old new 1 1 build 2 .log.xsl.swp
-
- Property svn:ignore
-
applications/editors/josm/plugins/czechaddress/build.xml
r15203 r15461 26 26 <!-- compile the plugin --> 27 27 <javac srcdir="src" 28 sourcepath="" 28 29 classpath="${josm.jar}" 29 30 destdir="${plugin.build.dir}" 30 debug="true" />31 debug="true"> 31 32 32 <!-- create the manifest -->33 <manifest file="${plugin.build.dir}/${plugin.basepackage.dir}/MANIFEST.MF">34 < attribute name="Author" value="Radomír Černoch"/>35 < attribute name="Plugin-Description" value="Creating and handling address nodes and buildings within Czech Republic."/>36 < attribute name="Plugin-Mainversion" value="1607"/>37 < attribute name="Plugin-Version" value="0.1.1"/>38 < attribute name="Plugin-Class" value="${plugin.basepackage}.CzechAddressPlugin"/>39 </ manifest>33 <include name="**/Status*.java"/> 34 <include name="**/StringUtils.java"/> 35 <include name="**/NotNull*.java"/> 36 <include name="**/addressdatabase/*.java"/> 37 <include name="**/proposal*/*.java"/> 38 <include name="**/intelligence/Reasoner*.java"/> 39 <include name="**/intelligence/Match.java"/> 40 </javac> 40 41 41 <!-- include the images -->42 <copy todir="${plugin.build.dir}/images">43 <fileset dir="images"/>44 </copy>45 42 </target> 46 43 47 <target name="dist"48 depends="compile"49 description="Create the .jar file for distribution">50 <mkdir dir="${plugin.dist.dir}"/>51 <jar destfile="${plugin.jar}"52 basedir="${plugin.build.dir}"53 manifest="${plugin.build.dir}/${plugin.basepackage.dir}/MANIFEST.MF"/>54 </target>55 56 <target name="doc" description="Create Javadoc API documentation">57 <ant antfile="build.xml" target="doc" dir="${josm.base}"/>58 <mkdir dir="${plugin.javadoc.dir}"/>59 <javadoc sourcepath="src"60 packagenames="*"61 destdir="${plugin.javadoc.dir}"62 use="true"63 charset="UTF-8">64 <doctitle><![CDATA[Czech Address JOSM plugin]]></doctitle>65 <bottom><![CDATA[<i>Licenced under GPLv3. Bugreports should be sent to66 <a href='mailto:radomir.cernoch@gmail.com'>Radomír Černoch</a></i>]]>67 </bottom>68 <!--<tag name="todo" scope="all" description="To do:"/>-->69 <link href="http://java.sun.com/j2se/1.5.0/docs/api/"/>70 <link href="http://developer.java.sun.com/developer/products/xml/docs/api/"/>71 <!--<link href="file://${user.home}/devel/core/doc"/>-->72 </javadoc>73 </target>74 75 <target name="install" depends="dist">76 <property environment="env"/>77 <condition property="josm.plugins.dir"78 value="${env.APPDATA}/JOSM/plugins"79 else="${user.home}/.josm/plugins">80 <and><os family="windows"/></and>81 </condition>82 <copy file="${plugin.jar}" todir="${josm.plugins.dir}"/>83 </target>84 44 85 45 <!-- Before running "run" target, please "ant dist" the JOSM. --> 86 46 <target name="run" depends="compile"> 87 <java classname=" JOSM" fork="true">47 <java classname="org.openstreetmap.josm.plugins.czechaddress.intelligence.Reasoner"> 88 48 <jvmarg value="-Xmx1024m"/> 89 49 <jvmarg value="-Xdebug"/> … … 97 57 <pathelement path="${java.class.path}"/> 98 58 </classpath> 99 <!--<arg value="/home/radek/Desktop/Hustopeče.osm"/>-->100 59 </java> 60 <exec executable="xsltproc" output="log.html"> 61 <arg value="log.xsl"/> 62 <arg value="log.xml"/> 63 </exec> 101 64 </target> 102 65 -
applications/editors/josm/plugins/czechaddress/nbproject
-
Property svn:ignore
set to
.project.xml.swp
-
Property svn:ignore
set to
-
applications/editors/josm/plugins/czechaddress/nbproject/project.xml
r15201 r15461 46 46 <target>compile</target> 47 47 </action> 48 <action name="debug">49 <script>nbproject/ide-targets.xml</script>50 <target>debug-nb</target>51 </action>52 48 </ide-actions> 49 <export> 50 <type>folder</type> 51 <location>build</location> 52 <build-target>compile</build-target> 53 </export> 53 54 <view> 54 55 <items> … … 71 72 <ide-action name="javadoc"/> 72 73 <ide-action name="run"/> 73 <ide-action name="debug"/>74 74 </context-menu> 75 75 </view> … … 80 80 <package-root>src</package-root> 81 81 <classpath mode="compile">../../core/build:../../core/src:tests/junit-4.5.jar</classpath> 82 <built-to>build</built-to> 82 83 <javadoc-built-to>doc</javadoc-built-to> 83 84 <source-level>1.5</source-level> -
applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/CzechAddressPlugin.java
r15203 r15461 27 27 import org.openstreetmap.josm.plugins.czechaddress.actions.ModifierAction; 28 28 import org.openstreetmap.josm.plugins.czechaddress.actions.SplitAreaByEmptyWayAction; 29 import org.openstreetmap.josm.plugins.czechaddress.gui.DatabaseModifier; 29 import org.openstreetmap.josm.plugins.czechaddress.gui.Inspector; 30 import org.openstreetmap.josm.plugins.czechaddress.gui.Renamer; 30 31 import org.openstreetmap.josm.plugins.czechaddress.gui.FactoryDialog; 31 32 import org.openstreetmap.josm.plugins.czechaddress.intelligence.Reasoner; … … 46 47 new ArrayList<AbstractButton>(); 47 48 48 static p rivate Reasoner mainReasoner = null;49 static p rivate Database mainDatabase = null;49 static public Reasoner reasoner = null; 50 static public Database database = null; 50 51 51 public SelectionMonitor selectionMonitor = null; 52 static public FactoryDialog factoryDialog = null; 53 static public ConflictResolver conflictResolver = null; 52 static public FactoryDialog factoryDialog = null; 53 static public ConflictResolver conflictResolver = null; 54 55 static public Renamer renamer = null; 56 static public Inspector inspector = null; 57 54 58 55 59 static private String pluginDir = null; … … 58 62 59 63 pluginDir = getPluginDir(); 64 addStatusListener(this); 60 65 61 factoryDialog = FactoryDialog.getInstance();66 factoryDialog = new FactoryDialog(); 62 67 conflictResolver = new ConflictResolver(); 63 68 64 addStatusListener(this); 65 addStatusListener(conflictResolver); 66 69 67 70 MainMenu.add(Main.main.menu.toolsMenu, new SplitAreaByEmptyWayAction()); 68 71 72 69 73 // Prepare for filling the database. 70 mainDatabase = new Database();74 database = new Database(); 71 75 final MvcrParser parser = new MvcrParser(); 72 76 //parser.setFilter(null, null, null, ""); 73 77 //parser.setFilter("HUSTOPEČE", "HUSTOPEČE", null, null); 74 parser.setTargetDatabase( mainDatabase);78 parser.setTargetDatabase(database); 75 79 parser.setStorageDir(pluginDir); 76 80 … … 80 84 try { 81 85 parser.fillDatabase(); 82 broadcastStatusChange d(StatusListener.MESSAGE_DATABASE_LOADED);86 broadcastStatusChange(StatusListener.MESSAGE_DATABASE_LOADED); 83 87 } catch (DatabaseLoadException dle) { 84 88 dle.printStackTrace(); … … 95 99 public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) { 96 100 97 super.mapFrameInitialized(oldFrame, newFrame);98 99 101 if (newFrame == null) 100 102 return; 101 103 102 newFrame.addToggleDialog( FactoryDialog.getInstance());104 newFrame.addToggleDialog(factoryDialog); 103 105 newFrame.addMapMode(new IconToggleButton(new FactoryAction(newFrame))); 104 }105 106 public static Reasoner getReasoner() {107 return mainReasoner;108 }109 110 public static Database getDatabase() {111 return mainDatabase;112 106 } 113 107 … … 121 115 122 116 // Update database according to the map 123 (new DatabaseModifier()).setVisible(true); 117 (new Renamer()).setVisible(true); 118 (new Inspector()).setVisible(true); 124 119 125 120 // And add them to the reasoner. 126 mainReasoner = new Reasoner(pool);127 mainReasoner.addPrimitives(Main.ds.allPrimitives());121 reasoner = new Reasoner(pool); 122 reasoner.addPrimitives(Main.ds.allPrimitives()); 128 123 } 129 124 130 125 static private ElementWithStreets location = null; 131 132 static public ElementWithStreets getLocation() { 126 static public ElementWithStreets getLocation() { 133 127 if (location == null) 134 128 changeLocation(); … … 142 136 if (newLocation != null && newLocation != location) { 143 137 location = newLocation; 144 145 /* 146 // Parse the database once more to get the streets and houses. 147 MvcrParser parser = new MvcrParser(); 148 ParentResolver resolver = new ParentResolver(location); 149 150 parser.setFilter(resolver.parentRegion == null ? null : resolver.parentRegion.getName(), 151 resolver.parentViToCi == null ? null : resolver.parentViToCi.getName(), 152 resolver.parentSuburb == null ? null : resolver.parentSuburb.getName(), 153 resolver.parentStreet == null ? null : resolver.parentStreet.getName()); 154 155 parser.setTargetDatabase(mainDatabase); 156 parser.setStorageDir(pluginDir); 157 try { 158 parser.fillDatabase(); 159 } catch (DatabaseLoadException dle) { 160 dle.printStackTrace(); 161 System.err.println("CzechAddress: " + 162 "Selhalo načtení databáze. A teď se budou dít divy..."); 163 }*/ 164 165 broadcastStatusChanged(StatusListener.MESSAGE_LOCATION_CHANGED); 166 initReasoner(); 138 broadcastStatusChange(MESSAGE_LOCATION_CHANGED); 167 139 } 168 140 } … … 182 154 } 183 155 184 static public void broadcastStatusChange d(int statusMessage) {156 static public void broadcastStatusChange(int statusMessage) { 185 157 for (StatusListener l : listeners) 186 158 l.pluginStatusChanged(statusMessage); … … 188 160 189 161 public void pluginStatusChanged(int message) { 190 if (message == StatusListener.MESSAGE_DATABASE_LOADED) {162 if (message == MESSAGE_DATABASE_LOADED) { 191 163 czechMenu = Main.main.menu.addMenu("Adresy", KeyEvent.VK_A, 4); 192 164 menuItems.add(MainMenu.add(czechMenu, new PointManipulatorAction())); … … 198 170 } 199 171 172 if (message == MESSAGE_LOCATION_CHANGED) { 173 initReasoner(); 174 return; 175 } 176 177 200 178 // SelectionMonitor cannot be used because of synchronization problems. 201 179 /*if (message == MESSAGE_REASONER_REASONED) { -
applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/StatusListener.java
r15166 r15461 3 3 import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.AddressElement; 4 4 import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.Database; 5 import org.openstreetmap.josm.plugins.czechaddress.parser.DatabaseParser;6 5 import org.openstreetmap.josm.plugins.czechaddress.intelligence.Reasoner; 7 6 … … 67 66 * 68 67 * @see CzechAddressPlugin 69 * @see DatabaseParser70 68 * @see Database 71 69 */ -
applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/StringUtils.java
r15201 r15461 43 43 44 44 public static String latLonToString(LatLon position) { 45 assert position != null; 46 //if (position == null) return ""; 45 if (position == null) return ""; 47 46 48 47 return "(lat: " + coordinateToString(position.lat()) … … 83 82 } 84 83 84 /** 85 * Capitalizes the given string (first letter of every word upper-case, 86 * others lower-case). Czech grammar rules are more or less obeyed. 87 * 88 * <p><b>TODO:</b> This should be moved somewhere else.</p> 89 * 90 * @param s string to be capitalized 91 * @return capitaized string 92 */ 93 public static String capitalize(String s) { 94 95 if (s == null) 96 return s; 97 98 String result = ""; 99 100 char last = ' '; 101 for (char ch : s.toCharArray()) { 102 if ((last >= 'a') && (last <= 'ž') || 103 (last >= 'A') && (last <= 'Ž')) 104 ch = Character.toLowerCase(ch); 105 else 106 ch = Character.toTitleCase(ch); 107 108 last = ch; 109 result = result + ch; 110 } 111 112 String[] noCapitalize = { "Nad", "Pod", "U", "Na" }; 113 for (String noc : noCapitalize) 114 result = result.replaceAll(" "+noc+" ", " "+noc.toLowerCase()+" "); 115 116 return result; 117 } 118 85 119 } -
applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/actions/FactoryAction.java
r15166 r15461 11 11 import org.openstreetmap.josm.plugins.czechaddress.CzechAddressPlugin; 12 12 import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.House; 13 import org.openstreetmap.josm.plugins.czechaddress.intelligence.Reasoner;14 13 import org.openstreetmap.josm.plugins.czechaddress.proposal.ProposalContainer; 15 14 import org.openstreetmap.josm.tools.ImageProvider; … … 54 53 Main.map.mapView.addMouseListener(this); 55 54 56 Reasoner r = CzechAddressPlugin.getReasoner(); 57 58 if (r == null) { 55 if (CzechAddressPlugin.reasoner == null) { 59 56 exitMode(); 60 57 return; 61 58 } 62 59 63 FactoryDialog d = FactoryDialog.getInstance(); 64 if (r.translate(d.getSelectedHouse()) != null) 60 // Switch to next unassigned house. 61 FactoryDialog d = CzechAddressPlugin.factoryDialog; 62 if (CzechAddressPlugin.reasoner.translate(d.getSelectedHouse()) != null) 65 63 d.selectNextUnmatchedHouseByCheckBox(); 66 64 } … … 88 86 89 87 // Get the currently selected House in the FactoryDialog. 90 House house = FactoryDialog.getInstance().getSelectedHouse();88 House house = CzechAddressPlugin.factoryDialog.getSelectedHouse(); 91 89 if (house == null) 92 90 return; // TODO: Some meaningful messageBox would be useful. … … 99 97 container.applyAll(); 100 98 101 // Notify reasoner about this newly added node.102 CzechAddressPlugin.getReasoner().overwriteMatch(house, newNode);103 104 99 // And make the new node selected. 105 100 Main.ds.addPrimitive(newNode); 106 101 Main.ds.setSelected(newNode); 107 102 108 // And do not forget to select next House in the list.109 FactoryDialog.getInstance().selectNextUnmatchedHouseByCheckBox();103 CzechAddressPlugin.reasoner.overwriteMatch(house, newNode); 104 CzechAddressPlugin.factoryDialog.selectNextUnmatchedHouseByCheckBox(); 110 105 } 111 106 } -
applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/actions/ModifierAction.java
r15201 r15461 9 9 import java.awt.event.KeyEvent; 10 10 import org.openstreetmap.josm.actions.JosmAction; 11 import org.openstreetmap.josm.plugins.czechaddress.gui. DatabaseModifier;11 import org.openstreetmap.josm.plugins.czechaddress.gui.Renamer; 12 12 import org.openstreetmap.josm.tools.Shortcut; 13 13 … … 17 17 */ 18 18 public class ModifierAction extends JosmAction { 19 20 // DatabaseModifier modifier = null;21 19 22 20 public ModifierAction() { … … 31 29 32 30 public void actionPerformed(ActionEvent e) { 33 (new DatabaseModifier()).setVisible(true);31 (new Renamer()).setVisible(true); 34 32 } 35 33 } -
applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/addressdatabase/AddressElement.java
r15203 r15461 31 31 /** 32 32 * Constructor setting the name of this element. 33 *34 * <p><b>TODO:</b> The name is capitalized during the assignment,35 * because the database contains all names IN CAPITALS. However36 * this should not be done here, but in the {@link DatabaseParser}.</p>37 33 */ 38 34 public AddressElement (String name) { 39 35 if (name == null) 40 36 throw new NullPointerException("You must specify the name of this AddressElement"); 41 this.name = capitalize(name);37 this.name = name; 42 38 } 43 39 … … 166 162 167 163 /** 168 * Capitalizes the given string (first letter of every word upper-case,169 * others lower-case). Czech grammar rules are more or less obeyed.170 *171 * <p><b>TODO:</b> This should be moved somewhere else.</p>172 *173 * @param s string to be capitalized174 * @return capitaized string175 */176 protected static String capitalize(String s) {177 178 if (s == null)179 return s;180 181 String result = "";182 183 char last = ' ';184 for (char ch : s.toCharArray()) {185 if ((last >= 'a') && (last <= 'ž') ||186 (last >= 'A') && (last <= 'Ž'))187 ch = Character.toLowerCase(ch);188 else189 ch = Character.toTitleCase(ch);190 191 last = ch;192 result = result + ch;193 }194 195 String[] noCapitalize = { "Nad", "Pod", "U", "Na" };196 for (String noc : noCapitalize)197 result = result.replaceAll(" "+noc+" ", " "+noc.toLowerCase()+" ");198 199 return result;200 }201 202 /**203 164 * Compute differences between two strings. 204 165 * … … 248 209 public List<Proposal> getDiff(OsmPrimitive prim) { 249 210 return null; 211 } 212 213 public boolean isMatchable(OsmPrimitive prim) { 214 return false; 250 215 } 251 216 -
applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/addressdatabase/House.java
r15203 r15461 204 204 } 205 205 206 206 public boolean isMatchable(OsmPrimitive prim) { 207 208 for (String key : prim.keySet()) { 209 String value = prim.get(key); 210 if (value != null && value.startsWith("addr:")) 211 return true; 212 } 213 214 return false; 215 } 207 216 } -
applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/addressdatabase/Region.java
r15201 r15461 69 69 public Region(String name, String nuts3name, String nuts4name) { 70 70 super(name); 71 if (nuts3name != null) this.nuts3name = capitalize(nuts3name);72 if (nuts4name != null) this.nuts4name = capitalize(nuts4name);71 if (nuts3name != null) this.nuts3name = nuts3name; 72 if (nuts4name != null) this.nuts4name = nuts4name; 73 73 } 74 74 -
applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/gui/ConflictResolver.java
r15166 r15461 258 258 if (best != null) best.qualityChanged(); 259 259 260 List<Match> competitors = r. getConflicts((OsmPrimitive) selMainObj);260 List<Match> competitors = r.conflicts((OsmPrimitive) selMainObj); 261 261 if (competitors != null) for (Match competitor : competitors) 262 262 competitor.qualityChanged(); … … 271 271 if (best != null) best.qualityChanged(); 272 272 273 List<Match> competitors = r. getConflicts((AddressElement) selMainObj);273 List<Match> competitors = r.conflicts((AddressElement) selMainObj); 274 274 if (competitors != null) for (Match competitor : competitors) 275 275 competitor.qualityChanged(); … … 333 333 334 334 if (parent instanceof AddressElement) 335 return r. getConflicts((AddressElement) parent).get(index).prim;335 return r.conflicts((AddressElement) parent).get(index).prim; 336 336 337 337 } catch (Exception e) { } … … 347 347 348 348 if (parent instanceof AddressElement) 349 return r. getConflicts((AddressElement) parent).size();349 return r.conflicts((AddressElement) parent).size(); 350 350 351 351 } catch (Exception exp) { } … … 361 361 362 362 if (parent instanceof AddressElement) 363 return r. getConflicts((AddressElement) parent).indexOf(child);363 return r.conflicts((AddressElement) parent).indexOf(child); 364 364 365 365 } catch (Exception exp) { } … … 383 383 384 384 if (parent instanceof OsmPrimitive) 385 return r.getConflicts ((OsmPrimitive) parent).get(index).elem;385 return r.getConflictsconflictsve) parent).get(index).elem; 386 386 387 387 } catch (Exception exp) { } … … 397 397 return r.getPrimitivesInConflict().size(); 398 398 if (parent instanceof OsmPrimitive) 399 return r.getConflicts ((OsmPrimitive) parent).size();399 return r.getConflictsconflictsve) parent).size(); 400 400 401 401 } catch (Exception exp) { } … … 412 412 413 413 } else if (parent instanceof OsmPrimitive) 414 return r.getConflicts ((OsmPrimitive) parent).indexOf(child);414 return r.getConflictsconflictsve) parent).indexOf(child); 415 415 416 416 } catch (Exception exp) { } -
applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/gui/FactoryDialog.form
r15166 r15461 1 1 <?xml version="1.0" encoding="UTF-8" ?> 2 2 3 <Form version="1.3" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">3 <Form version="1.3" maxVersion="1.3" type="org.netbeans.modules.form.forminfo.JPanelFormInfo"> 4 4 <AuxValues> 5 5 <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/> … … 26 26 <Group type="103" groupAlignment="0" attributes="0"> 27 27 <Group type="102" attributes="0"> 28 <Component id="streetComboBox" pref=" 50" max="32767" attributes="0"/>28 <Component id="streetComboBox" pref="92" max="32767" attributes="0"/> 29 29 <EmptySpace max="-2" attributes="0"/> 30 30 <Component id="relocateButton" min="-2" max="-2" attributes="0"/> … … 33 33 </Group> 34 34 <Group type="102" alignment="0" attributes="0"> 35 <Component id="keepOddityCheckBox" pref="2 82" max="32767" attributes="0"/>35 <Component id="keepOddityCheckBox" pref="278" max="32767" attributes="0"/> 36 36 <EmptySpace max="-2" attributes="0"/> 37 37 </Group> -
applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/gui/FactoryDialog.java
r15166 r15461 37 37 implements SelectionChangedListener, StatusListener { 38 38 39 private static FactoryDialog singleton = null;40 public static FactoryDialog getInstance() {41 if (singleton == null)42 singleton = new FactoryDialog();43 return singleton;44 }45 46 47 39 HouseListModel houseModel = new HouseListModel(); 48 40 StreetListModel streetModel = new StreetListModel(); … … 65 57 add(mainPanel); 66 58 67 // Register to all listeners59 // Register to all messages 68 60 CzechAddressPlugin.addStatusListener(this); 69 61 … … 94 86 keepOddityCheckBox.setEnabled(true); 95 87 return; 96 97 88 } 98 89 … … 115 106 116 107 public boolean existsAvailableHouse() { 117 Reasoner r = CzechAddressPlugin. getReasoner();108 Reasoner r = CzechAddressPlugin.reasoner; 118 109 119 110 int i = houseList.getSelectedIndex(); … … 136 127 public void selectNextUnmatchedHouse() { 137 128 138 Reasoner r = CzechAddressPlugin.getReasoner();139 129 int index = houseList.getSelectedIndex(); 140 130 … … 142 132 Object current; 143 133 while ( (current = houseModel.getElementAt(index)) != null 144 &&r.translate((House) current) != null)134 && CzechAddressPlugin.reasoner.translate((House) current) != null) 145 135 index++; 146 136 … … 326 316 private void houseListClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_houseListClicked 327 317 if (evt.getClickCount() == 2 && evt.getButton() == MouseEvent.BUTTON1) { 328 Reasoner r = CzechAddressPlugin. getReasoner();318 Reasoner r = CzechAddressPlugin.reasoner; 329 319 330 320 if (r.translate(getSelectedHouse()) != null) { … … 347 337 348 338 private void ensureConsistencyButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ensureConsistencyButtonActionPerformed 349 CzechAddressPlugin. getReasoner().ensureConsistency();339 CzechAddressPlugin.reasoner.ensureConsistency(); 350 340 }//GEN-LAST:event_ensureConsistencyButtonActionPerformed 351 341 … … 405 395 if (boldFont == null) boldFont = getFont().deriveFont(Font.BOLD); 406 396 407 Reasoner r = CzechAddressPlugin. getReasoner();397 Reasoner r = CzechAddressPlugin.reasoner; 408 398 409 399 if (value instanceof House) { … … 413 403 setFont(plainFont); 414 404 415 if ( r. getConflicts(house) != null)405 if ( r.conflicts(house) != null) 416 406 setIcon(envelopeExclIcon); 417 407 else if ( r.translate(house) == null) { … … 457 447 458 448 public void rebuild() { 459 Reasoner r = CzechAddressPlugin. getReasoner();449 Reasoner r = CzechAddressPlugin.reasoner; 460 450 if (r == null) return; 461 451 -
applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/gui/PointManipulatorDialog.java
r15203 r15461 368 368 if (match.elem instanceof House) { 369 369 setIcon(envelopeStarIcon); 370 if ( r. getConflicts(match.elem) != null )370 if ( r.conflicts(match.elem) != null ) 371 371 setIcon(envelopeExclIcon); 372 372 else if ( r.translate(match.elem) != null) -
applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/gui/Renamer.java
r15203 r15461 5 5 6 6 /* 7 * DatabaseModifier.java7 * Renamer.java 8 8 * 9 9 * Created on 24.5.2009, 18:03:35 … … 31 31 * @author radek 32 32 */ 33 public class DatabaseModifier extends ExtendedDialog {33 public class Renamer extends ExtendedDialog { 34 34 35 35 StreetModel<Street> streetModel = new StreetModel<Street>(); 36 36 37 /** Creates new form DatabaseModifier */38 public DatabaseModifier() {37 /** Creates new form Renamer */ 38 public Renamer() { 39 39 40 40 super(Main.parent, "Upravit databázi", -
applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/gui/UniversalTreeRenderer.java
r15166 r15461 65 65 66 66 67 if (value instanceof House ) {67 if (value instanceof House && r != null) { 68 68 House house = (House) value; 69 69 70 70 setIcon(envelopeNormIcon); 71 if ( r. getConflicts(house) != null )71 if ( r.conflicts(house) != null ) 72 72 setIcon(envelopeExclIcon); 73 73 else if ( r.translate(house) == null) -
applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/intelligence/Match.java
r15166 r15461 2 2 3 3 import java.util.List; 4 import org.openstreetmap.josm.data.osm.Node; 4 import java.util.logging.Level; 5 import java.util.logging.Logger; 5 6 import org.openstreetmap.josm.data.osm.OsmPrimitive; 6 7 import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.AddressElement; … … 20 21 public static final int MATCH_NOMATCH = 0; 21 22 22 public int q uality;23 public int qVal; 23 24 public OsmPrimitive prim; 24 25 public AddressElement elem; 25 26 26 27 public String checkSum; 28 public static Logger logger = Logger.getLogger("Match"); 27 29 28 30 public Match(AddressElement element, OsmPrimitive primitive, … … 30 32 31 33 assert primitive != null; 32 assert element != null; 33 assert qualityFactor <= MATCH_OVERWRITE; 34 assert qualityFactor > MATCH_NOMATCH 35 : "MATCH_NOMATCH represents no relation." 36 + "It's pointless to waste memory for it."; 37 34 assert element != null; 38 35 assert !primitive.deleted; 39 36 40 37 prim = primitive; 41 38 elem = element; 42 quality = qualityFactor; 43 44 checkSum = toString(); 39 qVal = qualityFactor; 45 40 } 46 41 … … 53 48 54 49 int quality = element.getMatchQuality(primitive); 50 51 logger.log(Level.FINE, "asked to create match", 52 new Object[] {element, primitive, quality}); 53 55 54 if (quality > MATCH_NOMATCH) 56 55 return new Match(element, primitive, quality); … … 58 57 return null; 59 58 } 59 /* 60 public boolean setQ(int desiredQ) { 61 int oldQ = evalQ(); 62 qVal = desiredQ; 63 int newQ = evalQ(); 60 64 61 public boolean qualityChanged() { 62 int newQuality 63 = prim.deleted ? MATCH_NOMATCH 64 : quality == MATCH_OVERWRITE ? MATCH_OVERWRITE 65 : elem.getMatchQuality(prim); 66 if (prim instanceof Node) { 67 Node node = (Node) prim; 68 if (node.coor == null || node.eastNorth == null) { 69 newQuality = MATCH_NOMATCH; 70 System.out.println("Suspicious node, ignoring it: " + AddressElement.getName(node)); 71 } 72 } 73 65 if (oldQ != newQ) 66 logger.log(Level.INFO, "changing match value: " + oldQ + " --> " + newQ 67 + " (desired value is " + desiredQ + ")", this); 68 return oldQ != evalQ(); 69 } 70 */ 71 public static int evalQ(OsmPrimitive prim, AddressElement elem, Integer oldQ) { 74 72 75 boolean difference = newQuality != quality;76 quality = newQuality;73 if (prim.deleted) 74 return MATCH_NOMATCH; 77 75 78 return difference; 76 if (oldQ == MATCH_OVERWRITE) 77 return MATCH_OVERWRITE; 78 79 return elem.getMatchQuality(prim); 79 80 } 80 81 81 82 @Override 82 83 public String toString() { 83 return "{Match: q=" + String.valueOf(q uality)84 return "{Match: q=" + String.valueOf(qVal) 84 85 + "; elem='" + elem.toString() 85 86 +"'; prim='" + AddressElement.getName(prim) + "'}"; -
applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/intelligence/Reasoner.java
r15166 r15461 1 1 package org.openstreetmap.josm.plugins.czechaddress.intelligence; 2 2 3 import java.util.ArrayList;4 import java.util.Collection;5 3 import java.util.HashMap; 6 import java.util.List; 4 import java.util.HashSet; 5 import java.util.Map; 6 import java.util.Set; 7 import java.util.logging.FileHandler; 8 import java.util.logging.Handler; 9 import java.util.logging.Level; 10 import java.util.logging.Logger; 11 import org.openstreetmap.josm.data.osm.Node; 7 12 import org.openstreetmap.josm.data.osm.OsmPrimitive; 8 import org.openstreetmap.josm.plugins.czechaddress.CzechAddressPlugin;9 import org.openstreetmap.josm.plugins.czechaddress.NotNullList;10 import org.openstreetmap.josm.plugins.czechaddress.StatusListener;11 13 import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.AddressElement; 12 14 import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.House; 13 import org.openstreetmap.josm.plugins.czechaddress.proposal.ProposalContainer; 14 import org.openstreetmap.josm.plugins.czechaddress.proposal.ProposalDatabase; 15 import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.Street; 15 16 16 17 /** … … 34 35 public class Reasoner { 35 36 36 /** A database of all matches, which are not in a conflict. */ 37 private NotNullList<Match> matches = new NotNullList<Match>(); 38 39 /** A list of {@link Match}es, which are in a conflict. */ 40 private NotNullList<Match> conflicts = new NotNullList<Match>(); 41 42 /** A list of {@link House}s, which have not yet been matched to any 43 * {@link OsmPrimitive} without a conflict. */ 44 private ArrayList<AddressElement> elemPool = new ArrayList<AddressElement>(); 45 46 /** A list of {@link OsmPrimitive}s, for which there was no suitable match. */ 47 private List<OsmPrimitive> notMatchable = new ArrayList<OsmPrimitive>(); 48 49 private HashMap<OsmPrimitive, Match> primMatchHashIndex 50 = new HashMap<OsmPrimitive, Match>(); 51 private HashMap<AddressElement, Match> elemMatchHashIndex 52 = new HashMap<AddressElement, Match>(); 53 54 private List<OsmPrimitive> primConflictListIndex = new ArrayList<OsmPrimitive>(); 55 private List<AddressElement> elemConflictListIndex = new ArrayList<AddressElement>(); 56 private HashMap<OsmPrimitive, List<Match>> primConflictHashIndex 57 = new HashMap<OsmPrimitive, List<Match>>(); 58 private HashMap<AddressElement, List<Match>> elemConflictHashIndex 59 = new HashMap<AddressElement, List<Match>>(); 60 61 62 /** 63 * Default constructor, which initializes the pool of 64 * {@link AddressElement}s to be used for matching. 65 */ 66 public Reasoner(ArrayList<AddressElement> elementPool) { 67 elemPool = elementPool; 68 } 69 70 /** 71 * Adds a single new primitive to the database, finds corresponding 72 * {@link House} for it and seeks for potential conflicts. 73 * 74 * <p>If you intend to add a list of new primitives, {@link addPrimitives} 75 * will be faster, because conflicts are traced after adding all the 76 * primitives and not after every single one.</p> 77 * 78 * <p>Moreover there is one substantial difference discussed in 79 * {@link addPrimitives()}.</p> 80 * 81 * @param newPrimitive new primitive to be added 82 */ 83 public synchronized void addPrimitive(OsmPrimitive newPrimitive) { 84 85 int firstNewIndex = matches.size(); 86 87 matchPrimitive(newPrimitive); 37 /* A list of {@link OsmPrimitive}s, for which there was no suitable match. */ 38 //private List<OsmPrimitive> notMatchable = new ArrayList<OsmPrimitive>(); 39 40 private Map<OsmPrimitive, AddressElement> primBestIndex 41 = new HashMap<OsmPrimitive, AddressElement> (); 42 private Map<AddressElement, OsmPrimitive> elemBestIndex 43 = new HashMap<AddressElement, OsmPrimitive> (); 44 45 private Map<OsmPrimitive, Map<AddressElement, Integer>> primMatchIndex 46 = new HashMap<OsmPrimitive, Map<AddressElement, Integer>> (); 47 private Map<AddressElement, Map<OsmPrimitive, Integer>> elemMatchIndex 48 = new HashMap<AddressElement, Map<OsmPrimitive, Integer>> (); 49 50 private Set<OsmPrimitive> primToUpdate = new HashSet<OsmPrimitive>(); 51 private Set<AddressElement> elemToUpdate = new HashSet<AddressElement>(); 52 // private Map<Object,Integer> statusBefore = new HashMap<Object,Integer>(); 53 54 public Logger logger = Logger.getLogger("Reasoner"); 55 56 public static final int STATUS_UNKNOWN = 0; 57 public static final int STATUS_CONFLICT = 1; 58 public static final int STATUS_MATCH = 2; 59 60 private Reasoner() {} 61 private static Reasoner singleton = null; 62 public static Reasoner getInstance() { 63 if (singleton == null) 64 singleton = new Reasoner(); 65 return singleton; 66 } 67 68 public void reset() { 69 primToUpdate.clear(); 70 elemToUpdate.clear(); 71 72 primMatchIndex.clear(); 73 elemMatchIndex.clear(); 74 primBestIndex.clear(); 75 primBestIndex.clear(); 76 } 77 78 private AddressElement getBest(OsmPrimitive prim) { 79 80 Map<AddressElement, Integer> matches = primMatchIndex.get(prim); 81 if (matches == null) return null; 82 83 AddressElement bestE = null; 84 int bestQ = Match.MATCH_NOMATCH; 85 86 for (AddressElement elem : matches.keySet()) { 87 if (matches.get(elem) == bestQ) 88 bestE = null; 89 90 if (matches.get(elem) > bestQ) { 91 bestQ = matches.get(elem); 92 bestE = elem; 93 } 94 } 95 96 return bestE; 97 } 98 99 private OsmPrimitive getBest(AddressElement prim) { 100 101 Map<OsmPrimitive, Integer> matches = elemMatchIndex.get(prim); 102 if (matches == null) return null; 103 104 OsmPrimitive bestE = null; 105 int bestQ = Match.MATCH_NOMATCH; 106 107 for (OsmPrimitive elem : matches.keySet()) { 108 if (matches.get(elem) == bestQ) 109 bestE = null; 110 111 if (matches.get(elem) > bestQ) { 112 bestQ = matches.get(elem); 113 bestE = elem; 114 } 115 } 116 117 return bestE; 118 } 119 120 public void openTransaction() { 121 assert primToUpdate.size() == 0; 122 assert elemToUpdate.size() == 0; 123 } 124 125 public void closeTransaction() { 126 127 Set<Object> changes = new HashSet<Object>(); 128 129 for (OsmPrimitive prim : primToUpdate) { 130 AddressElement bestMatch = getBest(prim); 131 132 if (primBestIndex.get(prim) != bestMatch) { 133 if (bestMatch == null) { 134 logger.log(Level.INFO, "primitive has no longer best match", 135 AddressElement.getName(prim)); 136 primBestIndex.remove(prim); 137 } else { 138 logger.log(Level.INFO, "primitive has a new best match", 139 "prim=„" + AddressElement.getName(prim) + "“ → " + 140 "elem=„" + bestMatch + "“"); 141 primBestIndex.put(prim, bestMatch); 142 } 143 changes.add(prim); 144 } 145 } 146 primToUpdate.clear(); 147 148 149 for (AddressElement elem : elemToUpdate) { 150 OsmPrimitive bestMatch = getBest(elem); 151 152 if (elemBestIndex.get(elem) != bestMatch) { 153 if (bestMatch == null) { 154 logger.log(Level.INFO, "element has no longer best match", elem); 155 elemBestIndex.remove(elem); 156 } else { 157 logger.log(Level.INFO, "element has a new best match", 158 "elem=„" + elem + "“ → " + 159 "prim=„" + AddressElement.getName(bestMatch) + "“"); 160 elemBestIndex.put(elem, bestMatch); 161 } 162 changes.add(elem); 163 } 164 } 165 elemToUpdate.clear(); 166 167 for (Object change : changes) { 168 if (change instanceof OsmPrimitive) 169 for (ReasonerListener listener : listeners) 170 listener.primitiveChanged((OsmPrimitive) change); 171 172 if (change instanceof AddressElement) 173 for (ReasonerListener listener : listeners) 174 listener.elementChanged((AddressElement) change); 175 } 176 } 177 178 private Set<ReasonerListener> listeners = new HashSet<ReasonerListener>(); 179 180 public void reconsider(OsmPrimitive prim, AddressElement elem) { 181 182 int oldQ = getQ(prim, elem); 183 int newQ = Match.evalQ(prim, elem, oldQ); 184 185 if (oldQ != newQ) { 186 logger.log(Level.INFO, "reconsidering match", 187 "q=" + String.valueOf(oldQ) + "→" + String.valueOf(newQ) + "; " + 188 "elem=„" + elem + "“; " + 189 "prim=„" + AddressElement.getName(prim) + "“"); 190 putQ(prim, elem, newQ); 191 192 primToUpdate.add(prim); 193 elemToUpdate.add(elem); 194 } 195 } 196 197 public void consider(OsmPrimitive prim) { 198 logger.log(Level.FINE, "considering primitive", AddressElement.getName(prim)); 199 200 Map<AddressElement, Integer> matches = primMatchIndex.get(prim); 201 if (matches == null) { 202 logger.log(Level.INFO, "new primitive detected", AddressElement.getName(prim)); 203 matches = new HashMap<AddressElement, Integer>(); 204 primMatchIndex.put(prim, matches); 205 } 206 207 for (AddressElement elem : elemMatchIndex.keySet()) 208 reconsider(prim, elem); 209 } 210 211 public void consider(AddressElement elem) { 212 logger.log(Level.FINE, "considering element", elem); 213 214 Map<OsmPrimitive, Integer> matches = elemMatchIndex.get(elem); 215 if (matches == null) { 216 logger.log(Level.INFO, "new element detected", elem); 217 matches = new HashMap<OsmPrimitive, Integer>(); 218 elemMatchIndex.put(elem, matches); 219 } 220 221 for (OsmPrimitive prim : primMatchIndex.keySet()) 222 reconsider(prim, elem); 223 } 224 225 /*private int getStatus(OsmPrimitive prim) { 226 if (primMatchIndex.get(prim) == null) return STATUS_UNKNOWN; 227 if (primMatchIndex.get(prim).size()==0) return STATUS_UNKNOWN; 228 if (translate(prim) != null) return STATUS_MATCH; 229 return STATUS_CONFLICT; 230 } 231 232 private int getStatus(AddressElement elem) { 233 if (elemMatchIndex.get(elem) == null) return STATUS_UNKNOWN; 234 if (elemMatchIndex.get(elem).size()==0) return STATUS_UNKNOWN; 235 if (translate(elem) != null) return STATUS_MATCH; 236 return STATUS_CONFLICT; 237 }*/ 238 239 public int getQ(OsmPrimitive prim, AddressElement elem) { 240 if (primMatchIndex.get(prim) == null) return 0; 241 if (elemMatchIndex.get(elem) == null) return 0; 242 243 assert primMatchIndex.get(prim).get(elem) == elemMatchIndex.get(elem).get(prim); 244 245 if (primMatchIndex.get(prim).get(elem) == null) 246 return 0; 247 else 248 return primMatchIndex.get(prim).get(elem); 249 } 250 251 public void putQ(OsmPrimitive prim, AddressElement elem, int qVal) { 88 252 89 ensureConsistency(firstNewIndex); 90 } 91 92 /** 93 * Adds new primitives to the database, finds suitable {@link House}s for 94 * them and afterwards seeks for potential conflicts. 95 * 96 * <p><b>NOTE:</b> Adding primitives through {@code addPrimitives()} has 97 * different effect from adding primitives one by one through 98 * {@code addPrimitive()}.</p> 99 * 100 * <p>The preffered way of handling this is to add a large bunch of elements 101 * from the database via {@code addPrimitives()}, because the possible 102 * conflicts are between all possible element-primitive combinations. 103 * For adding single node by user, {@code addPrimitives()} is the preferred 104 * way, because immediatelly after the matching the best suitable element 105 * is removed from the element pool and it cannot be matched to any other 106 * primitive.</p> 107 */ 108 public synchronized void addPrimitives(Collection<OsmPrimitive> newPrimitives) { 109 110 int firstNewIndex = matches.size(); 111 112 for (OsmPrimitive primitive : newPrimitives) 113 matchPrimitive(primitive); 114 115 ensureConsistency(firstNewIndex); 116 } 117 118 /** 119 * Removes the given primitive from the database and cancels all conflicts 120 * which can be solved by this removal. 121 */ 122 public synchronized void removePrimitive(OsmPrimitive primitive) { 123 124 // TODO: Implement the removal of a primitive 125 } 126 127 /** 128 * Forcibly matches given house to given primitive. 129 * 130 * <p>This can be useful in cases, where the user manually resolves 131 * a conflict by stating that this particular combination of 132 * house-primitive it the correct one.</p> 133 * 134 * <p>The quality is set to {@link Match}{@code .MATCH_OVERWRITE}.</p> 135 */ 136 public synchronized void overwriteMatch(AddressElement elem, OsmPrimitive prim) { 137 138 int firstNewIndex = matches.size(); 139 140 matches.add(new Match(elem, prim, Match.MATCH_OVERWRITE)); 141 matchesDirty = true; 142 143 reconsider(elem); 144 reconsider(prim); 145 146 ensureConsistency(firstNewIndex); 147 } 148 149 /** 150 * Returns all elements available for matching. 151 */ 152 public List<AddressElement> getElementPool() { 153 return elemPool; 154 } 155 156 /** Returns all primitives, which have not been assigned any element during 157 * the matching. */ 158 public List<OsmPrimitive> getNotMatchable() { 159 return notMatchable; 160 } 161 162 public List<Match> getAllMatches() { 163 164 return matches; 165 } 166 167 public Match findMatch(OsmPrimitive prim) { 168 return primMatchHashIndex.get(prim); 169 } 170 171 public Match findMatch(AddressElement elem) { 172 return primMatchHashIndex.get(elem); 173 } 174 175 /** 176 * Finds given primitive in list of {@code matches} and returns 177 * the corresponding element. 178 * 179 * <p>If the primitive is not found, {@code null} is returned.</p> 180 */ 253 if (qVal == Match.MATCH_NOMATCH) { 254 primMatchIndex.get(prim).remove(elem); 255 elemMatchIndex.get(elem).remove(prim); 256 257 if (primMatchIndex.get(prim).size() == 0) 258 primMatchIndex.put(prim, null); 259 if (elemMatchIndex.get(elem).size() == 0) 260 elemMatchIndex.put(elem, null); 261 262 } else { 263 primMatchIndex.get(prim).put(elem, qVal); 264 elemMatchIndex.get(elem).put(prim, qVal); 265 } 266 } 267 181 268 public AddressElement translate(OsmPrimitive prim) { 182 Match m = primMatchHashIndex.get(prim); 183 if (m == null) return null; 184 return m.elem; 185 } 186 187 /** 188 * Finds given element in list of {@code matches} and returns the corresponding 189 * primitive. 190 * 191 * <p>If the element is not found, {@code null} is returned.</p> 192 */ 269 AddressElement elem = primBestIndex.get(prim); 270 if (elemBestIndex.get(elem) == prim) 271 return elem; 272 return null; 273 } 274 193 275 public OsmPrimitive translate(AddressElement elem) { 194 Match m = elemMatchHashIndex.get(elem); 195 if (m == null) return null; 196 return m.prim; 197 } 198 199 /** 200 * Returns a list all conflicts corresponding to the given {@link AddressElement}. 201 */ 202 public List<Match> getConflicts(AddressElement elem) { 203 return elemConflictHashIndex.get(elem); 204 } 205 206 /** 207 * Returns a list all conflicts corresponding to the given {@link OsmPrimitive}. 208 */ 209 public List<Match> getConflicts(OsmPrimitive prim) { 210 return primConflictHashIndex.get(prim); 211 } 212 213 /** 214 * Returns a sorted list of all elements in conflict. 215 */ 216 public List<AddressElement> getElementsInConflict() { 217 return elemConflictListIndex; 218 } 219 220 /** 221 * Returns a sorted list of all primitives in conflict. 222 */ 223 public List<OsmPrimitive> getPrimitivesInConflict() { 224 return primConflictListIndex; 225 } 226 227 /** 228 * Returns the list of all conflicts. 229 */ 230 public List<Match> getAllConflicts() { 231 return conflicts; 232 } 233 234 /** 235 * Goes through all matches and returns proposals for changing 236 * every primitive (if it differs from the matched element). 237 */ 238 public ProposalDatabase getProposals() { 239 240 ProposalDatabase proposals = new ProposalDatabase(); 241 242 for (Match match : matches) { 276 OsmPrimitive prim = elemBestIndex.get(elem); 277 if (primBestIndex.get(prim) == elem) 278 return prim; 279 return null; 280 } 281 282 public Set<AddressElement> conflicts(OsmPrimitive prim) { 283 284 Set<AddressElement> result = new HashSet<AddressElement>(); 285 result.addAll(primMatchIndex.get(prim).keySet()); 286 287 AddressElement match = translate(prim); 288 if (match != null) 289 result.remove(match); 290 291 return result; 292 } 293 294 public Set<OsmPrimitive> conflicts(AddressElement elem) { 295 296 Set<OsmPrimitive> result = new HashSet<OsmPrimitive>(); 297 result.addAll(elemMatchIndex.get(elem).keySet()); 298 299 OsmPrimitive match = translate(elem); 300 if (match != null) 301 result.remove(match); 302 303 return result; 304 } 305 306 public static void main(String[] args) { 307 try { 308 309 Reasoner r = new Reasoner(); 310 311 Handler h = new FileHandler("log.xml"); 312 313 r.logger.addHandler(h); 314 r.logger.setLevel(Level.ALL); 243 315 244 ProposalContainer proposalContainer 245 = new ProposalContainer(match.prim); 316 Match.logger.addHandler(h); 317 Match.logger.setLevel(Level.ALL); 318 319 320 Street s1 = new Street("Jarní"); 321 Street s2 = new Street("Letní"); 322 323 House h1 = new House("240", "1"); s1.addHouse(h1); r.consider(h1); 324 House h2 = new House("241", "2"); s1.addHouse(h2); r.consider(h2); 325 House h3 = new House("241", "3"); s1.addHouse(h3); r.consider(h3); 326 House h4 = new House("242", "4"); s1.addHouse(h4); r.consider(h4); 327 328 House i1 = new House("42", "1"); s2.addHouse(i1); r.consider(i1); 329 House i2 = new House("45", "2"); s2.addHouse(i2); r.consider(i2); 330 House i3 = new House("61", "3"); s2.addHouse(i3); r.consider(i3); 331 House i4 = new House("240", "4"); s2.addHouse(i4); r.consider(i4); 332 333 246 334 247 proposalContainer.addProposals(match.getDiff()); 248 249 if (proposalContainer.getProposals().size() > 0) 250 proposals.addContainer(proposalContainer); 251 } 252 253 return proposals; 254 } 255 256 /** 257 * Finds suitable {@code Match}es in the pool of {@link AddressElement}s. 258 * 259 * @param primitive the primitive to be matched with elements of 260 * {@code elemPool}. 261 * @return the list of all matches, whose <i>quality</i> > 262 * {@link Match}{@code .MATCH_NOMATCH}. 263 */ 264 public NotNullList<Match> getMatchesForPrimitive(OsmPrimitive primitive) { 265 266 NotNullList<Match> result = new NotNullList<Match>(); 267 268 for (AddressElement elem : elemPool) 269 result.add(Match.createMatch(elem, primitive)); 270 return result; 271 } 272 273 /** 274 * Method for adding matches for a single primitive into the resoner. 275 * 276 * <p>This method uses {@code getMatchesForPrimitive()} for getting the 277 * list of suitable matches for the given primitive. Then it selects 278 * <u>all</u> matches with the highest {@code quality} and adds them 279 * into the {@code matches} list. 280 */ 281 protected void matchPrimitive(OsmPrimitive prim) { 282 boolean assertions = false; 283 assert assertions = true; 284 285 if (prim.deleted) return; 286 287 NotNullList<Match> suitable = getMatchesForPrimitive(prim); 288 NotNullList<Match> toDelete = new NotNullList<Match>(suitable.size()); 289 290 for (Match match1 : suitable) 291 for (Match match2 : suitable) 292 if ( match1 != match2 293 && match1.quality > match2.quality) { 294 toDelete.add(match2); 295 if (assertions) 296 System.out.println("Reasoner: Dominated match: " + match2.toString()); 297 } 298 299 suitable.removeAll(toDelete); 300 301 // Make sure we reconsider all elements. 302 for (Match match : matches) { 303 reconsider(match.elem); 304 reconsider(match.prim); 305 } 306 307 if (suitable.size() > 0) { 308 matches.addAll(suitable); 309 matchesDirty = true; 310 } else 311 notMatchable.add(prim); 312 } 313 314 //============================================================================== 315 // MESSAGE HANDLING SYSTEM 316 //============================================================================== 317 318 /** 319 * Should be true whenever {@code matches} have changed, but the 320 * {@link StatusListener}{@code .MESSAGE_MATCHES_CHANGED} message has 321 * not yet been sent. 322 */ 323 protected boolean matchesDirty = false; 324 325 /** 326 * Should be true whenever {@code conflicts} have changed, but the 327 * {@link StatusListener}{@code .MESSAGE_CONFLICT_CHANGED} message has 328 * not yet been sent. 329 */ 330 protected boolean conflictsDirty = false; 331 332 /** 333 * Broadcasts information about the changes of reasoner status. 334 * 335 * <p>If the {@code matchesDirty} or {@code conflictsDirty} flag is 336 * {@link true}, this method informs all listeners about the change 337 * of plugin's status.</p> 338 */ 339 protected void handleDirt() { 340 341 if (matchesDirty || conflictsDirty) 342 regenerateIndexes(); 343 344 if (matchesDirty) CzechAddressPlugin.broadcastStatusChanged( 345 StatusListener.MESSAGE_MATCHES_CHANGED); 346 347 if (conflictsDirty) CzechAddressPlugin.broadcastStatusChanged( 348 StatusListener.MESSAGE_CONFLICT_CHANGED); 349 350 matchesDirty = conflictsDirty = false; 351 } 352 353 //============================================================================== 354 // CONSISTENCY CHECKING 355 //============================================================================== 356 357 /** 358 * Should be called after modifying <b>anything</b> to put reasoner into 359 * consistent state. 360 * 361 * <p>This method should be called at the end of every public method, 362 * which changes anything in the reasoner.</p> 363 */ 364 public void ensureConsistency() { 365 ensureConsistency(0); 366 } 367 368 /** 369 * Should be called after modifying <b>anything</b> to put reasoner into 370 * consistent state. 371 * 372 * <p>This method should be called at the end of every public method, 373 * which changes anything in the reasoner.</p> 374 * 375 * <p>Checking every match with every match is computationally inefficient. 376 * Therefore by specifying {@code startElementIndex > 0}, we can 377 * reduce this cost by checking <i>every match</i> with <i>every match, 378 * whose index is greater than {@code startElementIndex}.</p> 379 */ 380 public void ensureConsistency(int startElementIndex) { 381 startElementIndex = 0; 382 383 NotNullList<Match> toDel = new NotNullList<Match>(10); 384 for (Match match1 : matches) for (Match match2 : matches) { 385 386 if (match1 == match2) continue; 387 388 if (match1.prim == match2.prim && match1.quality > match2.quality) { 389 System.out.println("Reasoner: Redundancy clean: " + match2); 390 toDel.add(match2); 391 matchesDirty = true; 392 } 393 394 if (match1.prim == match2.prim && match1.quality >= match2.quality 395 && match1.elem == match2.elem && !toDel.contains(match1)) { 396 System.out.println("Reasoner: Hyper redundancy: " + match2); 397 toDel.add(match2); 398 matchesDirty = true; 399 } 400 } 401 matches.removeAll(toDel); 402 403 toDel.clear(); 404 for (Match conflict1 : conflicts) for (Match conflict2 : conflicts) { 405 406 if (conflict1 == conflict2) continue; 407 408 if (conflict1.prim == conflict2.prim 409 && conflict1.elem == conflict2.elem && !toDel.contains(conflict1)) { 410 System.out.println("Reasoner: Confl redundancy: " + conflict2); 411 toDel.add(conflict2); 412 conflictsDirty = true; 413 } 414 } 415 conflicts.removeAll(toDel); 416 417 for (Match match : matches) 418 for (Match conflict : conflicts) { 419 assert match != conflict; 420 assert match.prim != conflict.prim; 421 } 422 423 424 425 if (handleDeletedPrimitivesSlowButSafe()) 426 startElementIndex = 0; 427 handleInconsistentMatches(startElementIndex); 428 handleDirt(); 429 430 CzechAddressPlugin.broadcastStatusChanged( 431 StatusListener.MESSAGE_REASONER_REASONED); 432 } 433 434 /** 435 * Finds conflicts in the {@code matches} list and moves them to 436 * {@code conflicts} list. 437 */ 438 protected void handleInconsistentMatches(int startElementIndex) { 439 boolean assertions = false; 440 assert assertions = true; 441 442 443 // Move all conflicting matches into 'conflicts' array. 444 int pos1 = 0; 445 while (pos1 < matches.size()) { 446 447 int pos2 = Math.max(pos1 + 1, startElementIndex); 448 while (pos2 < matches.size()) { 449 450 Match item1 = matches.get(pos1); 451 Match item2 = matches.get(pos2); 452 453 if ((item1.elem == item2.elem) || (item1.prim == item2.prim)) { 454 455 if (assertions) { 456 System.out.println("1. match in conflict: " + item2); 457 System.out.println("2. match in conflict: " + item1); 458 } 459 460 if (item1.quality >= item2.quality) { 461 if (assertions) 462 System.out.println("1. match moved to 'conflicts'."); 463 matches.remove(pos2); 464 conflicts.add(item2); 465 matchesDirty = conflictsDirty = true; 466 pos2--; 467 } 468 469 if (item1.quality <= item2.quality) { 470 if (assertions) { 471 System.out.println("2. match moved to 'conflicts'."); 472 System.out.println("----------------------------------------------------------------------"); 473 } 474 matches.remove(pos1); 475 conflicts.add(item1); 476 matchesDirty = conflictsDirty = true; 477 pos1--; 478 break; 479 } 480 481 if (assertions) 482 System.out.println("----------------------------------------------------------------------"); 483 } 484 485 pos2++; 486 } 487 pos1++; 488 } 489 } 490 491 /** 492 * Seeks and handles primitives, which have been deleted. 493 * 494 * <p>If a primitive has been deleted, the first immediate action is to 495 * remove it from the {@code matches} and {@code conflicts} lists. 496 * However there might be another conflict, which was caused by the 497 * deleted primitive. This method finds such conflicts and 498 * moves them back to {@code matches} list to 499 * be reconsideres later.</p> 500 */ 501 protected boolean handleDeletedPrimitives() { 502 503 boolean somethingChanged = false; 504 NotNullList<OsmPrimitive> blockers = new NotNullList<OsmPrimitive>(); 505 506 // Firstly create a list of all primitives, which were deleted. 507 for (Match match : matches) 508 if (match.prim.deleted) 509 blockers.add(match.prim); 510 511 for (Match conflict : conflicts) 512 if (conflict.prim.deleted) 513 blockers.add(conflict.prim); 514 515 // Now for every deleted primitive... 516 int i=0; 517 while (i < blockers.size()) { 518 OsmPrimitive blocker = blockers.get(i); 519 520 // ... remove its' entries in the 'matches' ... 521 if (primMatchHashIndex.get(blocker) != null) { 522 Match toRemove = primMatchHashIndex.get(blocker); 523 matches.remove(toRemove); 524 primMatchHashIndex.remove(toRemove.prim); 525 elemMatchHashIndex.remove(toRemove.elem); 526 somethingChanged = matchesDirty = true; 527 } 528 529 // ... and reconsider all 'conflicts', which may have been caused 530 // by the deleted primitive. We must do it recursively... 531 532 // Every conflict, which has the 'blocker' as a primitive 533 if (primConflictHashIndex.get(blocker) != null) { 534 for (Match match : primConflictHashIndex.get(blocker)) { 535 // Find the correspoding element and find all primitives, 536 // which are mapped to this element. 537 if (elemConflictHashIndex.get(match.elem) != null) { 538 for (Match novy : elemConflictHashIndex.get(match.elem)) { 539 // If this primitive has not yet been handled, do it! 540 if (!blockers.contains(novy.prim)) 541 blockers.add(novy.prim); 542 // And move the conflict back to 'matches' for reconsideration. 543 if (!novy.prim.deleted && !matches.contains(novy)) { 544 matches.add(novy); 545 somethingChanged = matchesDirty = true; 546 } 547 } 548 // Finally remove the reconsidered conflicts... 549 conflicts.removeAll(elemConflictHashIndex.get(match.elem)); 550 elemConflictHashIndex.remove(match.elem); 551 elemConflictListIndex.remove(match.elem); 552 somethingChanged = conflictsDirty = true; 553 } 554 // [move the conflict back to 'matches' for reconsideration] 555 if (!match.prim.deleted && !matches.contains(match)) { 556 matches.add(match); 557 somethingChanged = matchesDirty = true; 558 } 559 } 560 // ...and once again remove reconsidered conflicts. 561 conflicts.removeAll(primConflictHashIndex.get(blocker)); 562 primConflictHashIndex.remove(blocker); 563 primConflictListIndex.remove(blocker); 564 somethingChanged = conflictsDirty = true; 565 } 566 i++; 567 } 568 569 return somethingChanged; 570 } 571 572 /** 573 * Seeks and handles primitives, which have been deleted. 574 * 575 * <p>Slower, but safer counterpart of {@code handleDeletedPrimitives))}.</p> 576 */ 577 protected boolean handleDeletedPrimitivesSlowButSafe() { 578 579 boolean fire = false; 580 581 for (Match match : matches) 582 fire |= match.qualityChanged(); 583 584 for (Match conflict : conflicts) 585 fire |= conflict.qualityChanged(); 586 587 if (fire) { 588 matches.addAll(conflicts); 589 conflicts.clear(); 590 matchesDirty = conflictsDirty = true; 591 592 int i=0; 593 while (i<matches.size()) { 594 Match match = matches.get(i); 595 if (match.quality <= Match.MATCH_NOMATCH) { 596 System.out.println("Reasoner: Deleting " + matches.get(i)); 597 matches.remove(i); 598 599 assert fire; 600 assert !matches.contains(match); 601 } else 602 i++; 603 } 604 } 605 606 return fire; 607 } 608 609 protected void reconsider(OsmPrimitive prim) { 610 611 List<Match> reconsider; 612 613 reconsider = getConflicts(prim); 614 if (reconsider != null) { 615 matches.addAll(reconsider); 616 conflicts.removeAll(reconsider); 617 matchesDirty = conflictsDirty = true; 618 } 619 } 620 621 protected void reconsider(AddressElement elem) { 622 623 List<Match> reconsider; 624 625 reconsider = getConflicts(elem); 626 if (reconsider != null) { 627 matches.addAll(reconsider); 628 conflicts.removeAll(reconsider); 629 matchesDirty = conflictsDirty = true; 630 } 631 } 632 633 /** 634 * Recreates all {@code *Index} fields if this reasoner. 635 */ 636 protected void regenerateIndexes() { 637 boolean assertions = false; 638 assert assertions = true; 639 640 elemMatchHashIndex.clear(); 641 primMatchHashIndex.clear(); 642 elemConflictHashIndex.clear(); 643 primConflictHashIndex.clear(); 644 elemConflictListIndex.clear(); 645 primConflictListIndex.clear(); 646 647 for (Match match : matches) { 648 elemMatchHashIndex.put(match.elem, match); 649 primMatchHashIndex.put(match.prim, match); 650 } 651 652 for (Match conflict : conflicts) { 653 654 List<Match> elemConflicts = elemConflictHashIndex.get(conflict.elem); 655 if (elemConflicts == null) { 656 elemConflicts = new ArrayList<Match>(); 657 elemConflictHashIndex.put(conflict.elem, elemConflicts); 658 } 659 elemConflicts.add(conflict); 660 661 List<Match> primConflicts = primConflictHashIndex.get(conflict.prim); 662 if (primConflicts == null) { 663 primConflicts = new ArrayList<Match>(); 664 primConflictHashIndex.put(conflict.prim, primConflicts); 665 } 666 primConflicts.add(conflict); 667 } 668 669 for (AddressElement elem : elemConflictHashIndex.keySet()) 670 elemConflictListIndex.add(elem); 671 672 for (OsmPrimitive prim : primConflictHashIndex.keySet()) 673 primConflictListIndex.add(prim); 674 675 assert elemConflictHashIndex.size() == elemConflictListIndex.size(); 676 assert primConflictHashIndex.size() == primConflictListIndex.size(); 677 678 for (AddressElement elem : elemConflictListIndex) 679 assert elemConflictHashIndex.get(elem) != null; 680 for (OsmPrimitive prim : primConflictListIndex) 681 assert primConflictHashIndex.get(prim) != null; 682 683 if (assertions) { 684 System.out.println("Spárovaných dvojic: " + String.valueOf(matches.size())); 685 System.out.println("Konfliktů (celkem): " + String.valueOf(conflicts.size()) 686 + "; " + String.valueOf(elemConflictListIndex.size()) 687 + "+" + String.valueOf(primConflictListIndex.size()) 688 + " elementů+primitiv"); 335 Node n1 = new Node(1); 336 n1.put("addr:street", "Jarní"); 337 n1.put("addr:alternatenumber", "242"); 338 339 r.openTransaction(); 340 r.consider(n1); 341 r.closeTransaction(); 342 assert r.translate(n1) == h4; 343 assert r.conflicts(n1).size() == 0; 344 345 346 347 Node n2 = new Node(2); 348 n2.put("addr:alternatenumber", "240"); 349 r.openTransaction(); 350 r.consider(n2); 351 r.closeTransaction(); 352 assert r.translate(n2) == null; 353 assert r.conflicts(n2).contains(h1); 354 assert r.conflicts(n2).contains(i4); 355 356 n2.put("addr:street", "Letní"); 357 n2.put("addr:housenumber", "4"); 358 r.openTransaction(); 359 r.consider(n2); 360 r.closeTransaction(); 361 assert r.translate(n2) == i4; 362 assert r.conflicts(n2).contains(h1); 363 364 365 n2.deleted = true; 366 r.openTransaction(); 367 r.consider(n2); 368 r.closeTransaction(); 369 370 assert r.translate(n2) == null; 371 372 } catch (Exception ex) { 373 374 ex.printStackTrace(); 689 375 } 690 376 } -
applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/parser/MvcrParser.java
r15166 r15461 1 1 package org.openstreetmap.josm.plugins.czechaddress.parser; 2 2 3 import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.*; 3 import static org.openstreetmap.josm.plugins.czechaddress.StringUtils.capitalize; 4 4 5 import java.io.FileInputStream; 5 6 import java.io.IOException; … … 7 8 import java.util.zip.ZipEntry; 8 9 import java.util.zip.ZipInputStream; 9 10 11 10 import org.openstreetmap.josm.Main; 12 11 import org.openstreetmap.josm.plugins.czechaddress.DatabaseLoadException; 12 import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.ElementWithHouses; 13 import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.ElementWithStreets; 14 import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.House; 15 import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.Region; 16 import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.Street; 17 import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.Suburb; 18 import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.ViToCi; 13 19 import org.xml.sax.Attributes; 14 20 import org.xml.sax.Locator; … … 48 54 if (curRegion == null) {*/ 49 55 curRegion = new Region( 50 attributes.getValue("nazev"),51 attributes.getValue("kraj"),52 attributes.getValue("okres"));56 capitalize(attributes.getValue("nazev")), 57 capitalize(attributes.getValue("kraj")), 58 capitalize(attributes.getValue("okres"))); 53 59 54 60 target.regions.add(curRegion); … … 60 66 return; 61 67 62 // ========== PARSING ViToC I========== //68 // ========== PARSING ViToCi ========== // 63 69 if (name.equals("obec")) { 64 70 … … 69 75 //curViToCi = curRegion.findViToCi(attributes.getValue("nazev")); 70 76 //if (curViToCi == null) { 71 curViToCi = new ViToCi( attributes.getValue("nazev"));77 curViToCi = new ViToCi(capitalize(attributes.getValue("nazev"))); 72 78 // System.out.println("Parser: " + curViToCi); 73 79 curRegion.addViToCi(curViToCi); … … 86 92 //curSuburb = curViToCi.findSuburb(attributes.getValue("nazev")); 87 93 //if (curSuburb == null) { 88 curSuburb = new Suburb( attributes.getValue("nazev"));94 curSuburb = new Suburb(capitalize(attributes.getValue("nazev"))); 89 95 // System.out.println("Parser: " + curSuburb); 90 96 curViToCi.addSuburb(curSuburb); … … 105 111 //curStreet = topElem.findStreet(attributes.getValue("nazev")); 106 112 //if (curStreet == null) { 107 curStreet = new Street( attributes.getValue("nazev"));113 curStreet = new Street(capitalize(attributes.getValue("nazev"))); 108 114 // System.out.println("Parser: " + curStreet); 109 115 topElem.addStreet(curStreet);
Note:
See TracChangeset
for help on using the changeset viewer.