Ignore:
Timestamp:
2009-06-01T17:24:35+02:00 (16 years ago)
Author:
rcernoch
Message:

New Reasoner has first usable version. The rest of the plugin is TOTALLY broken.

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  
        11build
         2.log.xsl.swp
  • applications/editors/josm/plugins/czechaddress/build.xml

    r15203 r15461  
    2626        <!-- compile the plugin -->
    2727        <javac srcdir="src"
     28               sourcepath=""
    2829               classpath="${josm.jar}"
    2930               destdir="${plugin.build.dir}"
    30                debug="true"/>
     31               debug="true">
    3132
    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>
    4041
    41         <!-- include the images -->
    42         <copy todir="${plugin.build.dir}/images">
    43             <fileset dir="images"/>
    44         </copy>
    4542    </target>
    4643
    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 to
    66                     <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>
    8444
    8545    <!-- Before running "run" target, please "ant dist" the JOSM. -->
    8646    <target name="run" depends="compile">
    87         <java classname="JOSM" fork="true">
     47        <java classname="org.openstreetmap.josm.plugins.czechaddress.intelligence.Reasoner">
    8848            <jvmarg value="-Xmx1024m"/>
    8949            <jvmarg value="-Xdebug"/>
     
    9757                <pathelement path="${java.class.path}"/>
    9858            </classpath>
    99         <!--<arg value="/home/radek/Desktop/Hustopeče.osm"/>-->
    10059        </java>
     60        <exec executable="xsltproc" output="log.html">
     61            <arg value="log.xsl"/>
     62            <arg value="log.xml"/>
     63        </exec>
    10164    </target>
    10265
  • applications/editors/josm/plugins/czechaddress/nbproject

    • Property svn:ignore set to
      .project.xml.swp
  • applications/editors/josm/plugins/czechaddress/nbproject/project.xml

    r15201 r15461  
    4646                    <target>compile</target>
    4747                </action>
    48                 <action name="debug">
    49                     <script>nbproject/ide-targets.xml</script>
    50                     <target>debug-nb</target>
    51                 </action>
    5248            </ide-actions>
     49            <export>
     50                <type>folder</type>
     51                <location>build</location>
     52                <build-target>compile</build-target>
     53            </export>
    5354            <view>
    5455                <items>
     
    7172                    <ide-action name="javadoc"/>
    7273                    <ide-action name="run"/>
    73                     <ide-action name="debug"/>
    7474                </context-menu>
    7575            </view>
     
    8080                <package-root>src</package-root>
    8181                <classpath mode="compile">../../core/build:../../core/src:tests/junit-4.5.jar</classpath>
     82                <built-to>build</built-to>
    8283                <javadoc-built-to>doc</javadoc-built-to>
    8384                <source-level>1.5</source-level>
  • applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/CzechAddressPlugin.java

    r15203 r15461  
    2727import org.openstreetmap.josm.plugins.czechaddress.actions.ModifierAction;
    2828import org.openstreetmap.josm.plugins.czechaddress.actions.SplitAreaByEmptyWayAction;
    29 import org.openstreetmap.josm.plugins.czechaddress.gui.DatabaseModifier;
     29import org.openstreetmap.josm.plugins.czechaddress.gui.Inspector;
     30import org.openstreetmap.josm.plugins.czechaddress.gui.Renamer;
    3031import org.openstreetmap.josm.plugins.czechaddress.gui.FactoryDialog;
    3132import org.openstreetmap.josm.plugins.czechaddress.intelligence.Reasoner;
     
    4647            new ArrayList<AbstractButton>();
    4748
    48     static private Reasoner mainReasoner = null;
    49     static private Database mainDatabase = null;
     49    static public Reasoner reasoner = null;
     50    static public Database database = null;
    5051
    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
    5458
    5559    static private String pluginDir = null;
     
    5862
    5963        pluginDir = getPluginDir();
     64        addStatusListener(this);
    6065
    61         factoryDialog    = FactoryDialog.getInstance();
     66        factoryDialog    = new FactoryDialog();
    6267        conflictResolver = new ConflictResolver();
    6368
    64         addStatusListener(this);
    65         addStatusListener(conflictResolver);
    66 
     69       
    6770        MainMenu.add(Main.main.menu.toolsMenu, new SplitAreaByEmptyWayAction());
    6871
     72
    6973        // Prepare for filling the database.
    70         mainDatabase = new Database();
     74        database = new Database();
    7175        final MvcrParser parser = new MvcrParser();
    7276        //parser.setFilter(null, null, null, "");
    7377        //parser.setFilter("HUSTOPEČE", "HUSTOPEČE", null, null);
    74         parser.setTargetDatabase(mainDatabase);
     78        parser.setTargetDatabase(database);
    7579        parser.setStorageDir(pluginDir);
    7680
     
    8084            try {
    8185               parser.fillDatabase();
    82                broadcastStatusChanged(StatusListener.MESSAGE_DATABASE_LOADED);
     86               broadcastStatusChange(StatusListener.MESSAGE_DATABASE_LOADED);
    8387            } catch (DatabaseLoadException dle) {
    8488               dle.printStackTrace();
     
    9599    public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
    96100
    97         super.mapFrameInitialized(oldFrame, newFrame);
    98 
    99101        if (newFrame == null)
    100102            return;
    101103       
    102         newFrame.addToggleDialog(FactoryDialog.getInstance());
     104        newFrame.addToggleDialog(factoryDialog);
    103105        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;
    112106    }
    113107
     
    121115
    122116        // Update database according to the map
    123         (new DatabaseModifier()).setVisible(true);
     117        (new Renamer()).setVisible(true);
     118        (new Inspector()).setVisible(true);
    124119
    125120        // 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());
    128123    }
    129124
    130125    static private ElementWithStreets location = null;
    131 
    132     static public ElementWithStreets getLocation() {
     126    static public  ElementWithStreets getLocation() {
    133127        if (location == null)
    134128            changeLocation();
     
    142136        if (newLocation != null && newLocation != location) {
    143137            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);
    167139        }
    168140    }
     
    182154    }
    183155
    184     static public void broadcastStatusChanged(int statusMessage) {
     156    static public void broadcastStatusChange(int statusMessage) {
    185157        for (StatusListener l : listeners)
    186158            l.pluginStatusChanged(statusMessage);
     
    188160
    189161    public void pluginStatusChanged(int message) {
    190         if (message == StatusListener.MESSAGE_DATABASE_LOADED) {
     162        if (message == MESSAGE_DATABASE_LOADED) {
    191163            czechMenu = Main.main.menu.addMenu("Adresy", KeyEvent.VK_A, 4);
    192164            menuItems.add(MainMenu.add(czechMenu, new PointManipulatorAction()));
     
    198170        }
    199171
     172        if (message == MESSAGE_LOCATION_CHANGED) {
     173            initReasoner();
     174            return;
     175        }
     176
     177
    200178        // SelectionMonitor cannot be used because of synchronization problems.
    201179        /*if (message == MESSAGE_REASONER_REASONED) {
  • applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/StatusListener.java

    r15166 r15461  
    33import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.AddressElement;
    44import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.Database;
    5 import org.openstreetmap.josm.plugins.czechaddress.parser.DatabaseParser;
    65import org.openstreetmap.josm.plugins.czechaddress.intelligence.Reasoner;
    76
     
    6766     *
    6867     * @see CzechAddressPlugin
    69      * @see DatabaseParser
    7068     * @see Database
    7169     */
  • applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/StringUtils.java

    r15201 r15461  
    4343
    4444    public static String latLonToString(LatLon position) {
    45         assert position != null;
    46         //if (position == null) return "";
     45        if (position == null) return "";
    4746
    4847        return "(lat: " + coordinateToString(position.lat())
     
    8382    }
    8483
     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
    85119}
  • applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/actions/FactoryAction.java

    r15166 r15461  
    1111import org.openstreetmap.josm.plugins.czechaddress.CzechAddressPlugin;
    1212import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.House;
    13 import org.openstreetmap.josm.plugins.czechaddress.intelligence.Reasoner;
    1413import org.openstreetmap.josm.plugins.czechaddress.proposal.ProposalContainer;
    1514import org.openstreetmap.josm.tools.ImageProvider;
     
    5453        Main.map.mapView.addMouseListener(this);
    5554
    56         Reasoner r = CzechAddressPlugin.getReasoner();
    57 
    58         if (r == null) {
     55        if (CzechAddressPlugin.reasoner == null) {
    5956            exitMode();
    6057            return;
    6158        }
    6259
    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)
    6563            d.selectNextUnmatchedHouseByCheckBox();
    6664    }
     
    8886
    8987        // Get the currently selected House in the FactoryDialog.
    90         House house = FactoryDialog.getInstance().getSelectedHouse();
     88        House house = CzechAddressPlugin.factoryDialog.getSelectedHouse();
    9189        if (house == null)
    9290            return; // TODO: Some meaningful messageBox would be useful.
     
    9997        container.applyAll();
    10098
    101         // Notify reasoner about this newly added node.
    102         CzechAddressPlugin.getReasoner().overwriteMatch(house, newNode);
    103 
    10499        // And make the new node selected.
    105100        Main.ds.addPrimitive(newNode);
    106101        Main.ds.setSelected(newNode);
    107102
    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();
    110105    }
    111106}
  • applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/actions/ModifierAction.java

    r15201 r15461  
    99import java.awt.event.KeyEvent;
    1010import org.openstreetmap.josm.actions.JosmAction;
    11 import org.openstreetmap.josm.plugins.czechaddress.gui.DatabaseModifier;
     11import org.openstreetmap.josm.plugins.czechaddress.gui.Renamer;
    1212import org.openstreetmap.josm.tools.Shortcut;
    1313
     
    1717 */
    1818public class ModifierAction extends JosmAction {
    19 
    20 //    DatabaseModifier modifier = null;
    2119
    2220    public ModifierAction() {
     
    3129
    3230    public void actionPerformed(ActionEvent e) {
    33         (new DatabaseModifier()).setVisible(true);
     31        (new Renamer()).setVisible(true);
    3432    }
    3533}
  • applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/addressdatabase/AddressElement.java

    r15203 r15461  
    3131    /**
    3232     * 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. However
    36      * this should not be done here, but in the {@link DatabaseParser}.</p>
    3733     */
    3834    public AddressElement (String name) {
    3935        if (name == null)
    4036            throw new NullPointerException("You must specify the name of this AddressElement");
    41         this.name = capitalize(name);
     37        this.name = name;
    4238    }
    4339
     
    166162
    167163    /**
    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 capitalized
    174      * @return capitaized string
    175      */
    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             else
    189                 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     /**
    203164     * Compute differences between two strings.
    204165     *
     
    248209    public List<Proposal> getDiff(OsmPrimitive prim) {
    249210        return null;
     211    }
     212
     213    public boolean isMatchable(OsmPrimitive prim) {
     214        return false;
    250215    }
    251216
  • applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/addressdatabase/House.java

    r15203 r15461  
    204204    }
    205205
    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    }
    207216}
  • applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/addressdatabase/Region.java

    r15201 r15461  
    6969    public Region(String name, String nuts3name, String nuts4name) {
    7070        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;
    7373    }
    7474   
  • applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/gui/ConflictResolver.java

    r15166 r15461  
    258258             if (best != null) best.qualityChanged();
    259259
    260              List<Match> competitors = r.getConflicts((OsmPrimitive) selMainObj);
     260             List<Match> competitors = r.conflicts((OsmPrimitive) selMainObj);
    261261             if (competitors != null) for (Match competitor : competitors)
    262262                 competitor.qualityChanged();
     
    271271            if (best != null) best.qualityChanged();
    272272
    273             List<Match> competitors = r.getConflicts((AddressElement) selMainObj);
     273            List<Match> competitors = r.conflicts((AddressElement) selMainObj);
    274274            if (competitors != null) for (Match competitor : competitors)
    275275                 competitor.qualityChanged();
     
    333333
    334334                if (parent instanceof AddressElement)
    335                     return r.getConflicts((AddressElement) parent).get(index).prim;
     335                    return r.conflicts((AddressElement) parent).get(index).prim;
    336336
    337337            } catch (Exception e) {  }
     
    347347
    348348                if (parent instanceof AddressElement)
    349                     return r.getConflicts((AddressElement) parent).size();
     349                    return r.conflicts((AddressElement) parent).size();
    350350               
    351351            } catch (Exception exp) { }
     
    361361
    362362                if (parent instanceof AddressElement)
    363                     return r.getConflicts((AddressElement) parent).indexOf(child);
     363                    return r.conflicts((AddressElement) parent).indexOf(child);
    364364               
    365365            } catch (Exception exp) { }
     
    383383
    384384                if (parent instanceof OsmPrimitive)
    385                     return r.getConflicts((OsmPrimitive) parent).get(index).elem;
     385                    return r.getConflictsconflictsve) parent).get(index).elem;
    386386               
    387387            } catch (Exception exp) { }
     
    397397                    return r.getPrimitivesInConflict().size();
    398398                if (parent instanceof OsmPrimitive)
    399                     return r.getConflicts((OsmPrimitive) parent).size();
     399                    return r.getConflictsconflictsve) parent).size();
    400400
    401401            } catch (Exception exp) { }
     
    412412
    413413                } else if (parent instanceof OsmPrimitive)
    414                     return r.getConflicts((OsmPrimitive) parent).indexOf(child);
     414                    return r.getConflictsconflictsve) parent).indexOf(child);
    415415               
    416416            } catch (Exception exp) { }
  • applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/gui/FactoryDialog.form

    r15166 r15461  
    11<?xml version="1.0" encoding="UTF-8" ?>
    22
    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">
    44  <AuxValues>
    55    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
     
    2626          <Group type="103" groupAlignment="0" attributes="0">
    2727              <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"/>
    2929                  <EmptySpace max="-2" attributes="0"/>
    3030                  <Component id="relocateButton" min="-2" max="-2" attributes="0"/>
     
    3333              </Group>
    3434              <Group type="102" alignment="0" attributes="0">
    35                   <Component id="keepOddityCheckBox" pref="282" max="32767" attributes="0"/>
     35                  <Component id="keepOddityCheckBox" pref="278" max="32767" attributes="0"/>
    3636                  <EmptySpace max="-2" attributes="0"/>
    3737              </Group>
  • applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/gui/FactoryDialog.java

    r15166 r15461  
    3737        implements SelectionChangedListener, StatusListener {
    3838
    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 
    4739    HouseListModel  houseModel  = new HouseListModel();
    4840    StreetListModel streetModel = new StreetListModel();
     
    6557        add(mainPanel);
    6658
    67         // Register to all listeners
     59        // Register to all messages
    6860        CzechAddressPlugin.addStatusListener(this);
    6961
     
    9486            keepOddityCheckBox.setEnabled(true);
    9587            return;
    96 
    9788        }
    9889       
     
    115106
    116107    public boolean existsAvailableHouse() {
    117         Reasoner r = CzechAddressPlugin.getReasoner();
     108        Reasoner r = CzechAddressPlugin.reasoner;
    118109
    119110        int i = houseList.getSelectedIndex();
     
    136127    public void selectNextUnmatchedHouse() {
    137128
    138         Reasoner r = CzechAddressPlugin.getReasoner();
    139129        int index = houseList.getSelectedIndex();
    140130
     
    142132        Object current;
    143133        while ( (current = houseModel.getElementAt(index)) != null
    144                 && r.translate((House) current) != null)
     134              && CzechAddressPlugin.reasoner.translate((House) current) != null)
    145135            index++;
    146136
     
    326316    private void houseListClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_houseListClicked
    327317        if (evt.getClickCount() == 2 && evt.getButton() == MouseEvent.BUTTON1) {
    328             Reasoner r = CzechAddressPlugin.getReasoner();
     318            Reasoner r = CzechAddressPlugin.reasoner;
    329319
    330320            if (r.translate(getSelectedHouse()) != null) {
     
    347337
    348338    private void ensureConsistencyButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ensureConsistencyButtonActionPerformed
    349         CzechAddressPlugin.getReasoner().ensureConsistency();
     339        CzechAddressPlugin.reasoner.ensureConsistency();
    350340}//GEN-LAST:event_ensureConsistencyButtonActionPerformed
    351341
     
    405395            if (boldFont == null) boldFont = getFont().deriveFont(Font.BOLD);
    406396
    407             Reasoner r = CzechAddressPlugin.getReasoner();
     397            Reasoner r = CzechAddressPlugin.reasoner;
    408398
    409399            if (value instanceof House) {
     
    413403                setFont(plainFont);
    414404
    415                 if ( r.getConflicts(house) != null)
     405                if ( r.conflicts(house) != null)
    416406                    setIcon(envelopeExclIcon);
    417407                else if ( r.translate(house) == null) {
     
    457447
    458448        public void rebuild() {
    459             Reasoner r = CzechAddressPlugin.getReasoner();
     449            Reasoner r = CzechAddressPlugin.reasoner;
    460450            if (r == null) return;
    461451
  • applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/gui/PointManipulatorDialog.java

    r15203 r15461  
    368368                if (match.elem instanceof House) {
    369369                    setIcon(envelopeStarIcon);
    370                     if ( r.getConflicts(match.elem) != null )
     370                    if ( r.conflicts(match.elem) != null )
    371371                        setIcon(envelopeExclIcon);
    372372                    else if ( r.translate(match.elem) != null)
  • applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/gui/Renamer.java

    r15203 r15461  
    55
    66/*
    7  * DatabaseModifier.java
     7 * Renamer.java
    88 *
    99 * Created on 24.5.2009, 18:03:35
     
    3131 * @author radek
    3232 */
    33 public class DatabaseModifier extends ExtendedDialog {
     33public class Renamer extends ExtendedDialog {
    3434
    3535    StreetModel<Street> streetModel = new StreetModel<Street>();
    3636
    37     /** Creates new form DatabaseModifier */
    38     public DatabaseModifier() {
     37    /** Creates new form Renamer */
     38    public Renamer() {
    3939
    4040        super(Main.parent, "Upravit databázi",
  • applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/gui/UniversalTreeRenderer.java

    r15166 r15461  
    6565
    6666
    67         if (value instanceof House) {
     67        if (value instanceof House && r != null) {
    6868            House house = (House) value;
    6969
    7070            setIcon(envelopeNormIcon);
    71             if ( r.getConflicts(house) != null )
     71            if ( r.conflicts(house) != null )
    7272                setIcon(envelopeExclIcon);
    7373            else if ( r.translate(house) == null)
  • applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/intelligence/Match.java

    r15166 r15461  
    22
    33import java.util.List;
    4 import org.openstreetmap.josm.data.osm.Node;
     4import java.util.logging.Level;
     5import java.util.logging.Logger;
    56import org.openstreetmap.josm.data.osm.OsmPrimitive;
    67import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.AddressElement;
     
    2021    public static final int MATCH_NOMATCH   = 0;
    2122   
    22     public int quality;
     23    public int qVal;
    2324    public OsmPrimitive prim;
    2425    public AddressElement elem;
    2526
    2627    public String checkSum;
     28    public static Logger logger = Logger.getLogger("Match");
    2729
    2830    public Match(AddressElement element, OsmPrimitive primitive,
     
    3032       
    3133        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;
    3835        assert !primitive.deleted;
    3936
    4037        prim = primitive;
    4138        elem = element;
    42         quality = qualityFactor;
    43 
    44         checkSum = toString();
     39        qVal = qualityFactor;
    4540    }
    4641
     
    5348
    5449        int quality = element.getMatchQuality(primitive);
     50
     51        logger.log(Level.FINE, "asked to create match",
     52                               new Object[] {element, primitive, quality});
     53
    5554        if (quality > MATCH_NOMATCH)
    5655            return new Match(element, primitive, quality);
     
    5857        return null;
    5958    }
     59/*
     60    public boolean setQ(int desiredQ) {
     61        int oldQ = evalQ();
     62        qVal = desiredQ;
     63        int newQ = evalQ();
    6064
    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) {
    7472       
    75         boolean difference = newQuality != quality;
    76         quality = newQuality;
     73        if (prim.deleted)
     74            return MATCH_NOMATCH;
    7775
    78         return difference;
     76        if (oldQ == MATCH_OVERWRITE)
     77            return MATCH_OVERWRITE;
     78
     79        return elem.getMatchQuality(prim);
    7980    }
    8081
    8182    @Override
    8283    public String toString() {
    83         return "{Match: q=" + String.valueOf(quality)
     84        return "{Match: q=" + String.valueOf(qVal)
    8485                   + "; elem='" + elem.toString()
    8586                   +"'; prim='" + AddressElement.getName(prim) + "'}";
  • applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/intelligence/Reasoner.java

    r15166 r15461  
    11package org.openstreetmap.josm.plugins.czechaddress.intelligence;
    22
    3 import java.util.ArrayList;
    4 import java.util.Collection;
    53import java.util.HashMap;
    6 import java.util.List;
     4import java.util.HashSet;
     5import java.util.Map;
     6import java.util.Set;
     7import java.util.logging.FileHandler;
     8import java.util.logging.Handler;
     9import java.util.logging.Level;
     10import java.util.logging.Logger;
     11import org.openstreetmap.josm.data.osm.Node;
    712import 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;
    1113import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.AddressElement;
    1214import 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;
     15import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.Street;
    1516
    1617/**
     
    3435public class Reasoner {
    3536
    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) {
    88252       
    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
    181268    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
    193275    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);
    243315           
    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
    246334           
    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> &gt;
    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();
    689375        }
    690376    }
  • applications/editors/josm/plugins/czechaddress/src/org/openstreetmap/josm/plugins/czechaddress/parser/MvcrParser.java

    r15166 r15461  
    11package org.openstreetmap.josm.plugins.czechaddress.parser;
    22
    3 import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.*;
     3import static org.openstreetmap.josm.plugins.czechaddress.StringUtils.capitalize;
     4
    45import java.io.FileInputStream;
    56import java.io.IOException;
     
    78import java.util.zip.ZipEntry;
    89import java.util.zip.ZipInputStream;
    9 
    10 
    1110import org.openstreetmap.josm.Main;
    1211import org.openstreetmap.josm.plugins.czechaddress.DatabaseLoadException;
     12import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.ElementWithHouses;
     13import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.ElementWithStreets;
     14import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.House;
     15import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.Region;
     16import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.Street;
     17import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.Suburb;
     18import org.openstreetmap.josm.plugins.czechaddress.addressdatabase.ViToCi;
    1319import org.xml.sax.Attributes;
    1420import org.xml.sax.Locator;
     
    4854            if (curRegion == null) {*/
    4955                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")));
    5359
    5460                target.regions.add(curRegion);
     
    6066            return;
    6167
    62         // ========== PARSING ViToCI ========== //
     68        // ========== PARSING ViToCi ========== //
    6369        if (name.equals("obec")) {
    6470
     
    6975            //curViToCi = curRegion.findViToCi(attributes.getValue("nazev"));
    7076            //if (curViToCi == null) {
    71                 curViToCi = new ViToCi(attributes.getValue("nazev"));
     77                curViToCi = new ViToCi(capitalize(attributes.getValue("nazev")));
    7278            //    System.out.println("Parser: " + curViToCi);
    7379                curRegion.addViToCi(curViToCi);
     
    8692            //curSuburb = curViToCi.findSuburb(attributes.getValue("nazev"));
    8793            //if (curSuburb == null) {
    88                 curSuburb = new Suburb(attributes.getValue("nazev"));
     94                curSuburb = new Suburb(capitalize(attributes.getValue("nazev")));
    8995            //    System.out.println("Parser: " + curSuburb);
    9096                curViToCi.addSuburb(curSuburb);
     
    105111            //curStreet = topElem.findStreet(attributes.getValue("nazev"));
    106112            //if (curStreet == null) {
    107                 curStreet = new Street(attributes.getValue("nazev"));
     113                curStreet = new Street(capitalize(attributes.getValue("nazev")));
    108114            //    System.out.println("Parser: " + curStreet);
    109115                topElem.addStreet(curStreet);
Note: See TracChangeset for help on using the changeset viewer.