[mapcode] 14/32: New version of C code delivered by PG.
Stefan Fritsch
sf at moszumanska.debian.org
Wed Nov 2 23:27:16 UTC 2016
This is an automated email from the git hooks/post-receive script.
sf pushed a commit to annotated tag v1.33
in repository mapcode.
commit b65e2fcc8770c089be94983fc827f0fb520ff8b9
Author: Rijn Buve <rijn at buve.nl>
Date: Thu Aug 28 11:06:54 2014 +0200
New version of C code delivered by PG.
---
mapcoder/basics.h | 2 +-
mapcoder/mapcoder.c | 188 +++++++++++++++++++++++++++++++---------------------
mapcoder/mapcoder.h | 184 ++++++--------------------------------------------
3 files changed, 132 insertions(+), 242 deletions(-)
diff --git a/mapcoder/basics.h b/mapcoder/basics.h
old mode 100644
new mode 100755
index 116c085..8610179
--- a/mapcoder/basics.h
+++ b/mapcoder/basics.h
@@ -1,6 +1,6 @@
#define UWORD unsigned short int // 2-byte unsigned integer
-#define mapcode_cversion "1.3"
+#define mapcode_cversion "1.32"
#define MAXWIDE 10
#define BASEX 31
#define MAXFITLONG 6
diff --git a/mapcoder/mapcoder.c b/mapcoder/mapcoder.c
old mode 100644
new mode 100755
index 9bf9ac8..ad973f5
--- a/mapcoder/mapcoder.c
+++ b/mapcoder/mapcoder.c
@@ -1057,10 +1057,18 @@ int unpack_if_alldigits(char *input) // returns 1 if unpacked, 0 if left unchang
}
+#define VERSION_1_32// 1.32 true recursive processing
+#ifdef VERSION_1_32 // 1.32 true recursive processing
+int result_override=-1;
+#endif
+const char* makeiso(int cc,int longcode); // 0=short / 1=XX-YYY for states, XXX for country / 2=shortest unique
void addresult(char *resultbuffer, char *result, long x,long y, int ccode)
{
// add to global array (if any)
+#ifdef VERSION_1_32 // 1.32 true recursive processing
+ if (result_override>=0) ccode=result_override; // 1.32 true recursive processing
+#endif
if (*result && global_results && nr_global_results>=0 && nr_global_results+1<(2*MAXGLOBALRESULTS)) {
global_results[nr_global_results]=global_buffer[nr_global_results];
strcpy(global_results[nr_global_results++],result);
@@ -1355,8 +1363,7 @@ int master_decode( long *nx,long *ny, // <- store result in nx,ny
long minx,miny,maxx,maxy;
if (isuseless((j))) continue;
getboundaries((j),minx,miny,maxx,maxy);
- int xdiv8 = x_divider(miny,maxy)/4;
- if ( miny-45<=*ny && *ny<maxy+45 && isInRange(*nx,minx-xdiv8,maxx+xdiv8) ) { fitssomewhere=1; break; }
+ if ( miny<=*ny && *ny<maxy && isInRange(*nx,minx,maxx) ) { fitssomewhere=1; break; }
}
if (!fitssomewhere) {
err=-1234;
@@ -1601,6 +1608,11 @@ void master_encode( char *resultbuffer, int the_ctry, long x, long y, int forcec
return;
if (forcecoder>=0 ) // we would have found it the normal way!
return;
+
+#ifdef VERSION_1_32 // 1.32 true recursive processing
+ result_override=the_ctry; // 1.32 true recursive processing
+#endif
+
the_ctry =
mIsUsaState(the_ctry) ? ccode_usa :
mIsCanadaState(the_ctry) ? ccode_can :
@@ -1610,8 +1622,17 @@ void master_encode( char *resultbuffer, int the_ctry, long x, long y, int forcec
mIsChinaState(the_ctry) ? ccode_chn :
mIsRussiaState(the_ctry) ? ccode_rus :
ccode_aus;
+
+
+#ifdef VERSION_1_32 // 1.32 true recursive processing
+ if (!stop_with_one_result)
+ master_encode( resultbuffer, the_ctry, x,y, forcecoder, 0,0,1 );
+ result_override=-1;
+ return; /**/
+#else
setup_country( the_ctry );
i=iso_start-1; continue;
+#endif
}
if ( i>iso_end )
@@ -2163,84 +2184,77 @@ const UWORD* encode_utf16(const char *mapcode,int language) // convert mapcode t
#define TOKENDOT 1
#define TOKENCHR 2
#define TOKENZERO 3
+#define TOKENHYPH 4
#define ERR -1
+#define Prt -9 // partial
#define GO 99
-int lookslike_mapcode(const char *s) // return -999 if partial, 0 if ok, negative if not
-{
- static signed char statemachine[12][4] = {
- // SEP DOT CHR ZER
- { ERR,ERR, 1 ,ERR }, // 0 start
- { ERR, 7 , 2 ,ERR }, // 1 L
- { 0 , 7 , 3 ,ERR }, // 2 LL
- { 0 , 7 , 4 ,ERR }, // 3 LLL
- { ERR, 7 , 5 ,ERR }, // 4 LLLL
- { ERR, 7 , 6 ,ERR }, // 5 LLLLL
- { ERR, 7 ,ERR,ERR }, // 6 LLLLLL
- { ERR,ERR, 8 ,ERR }, // 7 prefix. // decision: do NOT allow immediate decoding when the dot is typed
- { ERR,ERR, 9 , GO }, // 8 prefix.L
- { ERR,ERR,10 , GO }, // 9 prefix.LL
- { ERR,ERR,11 , GO }, //10 prefix.LLL
- { ERR,ERR,ERR, GO } //11 prefix.LLLL
- };
+ static signed char fullmc_statemachine[23][5] = {
+ // WHI DOT DET ZER HYP
+ /* 0 start */ { 0 ,ERR, 1 ,ERR,ERR }, // looking for very first detter
+ /* 1 gotL */ { ERR,ERR, 2 ,ERR,ERR }, // got one detter, MUST get another one
+ /* 2 gotLL */ { 18 , 6 , 3 ,ERR,14 }, // GOT2: white: got territory + start prefix | dot: 2.X mapcode | det:3letter | hyphen: 2-state
+ /* 3 gotLLL */ { 18 , 6 , 4 ,ERR,14 }, // white: got territory + start prefix | dot: 3.X mapcode | det:4letterprefix | hyphen: 3-state
+ /* 4 gotprefix4 */ { ERR, 6 , 5 ,ERR,ERR }, // dot: 4.X mapcode | det: got 5th prefix letter
+ /* 5 gotprefix5 */ { ERR, 6 ,ERR,ERR,ERR }, // got 5char so MUST get dot!
+ /* 6 prefix. */ { ERR,ERR, 7 ,Prt,ERR }, // MUST get first letter after dot
+ /* 7 prefix.L */ { ERR,ERR, 8 ,Prt,ERR }, // MUST get second letter after dot
+ /* 8 prefix.LL */ { 22 ,ERR, 9 , GO,11 }, // get 3d letter after dot | X.2- | X.2 done!
+ /* 9 prefix.LLL */ { 22 ,ERR,10 , GO,11 }, // get 4th letter after dot | X.3- | X.3 done!
+ /*10 prefix.LLLL */ { 22 ,ERR,ERR, GO,11 }, // X.4- | x.4 done!
+
+ /*11 mc- */ { ERR,ERR,12 ,Prt,ERR }, // MUST get first precision letter
+ /*12 mc-L */ { 22 ,ERR,13 , GO,ERR }, // Get 2nd precision letter | done X.Y-1
+ /*13 mc-LL */ { 22 ,ERR,ERR, GO,ERR }, // done X.Y-2 (*or skip whitespace*)
+
+ /*14 ctry- */ { ERR,ERR,15 ,ERR,ERR }, // MUST get first state letter
+ /*15 ctry-L */ { ERR,ERR,16 ,ERR,ERR }, // MUST get 2nd state letter
+ /*16 ctry-LL */ { 18 ,ERR,17 ,ERR,ERR }, // white: got CCC-SS and get prefix | got 3d letter
+ /*17 ctry-LLL */ { 18 ,ERR,ERR,ERR,ERR }, // got CCC-SSS so MUST get whitespace and then get prefix
+
+ /*18 startprefix */ { 18 ,ERR,19 ,ERR,ERR }, // skip more whitespace, MUST get 1st prefix letter
+ /*19 gotprefix1 */ { ERR,ERR,20 ,ERR,ERR }, // MUST get second prefix letter
+ /*20 gotprefix2 */ { ERR, 6 ,21 ,ERR,ERR }, // dot: 2.X mapcode | det: 3d perfix letter
+ /*21 gotprefix3 */ { ERR, 6 , 4 ,ERR,ERR }, // dot: 3.x mapcode | det: got 4th prefix letter
+
+ /*22 whitespace */ { 22 ,ERR,ERR, GO,ERR } // whitespace until end of string
- int state=0;
- int gothyphen=0; // 1 hyphen at most
- int gotsep=0; // 2 seps in toal at most (hyphen+space or space+space)
- int prefix=0;
- int postfix=0;
+ };
- for(;;)
+ // pass fullcode=1 to recognise territory and mapcode, pass fullcode=0 to only recognise proper mapcode (without optional territory)
+ // returns 0 if ok, negative in case of error (where -999 represents "may BECOME a valid mapcode if more characters are added)
+ int lookslikemapcode(const char *s,int fullcode)
{
- // recognise token
- int token,newstate;
- if ( (*s>='a' && *s<='z') || (*s>='A' && *s<='Z') || (*s>='0' && *s<='9')) // letter or digit
- {
- token=TOKENCHR;
- if (state>=7) // got dot!
- postfix++;
- else
- {
- if (prefix==0) if (*s=='a' || *s=='A') prefix--; // dont count A as first letter
- prefix++;
- }
- }
- else if (*s==' ')
- {
- prefix=0; // start again with prefixing
- token=TOKENSEP; if (gotsep++>=2) return -5; // err if already got 2 separators
- }
- else if (*s=='-')
- {
- prefix=0; // start again with prefixing
- token=TOKENSEP; if (gothyphen++>0) return -3; if (gotsep++>0) return -5; // err if already got hyphen or space
- }
- else if (*s=='.')
- {
- token=TOKENDOT;
- }
- else if (*s==0)
- {
- token=TOKENZERO;
- }
- else
- {
- return -4; // invalid char
- }
-
- newstate = statemachine[state][token];
- if (newstate==ERR) return -100-state;
- if (newstate==GO)
- {
- if (prefix>5) return -7; // prefix too long
- if (prefix<2) return -999;
- if (postfix<2) return -999;
- if (prefix==5 && postfix<4) return -999;
- return 0;
- }
- state=newstate;
- s++;
+ int nondigits=0;
+ int state=(fullcode ? 0 : 18); // initial state
+ for(;;s++) {
+ int newstate,token;
+ // recognise token
+ if (*s>='0' && *s<='9') token=TOKENCHR;
+ else if ((*s>='a' && *s<='z') || (*s>='A' && *s<='Z'))
+ { token=TOKENCHR; if (state!=11 && state!=12) nondigits++; }
+ else if (*s=='.' ) token=TOKENDOT;
+ else if (*s=='-' ) token=TOKENHYPH;
+ else if (*s== 0 ) token=TOKENZERO;
+ else if (*s==' ' || *s=='\t') token=TOKENSEP;
+ else return -4; // invalid character
+ newstate = fullmc_statemachine[state][token];
+ if (newstate==ERR)
+ return -(1000+10*state+token);
+ if (newstate==GO )
+ return (nondigits>0 ? 0 : -5);
+ if (newstate==Prt)
+ return -999;
+ state=newstate;
+ if (state==18)
+ nondigits=0;
+ }
}
+
+int lookslike_mapcode(const char *s) // return -999 if partial, 0 if ok, negative if not
+{
+ // old-style recognizer, does not suport territory context
+ return lookslikemapcode(s,0);
}
@@ -2469,7 +2483,7 @@ int text2tc(const char *string,int optional_tc) // optional_tc: pass 0 or negati
// pass point to an array of pointers (at least 64), will be made to point to result strings...
// returns nr of results;
-int coord2mc( char **v, double lat, double lon, int tc )
+int coord2mc_full( char **v, double lat, double lon, int tc, int stop_with_one_result ) // 1.31 allow to stop after one result
{
int ccode=tc-1;
if (tc==0) ccode=0;
@@ -2483,12 +2497,13 @@ int coord2mc( char **v, double lat, double lon, int tc )
{
int i;
for(i=0;i<MAX_CCODE;i++) {
- master_encode(NULL,i,(long)lon,(long)lat,-1,0,0,0); // 1.29 - also add parents recursively
+ master_encode(NULL,i,(long)lon,(long)lat,-1,stop_with_one_result,0,0); // 1.29 - also add parents recursively
+ if (stop_with_one_result && nr_global_results>0) break;
}
}
else
{
- master_encode(NULL,ccode,(long)lon,(long)lat,-1,0,0,0); // 1.29 - also add parents recursively
+ master_encode(NULL,ccode,(long)lon,(long)lat,-1,stop_with_one_result,0,0); // 1.29 - also add parents recursively
}
global_results=NULL;
return nr_global_results/2;
@@ -2526,5 +2541,26 @@ const UWORD* encode_to_alphabet(const char *mapcode,int alphabet) // 0=roman, 2=
#endif
+int coord2mc( char **v, double lat, double lon, int tc )
+{
+ return coord2mc_full(v,lat,lon,tc,0);
+}
+
+int coord2mc1( char *result, double lat, double lon, int tc )
+{
+ char *v[2];
+ int ret=coord2mc_full(v,lat,lon,tc,1);
+ *result=0;
+ if (ret>0) {
+ if (strcmp(v[1],"AAA")!=0) {
+ strcpy(result,v[1]);
+ strcat(result," ");
+ }
+ strcat(result,v[0]);
+ }
+ return ret;
+}
+
+
#endif // RELEASENEAT
diff --git a/mapcoder/mapcoder.h b/mapcoder/mapcoder.h
old mode 100644
new mode 100755
index 370dab7..38f84b7
--- a/mapcoder/mapcoder.h
+++ b/mapcoder/mapcoder.h
@@ -1,182 +1,36 @@
-// Releases: always set RELEASE+RELEASENEAT,
-// (0) India borders: define TESTINDIA
-// (1) NavCore3: define RELEASE_FOR_NAVCORE, undefine CSVAPP
-// (2) NavKit: undefine RELEASE_FOR_NAVCORE
-// (3) mapcoder: define CSVAPP, RELEASE_FOR_NAVCORE, RELEASENEAT
-// (4) isotable: undefine NEAT/NAV/CSV (make sure you #define DUMP_ISOTABLE)
-// (5) web: undefine RELEASE_FOR_NAVCORE, undefine CSVAPP
#define RELEASENEAT // use clean code (mapcoder.c)
-//#define RELEASE_FOR_NAVCORE
-//#define CSVAPP // disable for isotable
-
+#define CSVAPP // disable for isotable and for C library
#define UWORD unsigned short int // 2-byte unsigned integer
+#define SUPPORT_FOREIGN_ALPHABETS
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//
-// #defines
-//
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-// *** should be defined!
- #define RELEASE
-#define SUPPORT_AUTOSPLIT // if rect is "almost" perfect xside/yside, make it perfect
-#define PREPROCESS_NUMERIC_CODES
-#define INCLUDEWORLD
-#define LIMIT_TO_OUTRECT
-#define RESTRICTUSELESS
-#define INTEGER_ARITHMETIC_ONLY // from now on, do only integer arithmentic, no floating point
-#define REMOVE_VALIDCODE // deprecated routine
-
-#ifndef RELEASE_FOR_NAVCORE
- #define SUPPORT_FOREIGN_ALPHABETS
- #define SUPPORT_DMS
- #define SUPPORT_LBS_WRAPPER
-#endif
-
-
-// *** should be undefined
-#ifndef RELEASE
- #define EXIT_WHEN_ERROR
- #define VERBOSE
- #define PRINTDISTANCE
- #define PRINTDISTANCE_IN_FILE
- // #define PRINTWARNINGS
-#endif
-
-// *** should be undefined!
-// #define SUPPRESS_MULTIPLE_PIPES // when encoding - undefined since NavCore3
-
-#ifdef CSVAPP
- #undef SUPPORT_DMS
- #undef SUPPORT_LBS_WRAPPER
-#endif
-
-
-
-
-////////////////////////////////////////////////////////////////
-//
-// disambiguation: call disambiguate(x) depending on the map that is loaded
-//
-////////////////////////////////////////////////////////////////
-
-// pass a number to disambiguate a 2-letter state codes
-// 1 - assume USA
-// 2 - assume India
-// 3 - assume Canada
-// 4 - assume Australia
-// 5 - assume Mexico
-// 6 - assume Brazil
-// 7 - assume Russia
-// 8 - assume China
-void disambiguate( int country );
-
-// Pass a string (not necessarily zero-term,inated) and its length (e.g. "NLD",3 or "US",2)
-// No need to check the return value, but:
-// returns negative if this string did not lean to disambiguation
-// returns a positive number (1-8) if it did
-int disambiguate_str( const char *s, int len ); // returns disambiguation >=1, or negative if error
-
-
-////////////////////////////////////////////////////////////////
-//
-// Low-level routines,
-//
-////////////////////////////////////////////////////////////////
-
-// retuns the "ccode" for a given ISO code (3 letter country code, or 2-letter state code)
-int ccode_of_iso3(const char *in_iso);
-
-// returns iso3 for ccode
-const char *entity_iso3(int ccode);
-
-// returns full ISO3166 iso code (between 3 and 7 characters, e.g. AU-QLD is Queensland state, Australia)
-const char *makeiso(int cc,int longcode);
-
-// setup country - call before accessing any of the other low-level routines
-void setup_country( int ccode );
-
-// returns nonzero if x,y is in area of ccode
-int isInArea(long x,long y,int ccode);
-
-// returns next ccode that contains x,y;
-// pass -1 the first time, pass previous ccode to find the next return value;
-// returns -1 when no more areas contain x,y;)
-int findAreaFor(long x,long y,int ccode);
-
-#ifdef SUPPORT_DMS
-int interpret_coords( unsigned char *i, double *x, double *y ); // returns negative if i does not look like a valid latitude/longitude
-// display as Degrees Minutes Seconds (precise to ca 15 meters)
-// pass degree symbol appropriate to your operating system in degsym, e.g. 176 (in ISO-8859-1 and its extension CP1252), although the ordinal indicator 167=� and 248 (Latin1) are also often used
-unsigned char *asdms(unsigned char *r,double lat,double lon,unsigned char degsym); // make sure r is at least 23 bytes (for worstcase including zts: -##d##'##",-###d##'##")
-#endif
-
-#ifdef SUPPORT_FOREIGN_ALPHABETS
-////////////////////////////////////////////////////////////////
-//
-// Foreign languages
-//
-////////////////////////////////////////////////////////////////
-#define MAXLANS 14 // 0=Roman 1=Greek 2=Cyrillic 3=Hebrew 4=Hindi 5=Malai 6=Georgisch 7=Katakana 8=Thai 9=Lao 10=Armenian 11=Bengali 12=Gurmukhi 13=Tibetan
-const UWORD* encode_utf16(const char *mapcode,int language); // convert mapcode to UTF16 in given language (0=roman 1=greek ...)
-const char *decode_utf16(const UWORD* s); // convert unicode (UTF16) to mapcode
-#endif // ifdef SUPPORT_FOREIGN_ALPHABETS
-
-
-////////////////////////////////////////////////////////////////
-//
-// High-level routines
-//
-////////////////////////////////////////////////////////////////
-
-#ifndef REMOVE_VALIDCODE
-// returns < 0 if invalid, 0 if potentially valid, 1 if potentially a complete code (i.e. from 2.2 to 5.4, using valid chars)
-int valid_code( const char *input );
-#endif
-
-// returns 0 if ok, negative if too different (no dot, two dots, two hyphens, three spaces, >5 letters before dot (unless the last one is an A), 5 letters after dot, invalid character, <2 or >3 letters before a hyphen)
-// return -999 if the mapcode looks OK but is PARTIAL (or INCOMPLETE); example incomplete mapcodes are XX.X or XXXXX.XXX
-int lookslike_mapcode(const char *s);
-
-// encode x,y in a given country or state (states are disambiguated based on the last call to disambiguate();)
-// result must be 11 bytes for worst-case (Earth) zts encode; returns empty string if error (e.g. bad iso);
-// returns nonzero if a code was generated
-// * if iso_found not NULL, it is filled with the "full" zts iso code (must be at least 7 bytes! worst-case result: AU-QLD)
-int mapcode_encode(char *result,long y, long x, const char *iso3,char *iso_found);
+// pass array of at least 64 strings, each at least 16 bytes
+// returns nr of results
+// pass tc=0 to get mapcodes in ALL territories
+int coord2mc( char **v, double lat, double lon, int tc ); // returns n = nr of results (stored in v[0]...v[2*n-1]
-// decode an input into coordinates x,y (within the context of a country or state; states are disambiguated based on the last call to disambiguate();)
-// returns nonzero if error
-// * if ccode_found is not NULL, it is filled with the RECOGNISED, DISAMBIGUATED code (and display entity_iso3(ccode_found) rather than iso3);
-// note that ccode_found can be negative if the iso3 is not recognised or the input contains an unrecognised iso code as prefix!
-// * if clean_input is not NULL, it is filled with the "clean" zts input (must be 11 chars to store the worst "earth" code)
-int full_mapcode_decode(long *y, long *x, const char *iso3, const char *input,int *ccode_found,char *clean_input);
-int mapcode_decode(long *y, long *x, const char *iso3, const char *input,int *ccode_found);
+// returns at most one mapcode (the shortest possible in the rettitory (or in ALL territories if tc=0 is passed); r must be large enough to store 24 characters including a zero terminator;
+int coord2mc1( char *result, double lat, double lon, int tc ); // returns positive in case of success (mapcode stored in result)
+// Converting a mapcode into a coordinate
+int mc2coord( double *lat, double *lon, const char *string, int context_tc ); // context_tc is used to disambiguate ambiguous short mapcode inputs; pass 0 or negative if not available
-#ifdef SUPPORT_LBS_WRAPPER
+// pass fullcode=1 to recognise territory and mapcode, pass fullcode=0 to only recognise proper mapcode (without optional territory)
+// returns 0 if ok, negative in case of error (where -999 represents "may BECOME a valid mapcode if more characters are added)
+int lookslikemapcode(const char *s,int fullcode);
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//
-// Wrapper for LBS team
-//
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Routines related to territories
+int text2tc(const char *string,int optional_tc); // returns negative, or tc
// formats: 0=full 1=short (state codes may be ambiguous)
const char *tc2text(int tc,int format); // returns temporary pointer to a string (will be destroyed by the next call)
-int text2tc(const char *string,int optional_tc); // returns negative, or tc
-int tcparent(int tc); // returns tc of parent country (if tc is a state), or negative
-int tccontext(int tc); // returns tc if tc is a country, parent country if tc is a state, -1 if tc is invalid
-int mc2coord( double *lat, double *lon, const char *string, int context_tc ); // context_tc is used to disambiguate ambiguous short mapcode inputs; pass 0 or negative if not available
-
-// pass array of at least 64 strings, each at least 16 bytes
-// returns nr of results
-// pass tc=0 to get mapcodes in ALL territories
-int coord2mc( char **v, double lat, double lon, int tc ); // returns n = nr of results (stored in v[0]...v[2*n-1]
+int tccontext(int tc); // returns tc if tc is a country, parent country if tc is a state, -1 if tc is invalid
+int tcparent(int tc); // returns tc of parent country (if tc is a state), or negative
+// Routines related to Unicode and/or foreign alphabets
+#define MAXLANS 14 // 0=Roman 1=Greek 2=Cyrillic 3=Hebrew 4=Hindi 5=Malai 6=Georgisch 7=Katakana 8=Thai 9=Lao 10=Armenian 11=Bengali 12=Gurmukhi 13=Tibetan
const char *decode_to_roman(const UWORD* s);
const UWORD* encode_to_alphabet(const char *mapcode,int alphabet); // 0=roman, 2=cyrillic, 4=hindi, 12=gurmukhi
-#endif
--
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