From d48b7bd267feccaf258289579c3288faca2605bf Mon Sep 17 00:00:00 2001 From: Mike Zhou Date: Mon, 10 Nov 2025 14:32:37 -0800 Subject: [PATCH 01/14] change the occupant tag and logic to or logic --- .../java/ca/bc/gov/ols/geocoder/data/indexing/TagIndex.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/data/indexing/TagIndex.java b/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/data/indexing/TagIndex.java index 14c0bc36..bab2ee23 100644 --- a/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/data/indexing/TagIndex.java +++ b/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/data/indexing/TagIndex.java @@ -82,7 +82,11 @@ public Set query(String tags) { if(results == null) { results = new THashSet(tie.items); } else { - results.retainAll(tie.items); + // intersect the results with the next tag's items (AND) + // results.retainAll(tie.items); + + // union logic (OR) would be: + results.addAll(tie.items); } } if(results == null) { From 5a3fc38212a0ff7a32584bdf55d471aa37982c6d Mon Sep 17 00:00:00 2001 From: Mike Zhou Date: Wed, 12 Nov 2025 11:16:19 -0800 Subject: [PATCH 02/14] fix pervious incorrect change location. The change should be in GeocoderQuery --- .gitignore | 2 ++ .../bc/gov/ols/geocoder/api/GeocodeQuery.java | 30 +++++++++++++++---- .../ols/geocoder/data/indexing/TagIndex.java | 6 +--- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index e51bca5e..5d7d99a8 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,5 @@ local.properties # InelliJ .idea + +local_data diff --git a/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/api/GeocodeQuery.java b/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/api/GeocodeQuery.java index 2d8f60aa..44710f49 100644 --- a/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/api/GeocodeQuery.java +++ b/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/api/GeocodeQuery.java @@ -471,11 +471,31 @@ public boolean pass(GeocodeMatch match) { @Override public boolean pass(GeocodeMatch match) { if(match instanceof AddressMatch - && ((AddressMatch)match).getAddress() instanceof OccupantAddress - && ((OccupantAddress)(((AddressMatch)match).getAddress())).getKeywordList() - .containsAll(Arrays.asList(tags.toLowerCase().split(";"))) - ) { - return true; + && ((AddressMatch)match).getAddress() instanceof OccupantAddress) { + List keywords = ((OccupantAddress)(((AddressMatch)match).getAddress())).getKeywordList(); + if(keywords == null || keywords.isEmpty()) { + return false; + } + String lowerTags = tags.toLowerCase(); + // OR if tags contain ':' + if(lowerTags.contains(":")) { + String[] tagArray = lowerTags.split(":"); + for(String t : tagArray) { + t = t.trim(); + if(keywords.contains(t)) { + return true; + } + } + return false; + } else { + // default to AND using ';' + String[] tagArray = lowerTags.split(";"); + List required = new ArrayList(tagArray.length); + for(String t : tagArray) { + required.add(t.trim()); + } + return keywords.containsAll(required); + } } return false; } diff --git a/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/data/indexing/TagIndex.java b/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/data/indexing/TagIndex.java index bab2ee23..14c0bc36 100644 --- a/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/data/indexing/TagIndex.java +++ b/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/data/indexing/TagIndex.java @@ -82,11 +82,7 @@ public Set query(String tags) { if(results == null) { results = new THashSet(tie.items); } else { - // intersect the results with the next tag's items (AND) - // results.retainAll(tie.items); - - // union logic (OR) would be: - results.addAll(tie.items); + results.retainAll(tie.items); } } if(results == null) { From bcafc675c4d41eb0932bded7d33164280534a969 Mon Sep 17 00:00:00 2001 From: Mike Zhou Date: Wed, 12 Nov 2025 15:49:47 -0800 Subject: [PATCH 03/14] Add AND logic to TagIndex --- .../ols/geocoder/data/indexing/TagIndex.java | 53 ++++++++++++++----- 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/data/indexing/TagIndex.java b/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/data/indexing/TagIndex.java index 14c0bc36..174fdf38 100644 --- a/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/data/indexing/TagIndex.java +++ b/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/data/indexing/TagIndex.java @@ -64,31 +64,58 @@ public List add(T item, String tags) { } /** - * Queries the tag index for items that match all of the tags listed in the tags parameter. - * @param tags semicolon separated list of tag strings + * Queries the tag index for items that match all or any of the tags listed in the tags parameter + * depending on the presence of ':'. + * @param tags colon/semicolon separated list of tag strings * @return a set of items matching all the specified tags */ public Set query(String tags) { if(tags == null || tags.isEmpty()) { return Collections.emptySet(); } - String[] tagArray = tags.toLowerCase().split(";"); + String lower = tags.toLowerCase(); Set results = null; - for(String tag : tagArray) { - TagIndexEntry tie = index.get(tag); - if(tie == null) { + // If tags contains ':' use OR semantics, otherwise default to AND using ';' + if(lower.contains(":")) { + String[] tagArray = lower.split(":"); + for(String tag : tagArray) { + tag = tag.trim(); + if(tag.isEmpty()) continue; + TagIndexEntry tie = index.get(tag); + if(tie == null) { + // missing tag contributes nothing for OR + continue; + } + if(results == null) { + results = new THashSet(tie.items); + } else { + results.addAll(tie.items); + } + } + if(results == null) { return Collections.emptySet(); } + return results; + } else { + String[] tagArray = lower.split(";"); + for(String tag : tagArray) { + tag = tag.trim(); + if(tag.isEmpty()) continue; + TagIndexEntry tie = index.get(tag); + if(tie == null) { + return Collections.emptySet(); + } + if(results == null) { + results = new THashSet(tie.items); + } else { + results.retainAll(tie.items); + } + } if(results == null) { - results = new THashSet(tie.items); - } else { - results.retainAll(tie.items); + return Collections.emptySet(); } + return results; } - if(results == null) { - return Collections.emptySet(); - } - return results; } public Set getTags() { From 30f6f809fe241073f6f4d94174c67822af0d9c9d Mon Sep 17 00:00:00 2001 From: Mike Zhou Date: Wed, 19 Nov 2025 09:21:22 -0800 Subject: [PATCH 04/14] Replace itn private road street name with street name 2 if exists --- .../gov/ols/siteloaderprep/RawStreetName.java | 1 + .../ca/bc/gov/ols/streetprep/StreetPrep.java | 40 +++++++++++++++++-- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/ols-geocoder-process/src/main/java/ca/bc/gov/ols/siteloaderprep/RawStreetName.java b/ols-geocoder-process/src/main/java/ca/bc/gov/ols/siteloaderprep/RawStreetName.java index b4ce81cc..0ae46356 100644 --- a/ols-geocoder-process/src/main/java/ca/bc/gov/ols/siteloaderprep/RawStreetName.java +++ b/ols-geocoder-process/src/main/java/ca/bc/gov/ols/siteloaderprep/RawStreetName.java @@ -8,6 +8,7 @@ public class RawStreetName { public String qual; public boolean typeIsPrefix; public boolean dirIsPrefix; + public boolean isPrivateRoad; // indicates if this street name is a private road name @Override public String toString() { diff --git a/ols-geocoder-process/src/main/java/ca/bc/gov/ols/streetprep/StreetPrep.java b/ols-geocoder-process/src/main/java/ca/bc/gov/ols/streetprep/StreetPrep.java index 3e9e258d..e96fc1ae 100644 --- a/ols-geocoder-process/src/main/java/ca/bc/gov/ols/streetprep/StreetPrep.java +++ b/ols-geocoder-process/src/main/java/ca/bc/gov/ols/streetprep/StreetPrep.java @@ -851,6 +851,13 @@ private TIntObjectMap readStreetNames(Map streetT name.body = rr.getString("NAME_BODY"); name.qual = rr.getString("NAME_DESCRIPTOR_CODE"); + + if(rr.getString("FULL_NAME") != null && (rr.getString("FULL_NAME").toLowerCase().contains("private rd") || + rr.getString("FULL_NAME").toLowerCase().contains("private road"))) { + // special case for "Private Rd" + name.isPrivateRoad = true; + } + if(name.qual != null) { String newQual = streetQualMap.get(name.qual); if(newQual == null) { @@ -1179,16 +1186,43 @@ private void writeStreetSegments(TIntObjectMap segMap) { private void writeStreetNameOnSegs(TIntObjectMap segMap, TIntObjectMap streetNameIdMap) { try(RowWriter rw = new JsonRowWriter(new File(outputDir + STREET_LOAD_STREET_NAME_ON_SEG_XREF_FILE), "bgeo_street_name_on_seg_xref", dates)) { TIntObjectIterator segIterator = segMap.iterator(); + // find the name ID for "private road" and "private rd" from the streetNameIdMap + // streetNameIdMap is keyed by STRUCTURED_NAME_ID, so we need to iterate through it to find the ID (the value is a RawStreetName. It has isPrivateRoad boolean) + int privateRoadNameId = -1; + for(TIntObjectIterator nameIterator = streetNameIdMap.iterator(); nameIterator.hasNext(); ) { + nameIterator.advance(); + RawStreetName name = nameIterator.value(); + if(name.isPrivateRoad) { + privateRoadNameId = name.id; + break; + } + } + while(segIterator.hasNext()) { segIterator.advance(); RawStreetSeg seg = segIterator.value(); - for(int nameIdx = 0; nameIdx < seg.nameIds.size(); nameIdx++) { + // new logic. Use STREET_SEGMENT_ID_2 if STREET_SEGMENT_ID_1 is "private road" or "private rd" + // and STREET_SEGMENT_ID_2 is not null. Please note the IDs are just number. + // Note: if the value was null in the source data, it will not be in the nameIds list. + // case 1: nameId 1 is private road and nameId 2 is not null -> use nameId 2 as primary + if(seg.nameIds.size() >= 2 && seg.nameIds.get(0) == privateRoadNameId) { Map row = new THashMap(); - row.put("STREET_NAME_ID", seg.nameIds.get(nameIdx)); + row.put("STREET_NAME_ID", seg.nameIds.get(1)); row.put("STREET_SEGMENT_ID", seg.streetSegmentId); - row.put("IS_PRIMARY_IND", nameIdx == 0); + row.put("IS_PRIMARY_IND", true); rw.writeRow(row); } + else{ + // case 2: nameId 1 is private road and nameId 2 is null -> do not change + // case 3: nameId 1 is not private road -> do not change + for(int nameIdx = 0; nameIdx < seg.nameIds.size(); nameIdx++) { + Map row = new THashMap(); + row.put("STREET_NAME_ID", seg.nameIds.get(nameIdx)); + row.put("STREET_SEGMENT_ID", seg.streetSegmentId); + row.put("IS_PRIMARY_IND", nameIdx == 0); + rw.writeRow(row); + } + } } } } From e6a87666932c6fa71d955c1d2061e84a12e8e161 Mon Sep 17 00:00:00 2001 From: Mike Zhou <124401782+3rdmike@users.noreply.github.com> Date: Mon, 8 Dec 2025 14:29:02 -0800 Subject: [PATCH 05/14] update the version to indicate private road change --- ols-geocoder-admin/pom.xml | 2 +- ols-geocoder-core/pom.xml | 2 +- ols-geocoder-process/pom.xml | 2 +- ols-geocoder-web/pom.xml | 2 +- pom.xml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ols-geocoder-admin/pom.xml b/ols-geocoder-admin/pom.xml index eea64378..258e0330 100644 --- a/ols-geocoder-admin/pom.xml +++ b/ols-geocoder-admin/pom.xml @@ -3,7 +3,7 @@ ca.bc.gov.ols ols-geocoder - 4.5.2 + 4.5.2-private-road OLS Geocoder Admin diff --git a/ols-geocoder-core/pom.xml b/ols-geocoder-core/pom.xml index a7f255d1..38af2e94 100644 --- a/ols-geocoder-core/pom.xml +++ b/ols-geocoder-core/pom.xml @@ -6,7 +6,7 @@ ca.bc.gov.ols ols-geocoder - 4.5.2 + 4.5.2-private-road OLS Geocoder Core diff --git a/ols-geocoder-process/pom.xml b/ols-geocoder-process/pom.xml index 1dec3559..8a45e6ad 100644 --- a/ols-geocoder-process/pom.xml +++ b/ols-geocoder-process/pom.xml @@ -4,7 +4,7 @@ ca.bc.gov.ols ols-geocoder - 4.5.2 + 4.5.2-private-road ols-geocoder-process OLS Geocoder Process diff --git a/ols-geocoder-web/pom.xml b/ols-geocoder-web/pom.xml index ad396dd9..8d883251 100644 --- a/ols-geocoder-web/pom.xml +++ b/ols-geocoder-web/pom.xml @@ -6,7 +6,7 @@ ca.bc.gov.ols ols-geocoder - 4.5.2 + 4.5.2-private-road OLS Geocoder Web diff --git a/pom.xml b/pom.xml index f96e63e4..b26d9496 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ ca.bc.gov.ols ols-geocoder - 4.5.2 + 4.5.2-private-road pom OLS Geocoder https://bcgov.github.io/ols-geocoder/ From d70ddc78f67f72c7905cbc649c1e661759d2323c Mon Sep 17 00:00:00 2001 From: Mike Zhou Date: Wed, 10 Dec 2025 11:52:13 -0800 Subject: [PATCH 06/14] added new parameter tagCondition and set default to or; reverted TagIndex changes --- .../bc/gov/ols/geocoder/api/GeocodeQuery.java | 27 ++++++++-- .../ols/geocoder/data/indexing/TagIndex.java | 53 +++++-------------- 2 files changed, 36 insertions(+), 44 deletions(-) diff --git a/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/api/GeocodeQuery.java b/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/api/GeocodeQuery.java index 44710f49..bf3a711c 100644 --- a/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/api/GeocodeQuery.java +++ b/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/api/GeocodeQuery.java @@ -58,6 +58,7 @@ public class GeocodeQuery extends SharedParameters{ private String streetQualifier; private String localityName; private String stateProvTerr; + private String tagCondition; private int minScore = 0; private EnumSet matchPrecision = null; @@ -428,6 +429,14 @@ public void setExactSpelling(boolean exactSpelling) { this.exactSpelling = exactSpelling; } + public String getTagCondition() { + return tagCondition; + } + + public void setTagCondition(String tagCondition) { + this.tagCondition = tagCondition; + } + public int getNumPrelimResults() { if(fuzzyMatch) { return 100; @@ -477,9 +486,19 @@ public boolean pass(GeocodeMatch match) { return false; } String lowerTags = tags.toLowerCase(); - // OR if tags contain ':' - if(lowerTags.contains(":")) { - String[] tagArray = lowerTags.split(":"); + + boolean useOr = true; + if(tagCondition != null && !tagCondition.trim().isEmpty()) { + String c = tagCondition.trim().toLowerCase(); + if(c.contains("or")) { + useOr = true; + } else if(c.contains("and")) { + useOr = false; + } + } + + if(useOr) { + String[] tagArray = lowerTags.split(";"); for(String t : tagArray) { t = t.trim(); if(keywords.contains(t)) { @@ -488,7 +507,7 @@ public boolean pass(GeocodeMatch match) { } return false; } else { - // default to AND using ';' + // default String[] tagArray = lowerTags.split(";"); List required = new ArrayList(tagArray.length); for(String t : tagArray) { diff --git a/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/data/indexing/TagIndex.java b/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/data/indexing/TagIndex.java index 174fdf38..14c0bc36 100644 --- a/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/data/indexing/TagIndex.java +++ b/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/data/indexing/TagIndex.java @@ -64,58 +64,31 @@ public List add(T item, String tags) { } /** - * Queries the tag index for items that match all or any of the tags listed in the tags parameter - * depending on the presence of ':'. - * @param tags colon/semicolon separated list of tag strings + * Queries the tag index for items that match all of the tags listed in the tags parameter. + * @param tags semicolon separated list of tag strings * @return a set of items matching all the specified tags */ public Set query(String tags) { if(tags == null || tags.isEmpty()) { return Collections.emptySet(); } - String lower = tags.toLowerCase(); + String[] tagArray = tags.toLowerCase().split(";"); Set results = null; - // If tags contains ':' use OR semantics, otherwise default to AND using ';' - if(lower.contains(":")) { - String[] tagArray = lower.split(":"); - for(String tag : tagArray) { - tag = tag.trim(); - if(tag.isEmpty()) continue; - TagIndexEntry tie = index.get(tag); - if(tie == null) { - // missing tag contributes nothing for OR - continue; - } - if(results == null) { - results = new THashSet(tie.items); - } else { - results.addAll(tie.items); - } - } - if(results == null) { + for(String tag : tagArray) { + TagIndexEntry tie = index.get(tag); + if(tie == null) { return Collections.emptySet(); } - return results; - } else { - String[] tagArray = lower.split(";"); - for(String tag : tagArray) { - tag = tag.trim(); - if(tag.isEmpty()) continue; - TagIndexEntry tie = index.get(tag); - if(tie == null) { - return Collections.emptySet(); - } - if(results == null) { - results = new THashSet(tie.items); - } else { - results.retainAll(tie.items); - } - } if(results == null) { - return Collections.emptySet(); + results = new THashSet(tie.items); + } else { + results.retainAll(tie.items); } - return results; } + if(results == null) { + return Collections.emptySet(); + } + return results; } public Set getTags() { From 171384cf93a887f2636ebc30c26a7e178bc61797 Mon Sep 17 00:00:00 2001 From: Mike Zhou Date: Wed, 10 Dec 2025 13:52:57 -0800 Subject: [PATCH 07/14] added some debug info in GeocoderQuery --- .../src/main/java/ca/bc/gov/ols/geocoder/api/GeocodeQuery.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/api/GeocodeQuery.java b/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/api/GeocodeQuery.java index bf3a711c..79876ccf 100644 --- a/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/api/GeocodeQuery.java +++ b/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/api/GeocodeQuery.java @@ -479,6 +479,7 @@ public boolean pass(GeocodeMatch match) { filters.add(new Filter() { @Override public boolean pass(GeocodeMatch match) { + if(match instanceof AddressMatch && ((AddressMatch)match).getAddress() instanceof OccupantAddress) { List keywords = ((OccupantAddress)(((AddressMatch)match).getAddress())).getKeywordList(); @@ -499,9 +500,11 @@ public boolean pass(GeocodeMatch match) { if(useOr) { String[] tagArray = lowerTags.split(";"); + System.out.println(">>>>>>>> keywords: " + keywords + " : " + Arrays.toString(tagArray)); for(String t : tagArray) { t = t.trim(); if(keywords.contains(t)) { + System.out.println(">>>>>>>> matched tag: " + t); return true; } } From fad19a4ea7f72239b71c9f3e05f97fc374dc9ee2 Mon Sep 17 00:00:00 2001 From: Mike Zhou Date: Tue, 30 Dec 2025 09:53:02 -0800 Subject: [PATCH 08/14] fixed issue with fuzzy match when all CAPs are used --- .../src/main/java/ca/bc/gov/ols/geocoder/Geocoder.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/Geocoder.java b/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/Geocoder.java index 97247cb5..fd06f782 100644 --- a/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/Geocoder.java +++ b/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/Geocoder.java @@ -252,12 +252,13 @@ public SearchResults geocode(GeocodeQuery query) { } if(query.isFuzzyMatch() && query.getAddressString() != null && !query.getAddressString().isEmpty()) { - // sort by fuzzy score (higher fuzzy score is better) + final String normalizedInput = query.getAddressString().toLowerCase(); matches.sort( Comparator.comparingInt((GeocodeMatch match) -> - FuzzySearch.ratio(query.getAddressString(), match.getAddressString()) + FuzzySearch.ratio(normalizedInput, match.getAddressString().toLowerCase()) ).reversed() ); + matches = matches.subList(0, Math.min(query.getMaxResults(), matches.size())); } From aa15d9253af7377b617074b2f066da9491d8bd25 Mon Sep 17 00:00:00 2001 From: Mike Zhou <124401782+3rdmike@users.noreply.github.com> Date: Thu, 8 Jan 2026 09:57:01 -0800 Subject: [PATCH 09/14] Rename versions back to 4.5.2 --- ols-geocoder-admin/pom.xml | 2 +- ols-geocoder-core/pom.xml | 2 +- ols-geocoder-process/pom.xml | 2 +- ols-geocoder-web/pom.xml | 2 +- pom.xml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ols-geocoder-admin/pom.xml b/ols-geocoder-admin/pom.xml index 258e0330..eea64378 100644 --- a/ols-geocoder-admin/pom.xml +++ b/ols-geocoder-admin/pom.xml @@ -3,7 +3,7 @@ ca.bc.gov.ols ols-geocoder - 4.5.2-private-road + 4.5.2 OLS Geocoder Admin diff --git a/ols-geocoder-core/pom.xml b/ols-geocoder-core/pom.xml index 38af2e94..a7f255d1 100644 --- a/ols-geocoder-core/pom.xml +++ b/ols-geocoder-core/pom.xml @@ -6,7 +6,7 @@ ca.bc.gov.ols ols-geocoder - 4.5.2-private-road + 4.5.2 OLS Geocoder Core diff --git a/ols-geocoder-process/pom.xml b/ols-geocoder-process/pom.xml index 8a45e6ad..1dec3559 100644 --- a/ols-geocoder-process/pom.xml +++ b/ols-geocoder-process/pom.xml @@ -4,7 +4,7 @@ ca.bc.gov.ols ols-geocoder - 4.5.2-private-road + 4.5.2 ols-geocoder-process OLS Geocoder Process diff --git a/ols-geocoder-web/pom.xml b/ols-geocoder-web/pom.xml index 8d883251..ad396dd9 100644 --- a/ols-geocoder-web/pom.xml +++ b/ols-geocoder-web/pom.xml @@ -6,7 +6,7 @@ ca.bc.gov.ols ols-geocoder - 4.5.2-private-road + 4.5.2 OLS Geocoder Web diff --git a/pom.xml b/pom.xml index b26d9496..f96e63e4 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ ca.bc.gov.ols ols-geocoder - 4.5.2-private-road + 4.5.2 pom OLS Geocoder https://bcgov.github.io/ols-geocoder/ From 70387c3cf5cfe21bbddf1537dec5eb64ada994ac Mon Sep 17 00:00:00 2001 From: Mike Zhou Date: Tue, 13 Jan 2026 12:48:36 -0800 Subject: [PATCH 10/14] add WYN in Geocoder Data Store --- .../src/main/java/ca/bc/gov/ols/geocoder/GeocoderDataStore.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/GeocoderDataStore.java b/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/GeocoderDataStore.java index c41c4e8a..154d3cff 100644 --- a/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/GeocoderDataStore.java +++ b/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/GeocoderDataStore.java @@ -1461,6 +1461,8 @@ private Map buildAbbreviationMappings( // Special case to handle the fact that Rue needs to map to St for french // but Rue is also a valid street type on its own wordMapBuilder.addWordMapping("Rue", "St"); + // Add Wye as a valid street type (railway term for Y-shaped track junction) + wordMapBuilder.addWord("Wye", WordClass.STREET_TYPE); // Add directionals rr = dataSource.getStreetDirs(); From 9b9bae14b11f7db03b3ef3da5ee88928a033c706 Mon Sep 17 00:00:00 2001 From: Mike Zhou Date: Tue, 13 Jan 2026 12:56:21 -0800 Subject: [PATCH 11/14] sublocality map to selve with higher scode than parent --- .../ca/bc/gov/ols/streetprep/StreetPrep.java | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/ols-geocoder-process/src/main/java/ca/bc/gov/ols/streetprep/StreetPrep.java b/ols-geocoder-process/src/main/java/ca/bc/gov/ols/streetprep/StreetPrep.java index 3e9e258d..64a8d066 100644 --- a/ols-geocoder-process/src/main/java/ca/bc/gov/ols/streetprep/StreetPrep.java +++ b/ols-geocoder-process/src/main/java/ca/bc/gov/ols/streetprep/StreetPrep.java @@ -693,11 +693,19 @@ private Map buildLocalityMappings(TIntObjectMap Date: Thu, 22 Jan 2026 09:44:15 -0800 Subject: [PATCH 12/14] revert the parent score adjustment --- .../ca/bc/gov/ols/streetprep/StreetPrep.java | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/ols-geocoder-process/src/main/java/ca/bc/gov/ols/streetprep/StreetPrep.java b/ols-geocoder-process/src/main/java/ca/bc/gov/ols/streetprep/StreetPrep.java index 64a8d066..3e9e258d 100644 --- a/ols-geocoder-process/src/main/java/ca/bc/gov/ols/streetprep/StreetPrep.java +++ b/ols-geocoder-process/src/main/java/ca/bc/gov/ols/streetprep/StreetPrep.java @@ -693,19 +693,11 @@ private Map buildLocalityMappings(TIntObjectMap Date: Wed, 28 Jan 2026 11:14:05 -0800 Subject: [PATCH 13/14] modified fuzzymatch to sort the results more carefully.Pefer exact locality matches over prefix matches --- .../java/ca/bc/gov/ols/geocoder/Geocoder.java | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/Geocoder.java b/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/Geocoder.java index 97247cb5..f35d5948 100644 --- a/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/Geocoder.java +++ b/ols-geocoder-core/src/main/java/ca/bc/gov/ols/geocoder/Geocoder.java @@ -252,12 +252,34 @@ public SearchResults geocode(GeocodeQuery query) { } if(query.isFuzzyMatch() && query.getAddressString() != null && !query.getAddressString().isEmpty()) { - // sort by fuzzy score (higher fuzzy score is better) + // When fuzzy matching is enabled, we need to sort results more intelligently + // than just by fuzzy score alone. We prioritize: + // 1. Exact locality matches (no penalty) over prefix matches (with penalty) + // 2. LOCALITY precision matches for simple word queries without numbers + // 3. Fuzzy score within each priority group + final String queryStr = query.getAddressString(); matches.sort( - Comparator.comparingInt((GeocodeMatch match) -> - FuzzySearch.ratio(query.getAddressString(), match.getAddressString()) - ).reversed() + Comparator + // First, prioritize matches without locality partialMatch faults (exact matches) + .comparing((GeocodeMatch match) -> + match.containsFault(MatchFault.MatchElement.LOCALITY, "partialMatch")) + // Second, for locality-only queries, prioritize LOCALITY precision matches + .thenComparing((GeocodeMatch match) -> { + // Check if this is likely a locality-only query (simple word(s), no numbers) + boolean likelyLocalityQuery = !queryStr.matches(".*\\d+.*"); + // If it's a locality query and this is a LOCALITY match, boost it + if (likelyLocalityQuery && match.getPrecision() == MatchPrecision.LOCALITY) { + return 0; // Higher priority + } + return 1; // Lower priority + }) + // Then sort by fuzzy score (higher is better) + .thenComparing((GeocodeMatch match) -> + FuzzySearch.ratio(queryStr, match.getAddressString()), + Comparator.reverseOrder() + ) ); + // limit to maxResults matches = matches.subList(0, Math.min(query.getMaxResults(), matches.size())); } From 05e4f345811b32dff7a747d28baeefda7f0d5e9a Mon Sep 17 00:00:00 2001 From: Mike Zhou Date: Wed, 28 Jan 2026 11:48:00 -0800 Subject: [PATCH 14/14] upgrade version to 4.5.3 --- .gitignore | 1 + ols-geocoder-admin/pom.xml | 2 +- ols-geocoder-core/pom.xml | 2 +- ols-geocoder-process/pom.xml | 2 +- ols-geocoder-web/pom.xml | 2 +- pom.xml | 2 +- 6 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 5d7d99a8..3bfeecc1 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,4 @@ local.properties .idea local_data +*~ diff --git a/ols-geocoder-admin/pom.xml b/ols-geocoder-admin/pom.xml index eea64378..bedfdb07 100644 --- a/ols-geocoder-admin/pom.xml +++ b/ols-geocoder-admin/pom.xml @@ -3,7 +3,7 @@ ca.bc.gov.ols ols-geocoder - 4.5.2 + 4.5.3 OLS Geocoder Admin diff --git a/ols-geocoder-core/pom.xml b/ols-geocoder-core/pom.xml index a7f255d1..daf16f59 100644 --- a/ols-geocoder-core/pom.xml +++ b/ols-geocoder-core/pom.xml @@ -6,7 +6,7 @@ ca.bc.gov.ols ols-geocoder - 4.5.2 + 4.5.3 OLS Geocoder Core diff --git a/ols-geocoder-process/pom.xml b/ols-geocoder-process/pom.xml index 1dec3559..82bc5d5a 100644 --- a/ols-geocoder-process/pom.xml +++ b/ols-geocoder-process/pom.xml @@ -4,7 +4,7 @@ ca.bc.gov.ols ols-geocoder - 4.5.2 + 4.5.3 ols-geocoder-process OLS Geocoder Process diff --git a/ols-geocoder-web/pom.xml b/ols-geocoder-web/pom.xml index ad396dd9..78c87f2a 100644 --- a/ols-geocoder-web/pom.xml +++ b/ols-geocoder-web/pom.xml @@ -6,7 +6,7 @@ ca.bc.gov.ols ols-geocoder - 4.5.2 + 4.5.3 OLS Geocoder Web diff --git a/pom.xml b/pom.xml index f96e63e4..e0d2d632 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ ca.bc.gov.ols ols-geocoder - 4.5.2 + 4.5.3 pom OLS Geocoder https://bcgov.github.io/ols-geocoder/