summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormvglasow <michael -at- vonglasow.com>2018-08-18 20:31:15 +0200
committermvglasow <michael -at- vonglasow.com>2018-08-18 20:53:47 +0200
commitbdca307cbd0da3f3b1484ec93ee97239cbe4c0a0 (patch)
treefd6c5056ff4bab013c9798e5b93bedcf033ad565
parentb1025f343611464a738c6b0839e1d145c03612a4 (diff)
downloadnavit-bdca307cbd0da3f3b1484ec93ee97239cbe4c0a0.tar.gz
Add:traffic:Handle partial matches for road/junction refs
Signed-off-by: mvglasow <michael -at- vonglasow.com>
-rw-r--r--navit/util.c66
1 files changed, 41 insertions, 25 deletions
diff --git a/navit/util.c b/navit/util.c
index c68f68d28..a29b9ecb6 100644
--- a/navit/util.c
+++ b/navit/util.c
@@ -204,15 +204,21 @@ static char * parse_for_systematic_comparison(const char *s) {
* \li Numeric parts are compared as integers, hence `'042'` equals `'42'`.
* \li Comparison of string parts is case-insensitive.
*
+ * Partial matches are currently determined by determining each part of one string with each part of the other. Each
+ * part of one string that is matched by at least one part of the other increases the score. Order is currently not
+ * taken into account, i.e. `'42A'` and `'A-42A'` are both considered full (not partial) matches for `'A42'`. Future
+ * versions may change this.
+ *
* @param s1 The first string
* @param s2 The second string
*
- * @return 0 if both strings match, nonzero if they do not. Currently `MAX_MISMATCH` is returned for any mismatch;
- * future versions may express the quality of partial matches (lower values indicating better matches).
+ * @return 0 if both strings match, nonzero if they do not. `MAX_MISMATCH` indicates a complete mismatch; values in
+ * between indicate partial matches (lower values correspond to better matches).
*/
int compare_name_systematic(const char *s1, const char *s2) {
int ret = MAX_MISMATCH;
int tmp;
+ int elements = 0, matches = 0;
char *l = NULL, *r = NULL, *l0, *r0;
if (!s1 || !s1[0]) {
@@ -249,39 +255,49 @@ int compare_name_systematic(const char *s1, const char *s2) {
}
/* s1 and s2 are single strings (no semicolons) */
- ret = 0;
-
l0 = parse_for_systematic_comparison(s1);
r0 = parse_for_systematic_comparison(s2);
- l = l0;
- r = r0;
-
- while (!ret && l[0] && r[0]) {
- if (atoi(l) || (l[0] == '0')) {
- if (atoi(r) || (r[0] == '0'))
- ret = (atoi(l) == atoi(r)) ? 0 : MAX_MISMATCH;
- else
- ret = MAX_MISMATCH;
- } else {
- if (atoi(r) || (r[0] == '0'))
- ret = MAX_MISMATCH;
- else
- ret = strcasecmp(l, r) ? MAX_MISMATCH : 0;
+ /* count left-hand elements and all left-hand elements matched by a right-hand element */
+ for (l = l0; l[0]; l += strlen(l) + 1) {
+ elements++;
+ for (r = r0; r[0]; r += strlen(r) + 1) {
+ if (atoi(l) || (l[0] == '0')) {
+ if ((atoi(r) || (r[0] == '0')) && (atoi(l) == atoi(r))) {
+ matches++;
+ break;
+ }
+ } else if (!strcasecmp(l, r)) {
+ matches++;
+ break;
+ }
}
-
- l += strlen(l) + 1;
- r += strlen(r) + 1;
}
- if (!ret)
- ret = (l[0] == r[0]) ? 0 : MAX_MISMATCH;
-
- dbg(lvl_debug, "'%s' %s '%s'\n", s1, ret?"does NOT match":"matches", s2);
+ /* same in the opposite direction */
+ for (r = r0; r[0]; r += strlen(r) + 1) {
+ elements++;
+ for (l = l0; l[0]; l += strlen(l) + 1) {
+ if (atoi(l) || (l[0] == '0')) {
+ if ((atoi(r) || (r[0] == '0')) && (atoi(l) == atoi(r))) {
+ matches++;
+ break;
+ }
+ } else if (!strcasecmp(l, r)) {
+ matches++;
+ break;
+ }
+ }
+ }
g_free(l0);
g_free(r0);
+ ret = ((elements - matches) * MAX_MISMATCH) / elements;
+
+ dbg(lvl_debug, "'%s' %s '%s', ret=%d",
+ s1, ret ? (ret == MAX_MISMATCH ? "does NOT match" : "PARTIALLY matches") : "matches", s2, ret);
+
return ret;
}