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 <[email protected]> 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 _______________________________________________ Pkg-grass-devel mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-grass-devel

