[mapcode] 03/05: Minor speed improvements
Stefan Fritsch
sf at moszumanska.debian.org
Wed Nov 2 23:27:54 UTC 2016
This is an automated email from the git hooks/post-receive script.
sf pushed a commit to tag v2.0.2.4
in repository mapcode.
commit 27f45e06344c488fdd69a1519906545d730c56da
Author: Mapcode C Developer <pieter.geelen at mapcode.com>
Date: Thu Aug 20 11:22:20 2015 +0200
Minor speed improvements
---
README.md | 4 +
mapcodelib/mapcoder.c | 457 ++++++++++++++++++++++----------------------------
mapcodelib/mapcoder.h | 2 +-
3 files changed, 204 insertions(+), 259 deletions(-)
diff --git a/README.md b/README.md
index 701c43e..186c58d 100644
--- a/README.md
+++ b/README.md
@@ -55,6 +55,10 @@ decode Mapcodes.
# Release Notes
+* 2.0.2.3
+
+ Cleaned up source
+
* 2.0.2.2
Cleaned up source
diff --git a/mapcodelib/mapcoder.c b/mapcodelib/mapcoder.c
index b43bd0f..264aa4f 100644
--- a/mapcodelib/mapcoder.c
+++ b/mapcodelib/mapcoder.c
@@ -1159,6 +1159,8 @@ static void encodeAutoHeader(char *result, const encodeRec *enc, int m, int extr
int i;
int STORAGE_START = 0;
int y = enc->lat32, x = enc->lon32;
+ int W, H, xdiv, product;
+ const mminforec *b;
// search back to first of the group
int firstindex = m;
@@ -1167,9 +1169,8 @@ static void encodeAutoHeader(char *result, const encodeRec *enc, int m, int extr
firstindex--;
}
- for (i = firstindex; coDex(i) == codexm; i++) {
- int W, H, xdiv, product;
- const mminforec *b = boundaries(i);
+ for (i = firstindex; i <= m; i++) {
+ b = boundaries(i);
// determine how many cells
H = (b->maxy - b->miny + 89) / 90; // multiple of 10m
xdiv = xDivider4(b->miny, b->maxy);
@@ -1183,41 +1184,40 @@ static void encodeAutoHeader(char *result, const encodeRec *enc, int m, int extr
int GOODROUNDER = codexm >= 23 ? (961 * 961 * 31) : (961 * 961);
product = ((STORAGE_START + product + GOODROUNDER - 1) / GOODROUNDER) * GOODROUNDER - STORAGE_START;
}
+ if (i < m) {
+ STORAGE_START += product;
+ }
+ }
- if (i == m) {
- // encode
- int dividerx = (b->maxx - b->minx + W - 1) / W;
- int vx = (x - b->minx) / dividerx;
- int extrax = (x - b->minx) % dividerx;
+ {
+ // encode
+ int dividerx = (b->maxx - b->minx + W - 1) / W;
+ int vx = (x - b->minx) / dividerx;
+ int extrax = (x - b->minx) % dividerx;
- int dividery = (b->maxy - b->miny + H - 1) / H;
- int vy = (b->maxy - y) / dividery;
- int extray = (b->maxy - y) % dividery;
+ int dividery = (b->maxy - b->miny + H - 1) / H;
+ int vy = (b->maxy - y) / dividery;
+ int extray = (b->maxy - y) % dividery;
- int codexlen = (codexm / 10) + (codexm % 10);
- int value = (vx / 168) * (H / 176);
+ int codexlen = (codexm / 10) + (codexm % 10);
+ int value = (vx / 168) * (H / 176);
- if (extray == 0 && enc->fraclat > 0) {
- vy--;
- extray += dividery;
- }
+ if (extray == 0 && enc->fraclat > 0) {
+ vy--;
+ extray += dividery;
+ }
- value += (vy / 176);
+ value += (vy / 176);
- // PIPELETTER ENCODE
- encodeBase31(result, (STORAGE_START / (961 * 31)) + value, codexlen - 2);
- result[codexlen - 2] = '.';
- encode_triple(result + codexlen - 1, vx % 168, vy % 176);
+ // PIPELETTER ENCODE
+ encodeBase31(result, (STORAGE_START / (961 * 31)) + value, codexlen - 2);
+ result[codexlen - 2] = '.';
+ encode_triple(result + codexlen - 1, vx % 168, vy % 176);
- encodeExtension(result, extrax << 2, extray, dividerx << 2, dividery, extraDigits, -1, enc); // autoheader
- return;
- }
-
- STORAGE_START += product;
+ encodeExtension(result, extrax << 2, extray, dividerx << 2, dividery, extraDigits, -1, enc); // autoheader
}
}
-
static void encoderEngine(int ccode, const encodeRec *enc, int stop_with_one_result, int extraDigits,
int requiredEncoder,
int result_override) {
@@ -1247,54 +1247,53 @@ static void encoderEngine(int ccode, const encodeRec *enc, int stop_with_one_res
*result = 0;
for (i = from; i <= upto; i++) {
- int codex = coDex(i);
- if (codex < 54) {
- if (fitsInside(x, y, i)) {
- if (isNameless(i)) {
- encodeNameless(result, enc, ccode, extraDigits, i);
- }
- else if (recType(i) > 1) {
- encodeAutoHeader(result, enc, i, extraDigits);
- }
- else if (i == upto && isRestricted(i) &&
- isSubdivision(ccode)) // if the last item is a reference to a state's country
- {
- // *** do a recursive call for the parent ***
- encoderEngine(ParentTerritoryOf(ccode), enc, stop_with_one_result, extraDigits, requiredEncoder, ccode);
- return; /**/
- }
- else // must be grid
- {
- // skip isRestricted records unless there already is a result
- if (result_counter || !isRestricted(i)) {
+ if (fitsInside(x, y, i)) {
+ if (isNameless(i)) {
+ encodeNameless(result, enc, ccode, extraDigits, i);
+ }
+ else if (recType(i) > 1) {
+ encodeAutoHeader(result, enc, i, extraDigits);
+ }
+ else if (i == upto && isRestricted(i) &&
+ isSubdivision(ccode)) // if the last item is a reference to a state's country
+ {
+ // *** do a recursive call for the parent ***
+ encoderEngine(ParentTerritoryOf(ccode), enc, stop_with_one_result, extraDigits, requiredEncoder, ccode);
+ return; /**/
+ }
+ else // must be grid
+ {
+ // skip isRestricted records unless there already is a result
+ if (result_counter || !isRestricted(i)) {
+ if (coDex(i) < 54) {
char headerletter = (char) ((recType(i) == 1) ? headerLetter(i) : 0);
encodeGrid(result, enc, i, extraDigits, headerletter);
}
}
+ }
- // =========== handle result (if any)
- if (*result) {
- result_counter++;
-
- repack_if_alldigits(result, 0);
-
- if (requiredEncoder < 0 || requiredEncoder == i) {
- int cc = (result_override >= 0 ? result_override : ccode);
- if (*result && enc->mapcodes && enc->mapcodes->count < MAX_NR_OF_MAPCODE_RESULTS) {
- char *s = enc->mapcodes->mapcode[enc->mapcodes->count++];
- if (cc == ccode_earth) {
- strcpy(s, result);
- } else {
- getTerritoryIsoName(s, cc + 1, 0);
- strcat(s, " ");
- strcat(s, result);
- }
+ // =========== handle result (if any)
+ if (*result) {
+ result_counter++;
+
+ repack_if_alldigits(result, 0);
+
+ if (requiredEncoder < 0 || requiredEncoder == i) {
+ int cc = (result_override >= 0 ? result_override : ccode);
+ if (*result && enc->mapcodes && enc->mapcodes->count < MAX_NR_OF_MAPCODE_RESULTS) {
+ char *s = enc->mapcodes->mapcode[enc->mapcodes->count++];
+ if (cc == ccode_earth) {
+ strcpy(s, result);
+ } else {
+ getTerritoryIsoName(s, cc + 1, 0);
+ strcat(s, " ");
+ strcat(s, result);
}
- if (requiredEncoder == i) { return; }
}
- if (stop_with_one_result) { return; }
- *result = 0; // clear for next iteration
+ if (requiredEncoder == i) { return; }
}
+ if (stop_with_one_result) { return; }
+ *result = 0; // clear for next iteration
}
}
} // for i
@@ -1303,227 +1302,169 @@ static void encoderEngine(int ccode, const encodeRec *enc, int stop_with_one_res
// returns nonzero if error
static int decoderEngine(decodeRec *dec) {
- int parentcode;
- int err;
- int ccode, len;
- char *minus;
- const char *iso3;
- char *s = dec->minput;
-
- // copy input, cleaned of leading and trailing whitespace, into private, non-const buffer
- {
- const char *r = dec->orginput;
- while (*r > 0 && *r <= 32) { r++; } // skip lead
- len = (int) strlen(r);
- if (len > MAX_MAPCODE_RESULT_LEN - 1) { len = MAX_MAPCODE_RESULT_LEN - 1; }
- while (len > 0 && r[len - 1] >= 0 && r[len - 1] <= 32) { len--; } // remove trail
- memcpy(s, r, len);
- s[len] = 0;
- }
+ int hasvowels = 0;
+ int hasletters = 0;
+ int ccode;
+ int err = -817;
+ int codex, prelen; // input codex
+ int from, upto; // record range for territory
+ int i;
+ const char *dot = NULL;
+ char *s;
- // make input (excluding territory) uppercase, and replace digits 0 and 1 with O and I
{
- char *t = strchr(s, ' ');
- if (t == NULL) { t = s; }
- for (; *t != 0; t++) {
- if (*t >= 'a' && *t <= 'z') { *t += ('A' - 'a'); }
- if (*t == 'O') { *t = '0'; }
- if (*t == 'I') { *t = '1'; }
+ int len;
+ char *w;
+ // skip whitesace
+ s = (char *) dec->orginput;
+ while (*s <= 32 && *s > 0) { s++; }
+ // remove trail and overhead
+ len = strlen(s);
+ if (len > MAX_MAPCODE_RESULT_LEN - 1) { len = MAX_MAPCODE_RESULT_LEN - 1; }
+ while (len > 0 && s[len - 1] <= 32 && s[len - 1] >= 0) { len--; }
+ // copy into dec->minput;
+ memcpy(w = dec->minput, s, len);
+ w[len] = 0;
+ // split off iso
+ s = strchr(w, ' ');
+ if (s) {
+ *s++ = 0;
+ while (*s > 0 && *s <= 32) { s++; }
+ ccode = ccode_of_iso3(w, dec->context);
}
- }
-
- // check if extension, determine length without extension
- minus = strchr(s + 4, '-');
- if (minus) {
- len = (int) (minus - s);
- }
-
- // make sure there is valid context
- iso3 = convertTerritoryCodeToIsoName(dec->context, 0); // get context string (or empty string)
- if (*iso3 == 0) { iso3 = "AAA"; }
- parentcode = disambiguate_str(iso3, (int) strlen(iso3)); // pass for future context disambiguation
-
- // insert context if none in input
- if (len > 0 && len <= 9 && strchr(s, ' ') == 0) // just a non-international mapcode without a territory code?
- {
- int ilen = (int) strlen(iso3);
- memmove(s + ilen + 1, s, strlen(s) + 1);
- s[ilen] = ' ';
- memcpy(s, iso3, ilen);
- len += (1 + ilen);
- iso3 = "";
- }
- // parse off extension
- s[len] = 0;
- if (minus) {
- dec->extension = &s[len + 1];
- } else {
+ else {
+ ccode = dec->context - 1;
+ s = w;
+ }
+ if (ccode == ccode_mex && len < 8) {
+ ccode = ccode_of_iso3("5MX", -1);
+ } // special case for mexico country vs state
+ dec->context = ccode;
+ dec->mapcode = s;
dec->extension = "";
- }
-
- // now split off territory, make point to start of proper mapcode
- if (len > 8 && (s[3] == ' ' || s[3] == '-') &&
- (s[6] == ' ' || s[7] == ' ')) // assume ISO3 space|minus ISO23 space MAPCODE
- {
- parentcode = disambiguate_str(s, 3);
- if (parentcode < 0) { return parentcode; }
- s += 4;
- len -= 4;
- }
- else if (len > 7 && (s[2] == ' ' || s[2] == '-') &&
- (s[5] == ' ' || s[6] == ' ')) // assume ISO2 space|minus ISO23 space MAPCODE
- {
- parentcode = disambiguate_str(s, 2);
- if (parentcode < 0) { return parentcode; }
- s += 3;
- len -= 3;
- }
-
- if (len > 4 && s[3] == ' ') // assume ISO whitespace MAPCODE, overriding iso3
- {
- iso3 = s; // overrides iso code!
- s += 4;
- len -= 4;
- }
- else if (len > 3 && s[2] == ' ') // assume ISO2 whitespace MAPCODE, overriding iso3
- {
- iso3 = s; // overrides iso code!
- s += 3;
- len -= 3;
- }
-
- while (*s > 0 && *s <= 32) {
- s++;
- len--;
- } // skip further whitespace
-
- // returns nonzero if error
- ccode = ccode_of_iso3(iso3, parentcode);
- if (ccode == ccode_mex && len < 8) { ccode = ccode_of_iso3("5MX", -1); } // special case for mexico country vs state
-
- // master_decode(s,ccode)
- {
- const char *dot = NULL; // dot position in input
- int prelen; // input prefix length
- int postlen; // input postfix length
- int codex; // input codex
- int from, upto; // record range for territory
- int i;
-
-
- // unpack digits (a-lead or aeu-encoded
- int voweled = unpack_if_alldigits(s);
- if (voweled < 0) {
- return -7;
+ // make upper, handle i and o, split off high precision characters if any
+ for (w = s; *w != 0; w++) {
+ // uppercase
+ if (*w >= 'a' && *w <= 'z') {
+ *w += ('A' - 'a');
+ }
+ // analyse
+ if (*w >= 'A' && *w <= 'Z') {
+ if (*w == 'O') {
+ *w = '0';
+ } else if (*w == 'I') {
+ *w = '1';
+ } else if (*w == 'A' || *w == 'E' || *w == 'U') {
+ hasvowels = 1;
+ } else {
+ hasletters = 1;
+ }
+ }
+ else if (*w == '.') {
+ if (dot) {
+ return -18;
+ } // already had a dot
+ prelen = (int) ((dot = w) - s);
+ }
+ else if (*w == '-') {
+ if (*dec->extension) {
+ return -17;
+ } // already had a hyphen
+ dec->extension = w + 1;
+ *w = 0;
+ }
+ else if (decodeChar(*w) < 0) { // invalid char?
+ return -4;
+ }
}
-
- // debug support: U-lead pre-processing
- if (*s == 'u' || *s == 'U') {
- s++;
- len--;
- voweled = 1;
+ if (!dot) {
+ return -27;
}
- if (len > 10) { return -8; }
+ codex = prelen * 10 + strlen(dot) - 1;
- // find dot and check that all characters are valid
- {
- int nrd = 0; // nr of true digits
- const char *r = s;
- for (; *r != 0; r++) {
- if (*r == '.') {
- if (dot) {
- return -5;
- } // more than one dot
- dot = r;
- }
- else if (decodeChar(*r) < 0) { // invalid char?
- return -4;
- } else if (decodeChar(*r) < 10) { // digit?
- nrd++;
- }
+ if (hasvowels) {
+ if (unpack_if_alldigits(s) <= 0) {
+ return -77;
}
- if (dot == NULL) {
- return -2;
- } else if (!voweled && nrd + 1 == len) { // everything but the dot is digit, so MUST be voweled!
- return -998;
- }//
- }//
-
-//////////// AT THIS POINT, dot=FIRST DOT, input=CLEAN INPUT (no vowels) ilen=INPUT LENGTH
-
- // analyse input
- prelen = (int) (dot - s);
- postlen = len - 1 - prelen;
- codex = prelen * 10 + postlen;
- if (prelen < 2 || prelen > 5 || postlen < 2 || postlen > 4) {
- return -3;
+ }
+ else if (!hasletters) {
+ return -78;
}
- if (len == 10) {
+ if (codex == 54) {
// international mapcodes must be in international context
ccode = ccode_earth;
}
else if (isSubdivision(ccode)) {
// int mapcodes must be interpreted in the parent of a subdivision
-
int parent = ParentTerritoryOf(ccode);
- if (len == 9 || (len == 8 && (parent == ccode_ind || parent == ccode_mex))) {
+ if (codex == 44 || ((codex == 34 || codex == 43) && (parent == ccode_ind || parent == ccode_mex))) {
ccode = parent;
- } //
- } //
+ }
+ }
- // remember final territory context
- dec->context = ccode;
- dec->mapcode = s;
+ }
- err = -817;
+ {
from = firstrec(ccode);
upto = lastrec(ccode);
// try all ccode rectangles to decode s (pointing to first character of proper mapcode)
for (i = from; i <= upto; i++) {
- int codexi = coDex(i);
- if (recType(i) == 0 && !isNameless(i) && (codexi == codex || (codex == 22 && codexi == 21))) {
- err = decodeGrid(dec, i, 0);
-
- // *** make sure decode fits somewhere ***
- if (isRestricted(i)) {
- int fitssomewhere = 0;
- int j;
- for (j = i - 1; j >= from; j--) { // look in previous rects
- if (!isRestricted(j)) {
- if (fitsInsideWithRoom(dec->lon32, dec->lat32, j)) {
- fitssomewhere = 1;
- break;
+ int r = recType(i);
+ if (r == 0) {
+ if (isNameless(i)) {
+ int codexi = coDex(i);
+ if ((codexi == 21 && codex == 22)
+ || (codexi == 22 && codex == 32)
+ || (codexi == 13 && codex == 23)) {
+ err = decodeNameless(dec, i);
+ break;
+ }
+ }
+ else {
+ int codexi = coDex(i);
+ if (codexi == codex || (codex == 22 && codexi == 21)) {
+ err = decodeGrid(dec, i, 0);
+
+ // *** make sure decode fits somewhere ***
+ if (isRestricted(i)) {
+ int fitssomewhere = 0;
+ int j;
+ for (j = i - 1; j >= from; j--) { // look in previous rects
+ if (!isRestricted(j)) {
+ if (fitsInsideWithRoom(dec->lon32, dec->lat32, j)) {
+ fitssomewhere = 1;
+ break;
+ }
+ }
}
- }
- }
- if (!fitssomewhere) {
- err = -1234;
+ if (!fitssomewhere) {
+ err = -1234;
+ }
+ } // *** make sure decode fits somewhere ***
+ break;
}
- } // *** make sure decode fits somewhere ***
- break;
- }
- else if (recType(i) == 1 && prefixLength(i) + 1 == prelen && postfixLength(i) == postlen &&
- headerLetter(i) == *s) {
- err = decodeGrid(dec, i, 1);
- break;
+ }
}
- else if (isNameless(i) &&
- ((codexi == 21 && codex == 22)
- || (codexi == 22 && codex == 32)
- || (codexi == 13 && codex == 23))) {
- err = decodeNameless(dec, i);
- break;
+ else if (r == 1) {
+ int codexi = coDex(i);
+ if (codex == codexi + 10 && headerLetter(i) == *s) {
+ err = decodeGrid(dec, i, 1);
+ break;
+ }
}
- else if (recType(i) >= 2 && postlen == 3 && prefixLength(i) + postfixLength(i) == prelen + 2) {
- err = decodeAutoHeader(dec, i);
- break;
+ else { //r>1
+ int codexi = coDex(i);
+ if (codex == 23 && codexi == 22 || codex == 33 && codexi == 23) {
+ err = decodeAutoHeader(dec, i);
+ break;
+ }
}
} // for
- }
+ }
// convert from millionths
if (err) {
@@ -1798,7 +1739,7 @@ int compareWithMapcodeFormat(const char *s, int fullcode) {
// returns nr of results;
static int encodeLatLonToMapcodes_internal(char **v, Mapcodes *mapcodes, double lat, double lon, int tc,
int stop_with_one_result, int requiredEncoder,
- int extraDigits)
+ int extraDigits)
{
encodeRec enc;
enc.mapcodes = mapcodes;
diff --git a/mapcodelib/mapcoder.h b/mapcodelib/mapcoder.h
index e03592f..51e58db 100644
--- a/mapcodelib/mapcoder.h
+++ b/mapcodelib/mapcoder.h
@@ -18,7 +18,7 @@
extern "C" {
#endif
-#define mapcode_cversion "2.0.2.2"
+#define mapcode_cversion "2.0.2.3"
#define UWORD unsigned short int // 2-byte unsigned integer.
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/mapcode.git
More information about the Pkg-grass-devel
mailing list