mobile-atlas-creator-1.9.14+dfsg1/0000755000175000017500000000000012217014251016517 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/build.xml0000644000175000017500000003317512171650636020365 0ustar paulliupaulliu -libraryjars "${rtlibraryjar}" -injars "${jar.name}" -outjars build/temp.jar -keepattributes *Annotation* -keep class ${main.class} { public static void main(java.lang.String[]); } -keep class mobac.program.* { public *; } -keep class mobac.program.interfaces.* { public *; } -keep class mobac.program.model.package-info -keep class mobac.program.model.* { public *; } -keep class mobac.program.jaxb.* { public *; } -keep class mobac.program.interfaces.* { public *; } -keep class mobac.program.download.UserAgent { public *; } -keep class mobac.exceptions.* { public *; } -keep class mobac.program.tilestore.berkeleydb.* { *; } -keep class mobac.program.tilestore.TileStoreEntry { public *; } -keep class mobac.program.atlascreators.AtlasCreator { public *; } -keep class mobac.utilities.beanshell.* { public *; } -keep class mobac.utilities.tar.TarIndex { public *; } -keep class mobac.utilities.tar.TarIndexedArchive { public *; } -keep class mobac.data.gpx.gpx11.* { public *; } -keep class mobac.mapsources.MapSourceTools { public *; } -keep class mobac.mapsources.MapSourceUrlUpdater { public *; } -keep class mobac.mapsources.custom.* { *; } -keep class org.apache.log4j.Layout { public *; } -keep class org.apache.log4j.Level { public *; } -keep class org.apache.commons.lang3.StringEscapeUtils { public *; } -keep class org.apache.log4j.Category { public *; } -keep class org.apache.log4j.Priority { public *; } -keep class org.apache.log4j.spi.LoggingEvent { public *; } -keep class org.apache.log4j.spi.ThrowableInformation { public *; } -keep class org.apache.log4j.spi.LocationInfo { public *; } -keep class org.apache.log4j.PatternLayout { public *; } -keep class org.apache.log4j.Appender { public *; } -keep class org.apache.log4j.FileAppender { public *; } -keep class com.sixlegs.png.PngImage { public *; } -keep class bsh.This { public *; } -keep class bsh.XThis { public *; } -keep class com.sleepycat.persist.PrimaryIndex { public *; } -keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); } -keepclassmembers class * implements java.io.Serializable { static final long serialVersionUID; private void writeObject(java.io.ObjectOutputStream); private void readObject(java.io.ObjectInputStream); java.lang.Object writeReplace(); java.lang.Object readResolve(); } -keepclassmembers class * implements com.sleepycat.persist.evolve.Conversion { boolean equals(java.lang.Object); } -dontwarn -dontoptimize -dontobfuscate mobile-atlas-creator-1.9.14+dfsg1/.classpath0000644000175000017500000000366612140762732020526 0ustar paulliupaulliu mobile-atlas-creator-1.9.14+dfsg1/misc/0000755000175000017500000000000012122526610017454 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/misc/launch4j.xml0000644000175000017500000000227112122526610021710 0ustar paulliupaulliu true gui Mobile_Atlas_Creator.jar ..\Mobile Atlas Creator.exe normal http://java.com/download false false mobac.ico 1.6.0_14 preferJre 1024 1.0.0.0 - Mobile Atlas Creator Windows Launcher MOBAC developers 1.0.0.0 - Mobile Atlas Creator Mobile Atlas Creator 1024MB max Heap Mobile Atlas Creator.exe mobile-atlas-creator-1.9.14+dfsg1/misc/mobac.ico0000644000175000017500000003275612122526610021246 0ustar paulliupaulliu  6h 00 %F( @ycRFO<.8#8"M9+fTHyv8$''(-,-./0/=$x0 %**.266788:659 jhgLB;)-3468>=>?@CA?V=+uuussswus/47:>AGGJKKNJHHxsquuuk\S<?CHLSTWXY [#X U Rtsjbvvv{J'EJPV[!c'f%j'l(m)o,k)g(~S9±|qhwwwgQFEGORZc"j%s+v)~4 @.2~/z-rYų|||V:+@FNX a"j%t)}-4a?̸vVƲdz[A+dNCBGOZf&o'z,15U)ɞzfVrI#HOZe$s+.4:?ȿ˲Y6M*EPXd$s+49@ FLڿz_Jve\CLY#d&r+/8=ELSܺФqL'JT `$l&{-5?GNV\Ҵ{[AuibO0!HNXg&v+3:EOV^d|&ⶥmVnJ-> AJR^!n'28AKV]elu@ɕeB[,C$S0LWe$v+5<GQ_ f m t {~ _b4\D7K$N\"j&|-;CNWahpv~ ձΥiּͫ|Z>q\OL%O^#p*3;DOYelsz BֲphТԯ | !z$ԏUָqXH Qb&q*2;HQ\fov} t$H~ ۈ1seǶ㶞bEpS1R"^"s+2<JR]gq w} GȐΜ1cgœܛXʵfOAiG1]#p*3<GT]fr y  ӫⱃuO7k)2:FT ]g o t{ AٵÞw(̉S|YL]MV_jq v| fܾҿ丆`ƨ~cÞM RZck pv { !麃 GmΪzQKTZc hm r t z9ҰϮmݧqLCwFϘm[ a ֍NڎIk nׄ8⯀һp\lPx[a6U̺әkq._^` ` ̺eLR3ga\-ɹ[STTÄS˘q[FmlJ`*K GQ\,ɾ»s_DiMuTU'=>=>d>sa>zFp4r5}FdB??( |sP=/8"8 T@1~s*/3:;=;aSJC&=EMQSPnP=r`WIR_"m(w1 x-s+ÚaI0A-3 3 8"J5&B-E1!VD5S{maeUHTA3h@,/)(((+()*++0,1?*TA3hvh]qcWE1"2 ((%'(*,0-.//0400//9!N=1ocYVC6s3 &%)(*,-/2534555965443ULE^\Zjfbr3K:-(%&(/.1357:<;<=<=@?=<:9jb[ttthhhdb`|tn([|{{YTPa][*-/52458:>??@@ABCEAAAD! }}}qqqfdbrh_Kxxxxpppuuuqnk,/367:<>@EEFGHIIJL HGFEhP@xxxgda^PFcxwwwpppzzzP=13:9=@BEGMMNPQQQRU#QPNLJ}}}mig[F6i^yyyqqq{{{:@@BEILOU UWYZ [ \!\!_&Z!Y!V!T U%`SIveXX4qqq{{{Y>0>EEINTW!["b( b%e&g'i'k(l)k)n- h'e%b$`'}n\L@wl3 rrr||||I&AFN OSWZ^ c"k(k%n&p'q(s)t)u*y/v,t-r-\AvpleWKԛ vvv{{{W<.ADGJQSX] d#i$m&u,w*y+}.\<>0050/|.~9xmaWo^Q }}}zzz|yR5&?AFKOX!] b"i%o'u){,30N'ű|JAf{vL,ukcyyy|A ABFKQYb&f$m's){,/29FuhJ%Y=%wg`=EGLR[ b"k)p'w+-148FϻlR>L' |fU|}}}S4$AJLSZ a"i%t,z,/37;>ʭM$aB)pӆjSHAFNRXa"i%r(}115=@EJ kL3X5ȡ$eMB?EJT W_"h%s+~19 :>BEHLП|P'pVA^D CIOY"a%i(t-{.2:;@EIORӛrZ3jJ0[vpls`WAGNX"a( e%m'z,05>AGJPTX޽rT<^9ZKB|oiF EOT Xc&k&u*/4;BGKPVZ_ژbm[_8^MDއB FLNU]!j)q)}.38?ENPV[`dj к|V8p^a:G0%T:.AGLQYb#m(z.17<CJR V[`ejo ކ0|Be7Z/ = =BHPT]!h%r)24:@GMW Z_ejnuyԸa9itL-Z,B%?P,IRXa"l&x+47=DKQ[ _e l q u y~jɮxWs^\. R:-D!^=+JT[ e$p(|-79@JR Y be i mquz ~ !jvh`K+GNVd(p,z-29BGNU\bl nty| ;B (9C|vxic eźW5s^zT6rbYnB I N[%c&o)|-3:BIPW^dl quz &u V 9~ ܞ\o v#hy=pQzch7}\Bouk*B[;&Q"W!a#p+}/4;CLPX^en qvz ,<9=ȖKϩߠ^ܞaϻײo,X:&^B/O!U `#o)|/4:AMRX_elrv{~ vׯxײ;ҵĥ`G7xj`l_[,`$l(|04;AHSX^dkux } $‹}&ಇ|u"w`(i'w-49@FR Y b g l q tx| Joe [ ټd7Ƶ#Y?v4 X4> FUO TZagn rvz} <̞|ۺḒђ[otæ)G}|UJSW\djp swz ~}s'o|)}tǾ_ùҧ)"xftM/m<t=x?u5y5{6|7~8~8{7z>V/΂#Ŀ~l+aFp}T3uEtBn8 l3m4q9 xE|L'̀V5}o+?????mobile-atlas-creator-1.9.14+dfsg1/gpl.txt0000644000175000017500000004310012122526622020045 0ustar paulliupaulliu GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License.mobile-atlas-creator-1.9.14+dfsg1/README.HTM0000644000175000017500000016735012175454032020052 0ustar paulliupaulliu Mobile Atlas Creator - Readme

Mobile Atlas Creator - Read-me

Welcome to Mobile Atlas Creator read-me file for end users.

Before January 2010 this project was known as "TrekBuddy Atlas Creator".

Mobile Atlas Creator is an open source project hosted on SourceForge.net:
http://mobac.sf.net

Table of contents


License

Mobile Atlas Creator is under GNU General Public License Version 2 (GPL). For details on the GPL see the license file gpl.txt.
The source code is available on the SourceForge.net for download and in the project's source code Subversion repository.

Description

Mobile Atlas Creator creates atlases for several applications. For example TrekBuddy and Mobile Trail Explorer (MTE), the Android applications AndNav, Maverick, Big Planet Tracks, RMaps, OruxMaps, the Pocket PC application Glopus and the commercial Windows application OziExplorer. The map image created for OziExplorer can also be used with any PNG capable image viewer (map image in one large PNG file).

Requirements

This application requires that a Java Runtime Environment Version 6 Update 14 (v1.6.0_14) or higher is installed on the computer.

If you have the choice between different Java Runtimes you should prefer the Java Runtime provided by Sun/Oracle. Especially the OpenJDK has some bugs regarding MOBAC and tends to crash on certain situations.

Java Advanced Imaging (optional)

For reducing the color depth of downloaded tiles the library files ( jai_core.jar and jai_codec.jar ) of the "Java Advanced Imaging" (JAI) have to be present on the system respectively in the same directory as Mobile_Atlas_Creator.jar. Ready to use binary builds of the Java Advanced Imaging library can be obtained at http://download.java.net/media/jai/builds/release/1_1_3/jai-1_1_3-lib.zip

Installation

Copy or move the unzipped files to a folder where you would like to have Mobile Atlas Creator installed. On computers running Windows please make sure not to install MOBAC into Program Files sub-directory!

Application start

Windows

The application is started by executing the Mobile Atlas Creator.exe . During the first application start all necessary files and folders are automatically created by the application.

Linux and OSX

You can start MOBAC by executing the start-up script start.sh . Before starting MOBAC the first time it may be necessary to set the executable bit for start.sh e.g. by executing the following command:

chmod u+x start.sh

During the first application start all necessary files and folders are automatically created by the application.


The different atlas formats

AFTrack OSZ

For creating atlases compatible with AFTrack (Symbian S60) you have to select AFTrack (OSZ) as format in atlas format selection dialog that appears when starting a new atlas (menu Atlas entry New Atlas).

OSZ is a ZIP-archive. Within this zip archive a (large) number of tiles with the calibrated folder structure (coordinates) are stored. OSZ only works if each tile has got a resolution of 256x256 Pixels. So be sure to uncheck Recreate/adjust map tiles (CPU intensive).

The output format is one file for each layer in the corresponding folder.

Restrictions

Depending on the device free memory the file maybe not work. So more then 80000 tiles should not be used.

AlpineQuestMap (AQM)

Sorry no further details are available for this atlas format.

Creating and using atlases with AndNav

For creating atlases compatible with AndNav you have to select AndNav atlas format as format in atlas format selection dialog that appears when starting a new atlas (menu Atlas entry New Atlas).
As atlases for AndNav do not support all features provided by Mobile Atlas Creator the following settings are ignored when creating atlases for AndNav:

  • Change height or width of the map tiles
  • Name of all layers and maps
  • Structure of the atlas (which maps belongs to which layer)

Creating and using atlases with Big Planet Tracks

For creating offline atlases compatible with Big Planet Tracks (Android application) you have to select Big Planet Tracks SQLite as format in atlas format selection dialog that appears when starting a new atlas (menu Atlas entry New Atlas).
The atlas format BigPlanet SQLite does not support all features provided by Mobile Atlas Creator the following settings can not be used or are ignored when creating atlases using this output format:

  • Recreate/adjust map tiles with custom tile size (height and
  • Name of all layers and maps
  • Structure of the atlas (which maps belongs to which layer)
  • Atlases created after another are merged into one Database named [Atlasname] atlas.sqlitedb which is located in the atlas output directory.

Creating atlases for CacheWolf

For creating atlases compatible with CacheWolf you have to select CacheWolf WFL as format in atlas format selection dialog that appears when starting a new atlas (menu Atlas entry New Atlas).

Custom tile processing settings enabled

Maps that have custom tile processing options set are saved as tiled images with one WFL calibration file for each tile. All processing options such as image format and tile size can be used.

Custom tile processing settings disabled

In this mode automatic tiling is disabled and the same restrictions and the warning as for the OziExplorer output format apply.

The output format of an "atlas" for CacheWolf is one subdirectory per layer and within this subdirectory one PNG image and one WFL file per defined map.

Creating Garmin Custom maps

For creating atlases of Creating Garmin Custom maps you have to select Garmin Custom Map (KMZ) as format in atlas format selection dialog that appears when starting a new atlas (menu Atlas entry New Atlas).
Details about the Garmin Custom Map format can be found in the Garmin Forums

Using this atlas output format the following features are ignored when creating atlases:

  • Recreate/adjust map tiles (custom tile size and image format)

The output format of an "atlas" for Garmin Custom maps is one KMZ file per layer containing all maps (max 100) as seperate JPG image files. The JPEG compression rate can be specified for each map/image using image format selector in the custom tile processing section. The Garmin Custom Map format defines a maximum image size of 1024x1024 pixels. If a map is larger it will be automatically scaled down to fit into this size. You can prevent scaling when setting the max map size in the settings dialog to 1024.

Creating atlases for Glopus

For creating atlases compatible with Glopus you have to select Glopus (PNG & KAL) or Glopus Map File (GMF) as format in atlas format selection dialog that appears when starting a new atlas (menu Atlas entry New Atlas).

Glopus (PNG & KAL)

Using this atlas output format the same restrictions and the warning as for the OziExplorer output format apply.

The output format of an "atlas" for Glopus is one subdirectory per layer and within this subdirectory one PNG image and one KAL file per defined map.

Glopus Map File (GMF)

Within this file a (large) number of tiles with its calibrated coordinates are stored. Glopus works best if each tile has a resolution of 1024x1024 pixels. So check Recreate/adjust map tiles (CPU intensive). Width and height should be set to 1024.

The output format is one file for each layer in the corresponding folder.

Glopus Map File (GMF) / AFTrack

For creating atlases compatible with AFTrack (Symbian S60) you have to select Glopus Map File (GMF) as format in atlas format selection dialog that appears when starting a new atlas (menu Atlas entry New Atlas).

Within this file a (large) number of tiles with its calibrated coordinates are stored. AFTrack works best if each tile has got a resolution of 256x256 Pixels. So uncheck Recreate/adjust map tiles (CPU intensive).

The output format is one file for each layer in the corresponding folder.

Restrictions

AFTrack can handle a maximum of 4096 tiles - so be sure not to select more.

Google Earth Overlay (KMZ)

For creating Google Earth Overlays you have to select Google Earth Overlay (KMZ) as format in atlas format selection dialog that appears when starting a new atlas (menu Atlas entry New Atlas).

Using this atlas output format the following features are ignored when creating atlases:

  • Recreate/adjust map tiles (custom tile size and image format)

Warning

The Google Earth Overlay atlas format uses JPG images. The image size depends on the selected maximum map size (see settings dialog). The theoretical maximum map size for this atlas format is 25000. However it is strongly recommended not to set the maximum map size higher than 10000 (this will result in a image with uncompressed size about 286 MB).

Creating Magellan RMP atlases

For creating atlases of Creating Garmin Custom Maps you have to select Magellan (RMP) as format in atlas format selection dialog that appears when starting a new atlas (menu Atlas entry New Atlas).

Using this atlas output format the following features are ignored when creating atlases:

  • Recreate/adjust map tiles (custom tile size and image format)

Additionally some other limitations may apply, based on which device and firmware version you are using. Mobile Atlas Creator does not chek those limitations - therefore it may work or not if you are using:

  • An atlas with more than 5 maps.
  • Maps with a zoom level higher than 15.

The output format of an "atlas" for Magellan is one RMP file in the atlas directory. You can directly load this file in Magellan VantagePoint or transfer it onto your device.

Creating atlases for MAPLORER

For creating atlases compatible with MAPLORER you have to select the Maplorer atlas format as format in atlas format selection dialog that appears when starting a new atlas (menu Atlas entry New Atlas). You have to choose JPG image format under Layer settings/tile format (PNG is not supported by Maplorer).

There are no specific limits on tile sizes and/or numbers; good results for hiking/biking can be obtained using zoom level 15, custom tile size of 1024x1024 (check Recreate/adjust map tiles (CPU intensive) under Layer settings. For good performance, avoid using too big or too many tiles (the maximum number of columns in Maplorer is currently 26 ('A' to 'Z'), but it is preferable to use less).

After defining the maps and layers (select region and click Add selection under Atlas Content) for the atlas, click the button Create Atlas. Once atlas download and creation has completed, all necessary files belonging to the atlas can be found in the directory atlases\[atlas name]_[current date and time] .

To install the atlas on your device, simply connect it to your PC and copy the content of the respective atlas subdirectory (i.e. all .jpg and .pos files generated) to the Maplorer directory (the one which contains maplorer.exe) on your device. Starting Maplorer on the device will automatically read all tiles and create the index map. Detailed instructions on making maps for Maplorer can be found at http://maplorer.com

Creating and using atlases with Maverick

For creating atlases compatible with Maverick you have to select Maverick atlas format as format in atlas format selection dialog that appears when starting a new atlas (menu Atlas entry New Atlas).
As atlases for Maverick do not support all features provided by Mobile Atlas Creator the following settings are ignored when creating atlases for AndNav:

  • Recreate/adjust map tiles (custom tile size and image format)
  • Name of all layers and maps
  • Structure of the atlas (which maps belongs to which layer)

For further information how to use offline atlases with Maverick please see Maverick Online Help on Setting up offline maps.

Creating and using atlases with MGMaps

For creating atlases compatible with MGMaps you have to select MGMaps as format in atlas format selection dialog that appears when starting a new atlas (menu Atlas entry New Atlas). Select a name for the maps, this is important as you will use it to view the maps in MGMaps.

How to copy the maps to your device

  1. Create a folder named MGMapsCache in the root of you device or memorycard
  2. Copy the created folders into this MGMapsCache folder so the directory structure looks like:
MGMapsCache
MGMapsCache\cache.conf
MGMapsCache\macos_10
MGMapsCache\macos_11
MGMapsCache\macos_12
MGMapsCache\macos_10\59_53.mgm
MGMapsCache\macos_11\150_106.mgm
MGMapsCache\macos_11\150_107.mgm
MGMapsCache\macos_11\151_106.mgm
MGMapsCache\macos_11\151_107.mgm
MGMapsCache\macos_12\365_213.mgm
MGMapsCache\macos_12\365_214.mgm
MGMapsCache\macos_12\366_213.mgm
MGMapsCache\macos_12\366_214.mgm
	

How to set up MGMaps to use the maps

  1. Select Settings/Map/Stored Maps, Click on the two boxes labelled Stored Maps and Offline Mode. The first box enables the use of stored map mode. The second box prohibits the use of the mobile phones Internet connect to download live maps. You can leave this unchecked if you want. stored maps folder: now tell MGMaps where you have stored the map tile files. in my case SDCard/MGMapsCache.
  2. Select Settings/Map/Map types, select options/add custom map,in map type name enter the name of the map you created using MAC in my case macos, map type url you can leave blank, select ok/options/save MGMaps will then apply the settings and display your created map.

Warning

Avoid using names native to MGMaps such as google, each name used must be defined as a custom map so the directory structure below must have macos,macroad and macsat defined as custom map types.

MGMapsCache MGMapsCache\cache.conf MGMapsCache\macos_10
MGMapsCache\macos_11 MGMapsCache\macroad_11 MGMapsCache\macsat_11
MGMapsCache\macos_12 MGMapsCache\macroad_12 MGMapsCache\macsat_12

Creating and using atlases with Mobile Trail Explorer (MTE)

For creating atlases compatible with Mobile Trail Explorer you have to select Mobile Trail Explorer Cache as format in atlas format selection dialog that appears when starting a new atlas (menu Atlas entry New Atlas).
If a map source uses an image format different to PNG the tiles will be automatically converted to the PNG format.
The output is one MTEFileCache file per atlas which contains all maps. An existing cache file can not be updated. If you want to add maps to an existing MTEFileCache please use the atlas format Mobile Trail Explorer which creates a file structure identical to JTileDownloader and then process the maps using MTE CacheCreator.
As atlases for Mobile Trail Explorer does not support all features provided by Mobile Atlas Creator the following settings are ignored when creating atlases for Mobile Trail Explorer:

  • Recreate/adjust map tiles (custom tile size and image format)
  • Name of all layers and maps
  • Structure of the atlas (which maps belongs to which layer)

Creating atlases for NaviComputer

For creating atlases, compatible with NaviComputer, you have to select NaviComputer (NMAP) as format in atlas format selection dialog that appears when starting a new atlas (menu Atlas entry New Atlas).
After defining the maps and layers for the atlas to be created, start atlas download and creation via the button Create Atlas. Once download and creation has completed, the generated file with the extension nmap can be found in the MOBAC output directory. This *.nmap-file is the required input file for NaviComputer.

Creating atlases for nfComPass

For creating atlases, compatible with nfComPass, you have to click Atlas -> New Atlas, select nfComPass and give your Atlas a name.
By default atlases with a tilesize of 64x64 are created (recommended). For different tile sizes check Recreate/adjust map tiles (CPU intensive) under Layer settings. Set Tileformat can not be changed - it is always png. Maybe you must tryout, what is the best tilesize for your device. Choose your layer and zoomlevels and click Add selection. Then click Create atlas. Once download and creation has completed, the generated folders can be found in the MOBAC output directory. You must copy the data from the nfComPass.dat to your nfComPass.dat and fill in the path to your mapdirectory. After that, copy the folder(s) to your device. If it is possible, you should not copy the files with Active Sync to your device.

Creating OruxMaps atlases

For creating atlases compatible with OruxMaps as format you have to select OruxMaps as format in atlas format selection dialog that appears when starting a new atlas (menu Atlas entry New Atlas).

Using this atlas output format the following features are ignored when creating atlases:

  • Layer settings, custom tile size. OruxMaps always uses 512x512 tile size. You can select the tile format (PNG or JPEG). If you do not select any, default value is JPEG - quality 90.

The output format of an "atlas" for OruxMaps is one or more map directories in the atlas directory. You have to copy those maps onto your device (default directory: /oruxmaps/mapfiles/).

Creating atlases for OSMAND

For creating atlases compatible with OSMAND you have to select OSMAND tile storage or OSMAND SQlite as format in atlas format selection dialog that appears when starting a new atlas (menu Atlas entry New Atlas).
As atlases for OSMAND do not support all features provided by Mobile Atlas Creator the following settings are ignored when creating atlases for OSMAND:

  • Change height or width of the map tiles
  • Name of all layers and maps
  • Structure of the atlas (which maps belongs to which layer)

Creating atlases for Osmdroid

For creating atlases compatible with Osmdroid you have to select either Osmdroid ZIP, Osmdroid SQLite or Osmdroid GEMF as format in atlas format selection dialog that appears when starting a new atlas (menu Atlas entry New Atlas).
The mentioned three formats are "single file" atlases. One of the other possible atlas formats might also be acceptable for Osmdroid. Also, there is other software that is able to deal with GEMF archives.
As atlases for Osmdroid do not support all features provided by Mobile Atlas Creator the following settings are ignored when creating atlases for Osmdroid:

  • Change height or width of the map tiles
  • Name of all layers and maps
  • Structure of the atlas (which maps belongs to which layer)

Creating atlases for OSMTracker

For creating atlases compatible with OSMTracker you have to select OSMTracker tile storage as format in atlas format selection dialog that appears when starting a new atlas (menu Atlas entry New Atlas).
As atlases for OSMTracker do not support all features provided by Mobile Atlas Creator the following settings are ignored when creating atlases for OSMTracker:

  • Change height or width of the map tiles
  • Name of all layers and maps
  • Structure of the atlas (which maps belongs to which layer)

Creating and using atlases with OziExplorer / large PNG image export

For creating atlases compatible with OziExplorer you have to select OziExplorer (PNG & MAP) as format in atlas format selection dialog that appears when starting a new atlas (menu Atlas entry New Atlas).

Restrictions

As OziExplorer does not support tiled maps some features are ignored when creating atlases in this format:

  • Image output format is fix: 24bit PNG
  • Recreate/adjust map tiles custom tile is ignored

The output format of an "atlas" for OziExplorer is one subdirectory per layer and within this subdirectory one PNG image and one MAP file per defined map. For opening a map in OziExplorer select the menu FileLoad from FileLoad from MAP file, browse to the layer directory of the created atlas and select the MAP file.

If you are only interested in the map image you can safely delete the created map file.

Warning

Mobile Atlas Creator uses a highly sophisticated and optimized algorithm for creating the PNG files for OziExplorer use. This algorithm allows to create very large maps images at low memory usage. OziExplorer and most image viewers do not use such sophisticated algorithms which can lead to the situation that you can create very large map images - but OziExplorer and other image viewers are not able to open the image.

Creating atlases for PathAway

For creating atlases compatible with PathAway you have to select PathAway tile cache as format in atlas format selection dialog that appears when starting a new atlas (menu Atlas entry New Atlas).
As atlases for PathAway do not support all features provided by Mobile Atlas Creator the following restrictions apply when creating atlases for PathAway:

  • The maximum zoom level is 16 - higher zoom levels are not possible with this atlas format
  • Tile width and width can not be changed (settings will be ignored)
  • Name of all layers and maps is ignored
  • Structure of the atlas is ignored (which maps belongs to which layer)

Creating and using atlases with RMaps

For creating offline atlases compatible with RMaps (Android application) you have to select RMaps SQLite as format in atlas format selection dialog that appears when starting a new atlas (menu Atlas entry New Atlas).
The atlas format RMaps does not support all features provided by Mobile Atlas Creator the following settings can not be used or are ignored when creating atlases using this output format:

  • Recreate/adjust map tiles with custom tile size (height and width have to be 256)
  • Name of all layers and maps
  • Structure of the atlas (which maps belongs to which layer)
  • Atlases created after another are merged into one Database named [AtlasName] atlas.sqlitedb which is located in the atlas output directory.

[Nokia] Sports Tracker

For creating atlases compatible with Sports Tracker(ST) you have to select Sports Tracker (NOT GPS Sportstracker) as format in atlas format selection dialog that appears when starting a new atlas (menu Atlas entry New Atlas).

Do not select Recreate/adjust map tiles.

Maximum Zoomlevel of Sports Tracker is 17, default is 13.

Copy the created atlas (the whole folder) into the following folder of youre phone (depending of the Sports Tracker version):

  • Sports Tracker 1.76: E:\system\data\Maps\Street\
  • Sports Tracker 2.x: E:\system\data\Maps\Street\
  • Sports Tracker 3.x: E:\system\data\STMaps\Street\

For changing the zoom level inside Storts Tracker press 5 to zoom in and 0 to zoom out.

Creating and using atlases with Touratech QV / large PNG image export

For creating atlases compatible with Touratech QV you have to select Touratech QV as format in atlas format selection dialog that appears when starting a new atlas (menu Atlas entry New Atlas).

Restrictions

As Touratech QV does not support tiled maps some features are ignored when creating atlases in this format:

  • Image output format is fix: 24bit PNG
  • Recreate/adjust map tiles custom tile is ignored

The output format of an "atlas" for Touratech QV is one subdirectory per layer and within this subdirectory one PNG image and one CAL file per defined map.

If you are only interested in the map image you can safely delete the created cal file.

Warning

Mobile Atlas Creator uses a highly sophisticated and optimized algorithm for creating the PNG files for Touratech QV use. This algorithm allows to create very large maps images at low memory usage. Touratech QV and most image viewers do not use such sophisticated algorithms which can lead to the situation that you can create very large map images - but Touratech QV and other image viewers are not able to open the image.

Creating atlases using TomTom Raster format

TBD

Creating and using atlases with TrekBuddy

For creating atlases compatible with TrekBuddy you have to select TrekBuddy tared atlas or TrekBuddy untared atlas as format in atlas format selection dialog that appears when starting a new atlas (menu Atlas entry New Atlas).

After defining the maps and layers for the atlas to be created start atlas download and creation via the button Create Atlas. Once atlas download and creation has completed all necessary files belonging to the atlas can be found in the directory atlases\[atlas name]_[current date and time] .

The atlas itself consists of the atlas startup file cr.tar (tar format) or cr.tba (regular/untared format) and the subdirectories containing the different maps of the atlas. For using the atlas with TrekBuddy copy the whole directory onto your J2ME device. Then use the Load Atlas function of TrekBuddy and open cr.tar / cr.tba (in the atlas root directory).

Creating and using atlases with TwoNav & CompeGPS Land/Air

To create atlases compatible with TwoNav software you have to select TwoNav (RMAP) as format in atlas format selection dialog that appears when starting a new atlas (menu Atlas entry New Atlas). Atlases created for TwoNav are stored in a format called rmap. It's a binary format that holds the same map data stored at different resolutions - in order to make zooming in and out on low performance mobile devices fast and efficient. However, this causes some restrictions which have to be taken into account:

  • Each map within a layer has to have the same geographical bounds.
  • There only can be one map in a layer with a given zoom level

If there are several layers in one atlas, each layer will be stored as a separate rmap file.

The easiest way to create a correct atlas content is: first select the appropriate grid zoom (combobox next to the zoom slider), then pick zoom levels from the selected grid zoom up to the zoom level of the desired most detailed level, and finally add a selection to the Atlas content by clicking on the "Add selection" button.

Rmap format also requires no gaps in a zoom level range from the maximum to the minimum selected zoom level. If there are missing zoom levels, they will be created internally by shrinking the existing downloaded tiles. If the missing zoom levels contain a lot of tiles, this operation could take a while.

Finally copy the layer.rmap file from the atlases\[atlas name]_[current date and time] folder to your TwoNav maps folder.

As TwoNav does not support all available features provided my MOBAC, some features can not be used when creating atlases in this format:

  • Custom tile height and width (is ignored for TwoNav RMP atlases)
  • Custom tile format: Only JPEG formats are allowed

Creating and using atlases with Viewranger

For creating atlases compatible with Viewranger(VR) you have to select Viewranger as format in atlas format selection dialog that appears when starting a new atlas (menu Atlas entry New Atlas).

Maximum Zoomlevel of Viewranger is 18, minimum is 3.

After creating youre atlas the folder structure looks like:

  • Mobile Atlas Creator 1.9\atlases\VR_2012-03-28_154944\OSM\13\4308
  • Mobile Atlas Creator 1.9\atlases\VR_2012-03-28_154944\OSM\14\43
  • Mobile Atlas Creator 1.9\atlases\VR_2012-03-28_154944\google\13\4308
  • Mobile Atlas Creator 1.9\atlases\VR_2012-03-28_154944\google\14\43

Now we have to Create a Folder Structure on the Device:

If you youre VR Folder is on E: it is on Symbian located in E:/ViewRanger/MapCache/_PAlbTN/

In this folder create following Subfolders, if not already present:

84,85,87,88,89,129

e.g. /ViewRanger/MapCache/_PAlbTN/84

Copy the content of "OSM" into 84, "google" into 85 and so on.

Now it looks like: E:/ViewRanger/MapCache/_PAlbTN/13/4308/2687 , 2687 is a tile

VR has different Online Mapsources which are assigned to the Numbers as shown:

  • OSM->84
  • Opencyclemap->85
  • OSM Direct->87
  • OSM Midnigth->88
  • OSM Fresh->89
  • Open Piste Map->129

Of course you can fill the Tilecache with different Maps.

I use the Open Piste Map eg. as "OSM Public Transport"

Enhancement requests

If you are missing the map provider of your choice or have other enhancement ideas for Mobile Atlas Creator feel free to open an Feature Request Ticket at SourceForge.

If have a new online map which is not available in Mobile Atlas Creator there my be change to add it. Before opening a Feature Request please take a look into the list of map sources known to incompatible with Mobile Atlas Creator.

Problems, Bugs & Errors

In case of unexpected errors while executing Mobile Atlas Creator you may get presented a exception dialog containing detailed information about the problem. In such a case please create a new ticket in the Bug Tracker at SourceForge. Please add the detailed exception information and a detailed description of your last performed actions.

The default error log

By default Mobile Atlas Creator records all errors of the current session into it's error log file Mobile Atlas Creator.log . This log file is located on Windows system in the directory %APPDATA%\Mobile Atlas Creator\ and on Linux/Unix/OSX system in the directory ~/.mobac/

Activate the advanced logging system

If the recorded errors in the error log do not indicate a problem you can activate the overall message logging mechanism of Mobile Atlas Creator:
Download the file log4j.xml and save it in the directory where the jar file of Mobile Atlas Creator is installed to.

The next start Mobile Atlas Creator will create a log file in the current directory (on Windows this is usually the directory where the JAR file is located on Linux usually the profile directory). Please note that the log file is erased on each program start. If you think you have found a bug please file it in the bug tracker at SourceForge.

Known problems and limitations

New map sources

Mobile Atlas Creator is limited to map sources that provide their maps if form of map tiles. Each of that map tiles has to be of size 256x256 pixels. Additionally the map source has to use the spherical Mercator projection and the number of tiles forming the world on each zoom level has to be one of the following values: 20, 21, 22 ... 221, 222.
For more details see OpenStreetMap Wiki: Slippy map tilenames, Mercator, Height and width of a map and Zoom levels

Java Bugs

Due to bugs in Java you should not do the following:

  • Install Mobile Atlas Creator into a directory which path contains an "!" (exclamation mark) because of this Sun Java bug
  • Do not use OpenJDK if you want to work with GPX tracks in Mobile Atlas Creator
  • On Windows without a system proxy set (see connection settings of IE) it is strongly recommended not to use the following proxy setting:Use standard Java proxy settings

Details for advanced users

Specifying directory configuration

The following steps are necessary if MOBAC is installed to to a directory that is not writable for reguar users:

For changing the directory configuration pattern for all users of a MOBAC installation save this file into the same directory where Mobile_Atlas_Creator.jar has been installed into and change it's name to directories.ini . For more details read the comments in this configuration file.

Moving the tile store directory

Usually the tile store directory where Mobile Atlas Creator saves all downloaded images in is automatically determined.
In case you want to select a different directory perform the following steps:

  1. Make sure you have closed MOBAC
  2. Open settings.xml in an text editor
  3. Inside of the tag <settings> search for the tag <directories>. Inside this tag create a new tag named <tileStoreDirectory>
  4. Set the path name to the value of this tag (Windows users should replace backslashes with a slashes)
  5. (optional) Copy or move the content of the old tile store directory into the new tile store directory.

Example

<settings>
    <directories>
        <tileStoreDirectory>E:/tiles</tileStoreDirectory>
    </directories>
    ...
</settings>

This specified the windows directory E:\tiles as new tile store directory. The previously used tile store will not be used anymore.
Deleting the <tileStoreDirectory> tag restores the old behavior (automatically tile store directory selection).

Starting external tools from within MOBAC

External tools like scripts or other executable programs can be started from the Tools menu from within MOBAC. This menu is only visible if external programs have been configured. The advantage of starting a program from within MOBAC is that certain information about selected map source, selected region ... can be transmitted as parameters to the executed program.
This allows you for example to create your own maps (render tiles) with external tools like OSMFILTER, OSMCONVERT, MAPERITIVE...

For defining an external program, create an xml file for each external program to be called. The content of the xml file has to be like one of the following examples. The file-name of the xml is not relevant - it only has to end with .xml

test.xml

Demonstrates how to execute an Windows batch file.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ExternalTool>
 <name>Name shown in tools menu</name>
 <command>cmd.exe /c start .\tools\mybatch.cmd</command>
 <parameters>MIN_LON MIN_LAT MAX_LON MAX_LAT MIN_ZOOM MAX_ZOOM MAPSOURCE_NAME MAPSOURCE_DISPLAYNAME NAME_EDITBOX </parameters>
 <debug>true</debug>
</ExternalTool>

Annotated sample file download

test-exe.xml

Demonstrates how to execute an regular windows program.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ExternalTool>
 <name>Name shown in tools menu</name>
 <command>C:\sample-path\program.exe</command>
 <parameters>MIN_LON MIN_LAT MAX_LON MAX_LAT MIN_ZOOM MAX_ZOOM MAPSOURCE_NAME MAPSOURCE_DISPLAYNAME NAME_EDITBOX </parameters>
 <debug>true</debug>
</ExternalTool>

The most interesting section is the content of <parameters>. It contains a space separated list of parameters the specified command will be executed with. The following values can be used:

  • MAX_LAT - Maximum latitude (upper border) off the selected area
  • MIN_LAT - Minimum latitude (lower border) off the selected area
  • MAX_LON - Maximum longitude (right border) off the selected area
  • MIN_LON - Minimum longitude (left border) off the selected area
  • MIN_ZOOM - minimum zoom of selected zoom levels check-boxes
  • MAX_ZOOM - maximum zoom of selected zoom levels check-boxes
  • MAPSOURCE_NAME - Currently select map source internal name (used in atlas profile xml file)
  • MAPSOURCE_DISPLAYNAME - Currently select map source display name (as shown in the GUI)
  • NAME_EDITBOX - content of the edit box "Name" in the side panel "Atlas Content"

Custom map sources

Simple custom map sources

Custom map sources which uses a similar URL scheme as Google/OpenStreetMap can be added by saving for each custom map source the definition in form of an xml file in the mapsources directory.

The following section shows is an example how the xml file has to be formatted. It defines an additional map source named "Custom OSM Mapnik" which shows map tiles identical to the predefined map source "OpenStreetMap Mapnik".

Note:The name specified in there has to be unique among all available map sources within MOBAC. The list of all available map sources can be obtained via command Show all map source names in the menu Debug.

<?xml version="1.0" encoding="UTF-8"?>
<customMapSource>
	<name>Custom OSM Mapnik</name>
	<minZoom>0</minZoom>
	<maxZoom>18</maxZoom>
	<tileType>png</tileType>
	<tileUpdate>None</tileUpdate>
	<url>http://tile.openstreetmap.org/{$z}/{$x}/{$y}.png</url>
	<backgroundColor>#000000</backgroundColor>
</customMapSource>

The most important part of this definition is the url. It is a template containing specific placeholders which are encapsulated by curly brace:

  • {$z} for the zoom level - number range: [minZoom .. maxZoom]
  • {$x} for the x tile coordinate - number range: [0..2zoom level ]
  • {$y} for the y tile coordinate - number range: [0..2zoom level ]

Note: If the url contains the ampersand character & you have to encode it as &amp;. Otherwise it not be valid XML and therefore can not bo loaded by MOBAC.

Example file for download: Example custom map source.xml

Custom WMS map sources

Similar a WMS map source can be defined. Currently only EPSG:4326 as coordinatesystem is supported.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<customWmsMapSource>
    <name>TerraServer WMS</name>
    <minZoom>12</minZoom>
    <maxZoom>18</maxZoom>
    <tileType>JPG</tileType>
    <version>1.1.1</version>
    <layers>DRG</layers>
    <url>http://terraserver-usa.com/ogcmap6.ashx?</url>
    <coordinatesystem>EPSG:4326</coordinatesystem>
    <aditionalparameters>&amp;EXCEPTIONS=BLANK&amp;Styles=</aditionalparameters>
    <backgroundColor>#000000</backgroundColor>
</customWmsMapSource>

Example file (with comments) for download: Example custom WMS map source.xml

Custom multi-layer map sources

The same way as custom map sources map sources which consist of two or more layers can be defined as well. Note that all except the background map source layer (first in the list) must have transparent parts - otherwise layers in the list before will not be visible.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<customMultiLayerMapSource>
    <name>Custom OSM Mapnik with Hills (Ger)</name>
    <tileType>PNG</tileType>
    <layers>
        <customMapSource>
            <name>Custom OSM Mapnik</name>
            <minZoom>0</minZoom>
            <maxZoom>18</maxZoom>
            <tileType>PNG</tileType>
            <tileUpdate>None</tileUpdate>
            <url>http://tile.openstreetmap.org/{$z}/{$x}/{$y}.png</url>
            <backgroundColor>#000000</backgroundColor>
        </customMapSource>
        <customMapSource>
            <name>Custom transparent hillshade</name>
            <minZoom>0</minZoom>
            <maxZoom>18</maxZoom>
            <tileType>PNG</tileType>
            <tileUpdate>None</tileUpdate>
            <url>http://www.wanderreitkarte.de/hills/{$z}/{$x}/{$y}.png</url>
        </customMapSource>
    </layers>
</customMultiLayerMapSource>

Example file for download: Example custom multi-layer map source.xml

Custom CloudMade map sources

The CloudMade map service offers a large number of OpenStreetMap based maps with different styles. Each style is accessible through it's styleID . Custom CloudMade maps can be added to MOBAC via a simple XML file containing a map name used by MOBAC and a styleID:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<cloudMade>
    <displayName>CloudMade blackout</displayName>
    <styleID>1960</styleID>
</cloudMade>

Example file for download: Example CloudMade1960.xml

Custom BeanShell map sources

BeanShell map sources as the can be developed using MapEvaluator can be used by MOBAC. To do so place the saved BeanShell code file (file extension .bsh ) in the mapsources directory. It will be loaded on next start-up of MOBAC.

It is recommended to add a line defining the map source name (must be unique).

name = "Your map source name here";

Example file for download: Example beanshell map source.bsh

Custom Map Pack

Developing a custom map pack requires at least basic Java skills. Therefore the description on how to develop a custom map pack is only part of the source code release of MOBAC. You can get the source code of MOBAC by using the latest src release available in the files section at Sourceforge or you can get it directly from the Subversion code repository using the latest trunk version.

Custom atlas as map source / locally generated tiles

Existing atlases or locally rendered tiles can be directly integrated into MOBAC as custom map source without having to set-up a local web-server.
At the moment the formats used by OSMTracker, AndNav, Maverick and OSMAND are supported. For adding such an atlas as map source download the Example custom tile files source.xml file, adapt the <sourceFolder> entry and place it in the mapsources directory.

Tiles can also be packed into one or more zip files and directly used by MOBAC. For details please see the Example custom tile zip source.xml.
Note: When working with large ZIP files (more than 4 GB) it is required to use Java 7.

SQLite based atlas formats can also be used directly by MOBAC. For details please see the Example custom tile SQLite source.xml

mobile-atlas-creator-1.9.14+dfsg1/.project0000644000175000017500000000131412122526602020170 0ustar paulliupaulliu MOBAC org.eclipse.jdt.core.javabuilder org.eclipse.ui.externaltools.ExternalToolBuilder clean,full,incremental, LaunchConfigHandle <project>/.externalToolBuilders/Svnversion.launch org.eclipse.jdt.core.javanature mobile-atlas-creator-1.9.14+dfsg1/log4j.xml0000644000175000017500000000337012122526622020270 0ustar paulliupaulliu mobile-atlas-creator-1.9.14+dfsg1/lib/0000755000175000017500000000000012217014251017265 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/start.sh0000644000175000017500000000061612122526622020220 0ustar paulliupaulliu#!/bin/sh # If you see this file in an editor you may have to set the executable bit and execute it as script in a terminal # This file will start the Mobile Atlas Creator with custom memory settings for # the JVM. With the below settings the heap size (Available memory for the application) # will range from 64 megabyte up to 1024 megabyte. java -Xms64m -Xmx1024M -jar Mobile_Atlas_Creator.jarmobile-atlas-creator-1.9.14+dfsg1/src/0000755000175000017500000000000012122526602017311 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/0000755000175000017500000000000012122526606020241 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/0000755000175000017500000000000012122526602021156 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/0000755000175000017500000000000012134265562022247 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/0000755000175000017500000000000012134265562024262 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/beanshell/0000755000175000017500000000000012122526606026213 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/beanshell/Tools.java0000644000175000017500000000544512122526606030166 0ustar paulliupaulliupackage mobac.utilities.beanshell; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.security.SecureRandom; import mobac.mapsources.MapSourceTools; import mobac.mapsources.mapspace.MercatorPower2MapSpace; import mobac.program.interfaces.MapSpace; import org.apache.commons.codec.DecoderException; import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Hex; public class Tools { @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface MethodDescription { String value(); } public static final SecureRandom RND = new SecureRandom(); public static final MapSpace OSM_MERCATOR = MercatorPower2MapSpace.INSTANCE_256; @MethodDescription("Converts an horizontal tile number on a certain zoom level " + "into the corespondent longitude") public static double xTileToLon(int x, int zoom) { return OSM_MERCATOR.cXToLon(x, zoom); } @MethodDescription("Converts an vertical tile number on a certain zoom level " + "into the corespondent latitude") public static double yTileToLat(int y, int zoom) { return OSM_MERCATOR.cYToLat(y, zoom); } @MethodDescription("Returns a random value. Range [0..max]") public int getRandomInt(int max) { return RND.nextInt(max + 1); } @MethodDescription("Converts a tile numer on a certain zoom level into a quad tree coordinate") public static String encodeQuadTree(int zoom, int tilex, int tiley) { return MapSourceTools.encodeQuadTree(zoom, tilex, tiley); } @MethodDescription("Returns a byte array of length length filled with random data.") public byte[] getRandomByteArray(int length) { byte[] buf = new byte[length]; RND.nextBytes(buf); return buf; } @MethodDescription("Encodes the binaryData byte array to a " + "base64 String without line breaks") public static String encodeBase64(byte[] binaryData) { return new String(Base64.encodeBase64(binaryData)); } @MethodDescription("Decodes an base64 encoded String to a byte array") public static byte[] decodeBase64(String base64String) { return Base64.decodeBase64(base64String); } @MethodDescription("Encodes the binaryData byte array to a hexadecimal String " + "without line breaks, leading 0x and spaces") public static String encodeHex(byte[] binaryData) throws DecoderException { return Hex.encodeHexString(binaryData); } @MethodDescription("Decodes an hexadecimal encoded String to a byte array. The string have to " + "contain only the hexadecimal encoded nibbles.") public static byte[] decodeHex(String hexString) throws DecoderException { return Hex.decodeHex(hexString.toCharArray()); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/tar/0000755000175000017500000000000012122526606025044 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/tar/TarIndex.java0000644000175000017500000000425012122526606027426 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities.tar; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; import org.apache.log4j.Logger; public class TarIndex { private static final Logger log = Logger.getLogger(TarIndex.class); private File tarFile; private RandomAccessFile tarRAFile; private TarIndexTable tarIndex; public TarIndex(File tarFile, TarIndexTable tarIndex) throws FileNotFoundException { super(); this.tarFile = tarFile; this.tarIndex = tarIndex; tarRAFile = new RandomAccessFile(tarFile, "r"); } public byte[] getEntryContent(String entryName) throws IOException { long off = tarIndex.getEntryOffset(entryName); if (off < 0) return null; tarRAFile.seek(off); byte[] buf = new byte[512]; tarRAFile.readFully(buf); TarHeader th = new TarHeader(); th.read(buf); int fileSize = th.getFileSizeInt(); log.trace("reading file " + entryName + " off=" + off + " size=" + fileSize); byte[] data = new byte[fileSize]; tarRAFile.readFully(data); return data; } public int size() { return tarIndex.size(); } public void close() { try { tarRAFile.close(); } catch (IOException e) { } } public void closeAndDelete() { close(); tarFile.deleteOnExit(); tarFile.delete(); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/tar/TarArchive.java0000644000175000017500000001005112122526606027734 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities.tar; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.Arrays; import mobac.utilities.stream.CountingOutputStream; /** * Creates a new tar file and allows to add files from the file system or * "virtual files" that only exist in memory as byte[]. */ public class TarArchive { protected CountingOutputStream tarFileStream; protected File tarFile; protected File baseDir; /** * * @param tarFile * @param baseDir * root directory used for getting the relative path when adding * a file from the file system. If only in memory files are added * this parameter can be null * @throws FileNotFoundException */ public TarArchive(File tarFile, File baseDir) throws FileNotFoundException { this.tarFile = tarFile; this.tarFileStream = new CountingOutputStream(new BufferedOutputStream( new FileOutputStream(tarFile, false))); this.baseDir = baseDir; } public long getTarFilePos() { return tarFileStream.getBytesWritten(); } public boolean writeContentFromDir(File dirToAdd) throws IOException { if (!dirToAdd.isDirectory()) return false; TarHeader th = new TarHeader(dirToAdd, baseDir); writeTarHeader(th); File[] files = dirToAdd.listFiles(); Arrays.sort(files); for (File f : files) { if (!f.isDirectory()) writeFile(f); else writeContentFromDir(f); } return true; } public void writeFile(File fileOrDirToAdd) throws IOException { TarHeader th = new TarHeader(fileOrDirToAdd, baseDir); writeTarHeader(th); if (!fileOrDirToAdd.isDirectory()) { TarRecord tr = new TarRecord(fileOrDirToAdd); tarFileStream.write(tr.getRecordContent()); } } public void writeDirectory(String dirName) throws IOException { TarHeader th = new TarHeader(dirName, 0, true); writeTarHeader(th); } /** * Writes a "file" into tar archive that does only exists in memory * * @param fileName * @param data * @throws IOException */ public void writeFileFromData(String fileName, byte[] data) throws IOException { writeFileFromData(fileName, data, 0, data.length); } /** * Writes a "file" into tar archive that does only exists in memory * * @param fileName * @param data * @param off * @param len * @throws IOException */ public void writeFileFromData(String fileName, byte[] data, int off, int len) throws IOException { TarHeader th = new TarHeader(fileName, len, false); writeTarHeader(th); TarRecord tr = new TarRecord(data, off, len); tarFileStream.write(tr.getRecordContent()); } protected void writeTarHeader(TarHeader th) throws IOException { tarFileStream.write(th.getBytes()); } public void writeEndofArchive() throws IOException { byte[] endOfArchive = new byte[1024]; tarFileStream.write(endOfArchive); tarFileStream.flush(); } public void close() { try { tarFileStream.close(); } catch (Exception e) { } tarFileStream = null; } public File getTarFile() { return tarFile; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/tar/TarTmiArchive.java0000644000175000017500000000471112122526606030414 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities.tar; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.Writer; import mobac.program.atlascreators.AtlasCreator; import mobac.utilities.Utilities; /** * * Extended version of {@link TarArchive} that automatically creates the * TrekBuddy tmi-file while writing the archive entries. * * @author r_x * * @see * TrekBuddy tmi map tar index file description< /a> */ public class TarTmiArchive extends TarArchive { Writer tmiWriter; public TarTmiArchive(File tarFile, File baseDir) throws IOException { super(tarFile, baseDir); String tmiFilename = tarFile.getAbsolutePath(); if (tmiFilename.toLowerCase().endsWith(".tar")) tmiFilename = tmiFilename.substring(0, tmiFilename.length() - 4); tmiWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(tmiFilename + ".tmi"), AtlasCreator.TEXT_FILE_CHARSET)); } @Override public void writeEndofArchive() throws IOException { super.writeEndofArchive(); tmiWriter.flush(); } @Override public void close() { super.close(); Utilities.closeWriter(tmiWriter); } @Override protected void writeTarHeader(TarHeader th) throws IOException { long streamPos = getTarFilePos(); int block = (int) (streamPos >> 9); String line = String.format("block %10d: %s\n", new Object[] { block, th.getFileName() }); tmiWriter.write(line); super.writeTarHeader(th); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/tar/TarIndexedArchive.java0000644000175000017500000000366212122526606031247 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities.tar; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Hashtable; /** * Extended version of {@link TarArchive} that automatically creates * {@link Hashtable} with the starting offsets of every archived file. */ public class TarIndexedArchive extends TarArchive { private TarIndexTable tarIndex; public TarIndexedArchive(File tarFile, int approxFileCount) throws IOException { super(tarFile, null); tarIndex = new TarIndexTable(approxFileCount); } @Override protected void writeTarHeader(TarHeader th) throws IOException { long streamPos = getTarFilePos(); tarIndex.addTarEntry(th.getFileName(), streamPos); super.writeTarHeader(th); } public void delete() { if (tarFile != null) { boolean b = tarFile.delete(); if (!b && tarFile.isFile()) tarFile.deleteOnExit(); } } public TarIndex getTarIndex() { try { return new TarIndex(tarFile, tarIndex); } catch (FileNotFoundException e) { // should never happen return null; } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/tar/TarHeader.java0000644000175000017500000002057212122526606027554 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities.tar; import java.io.File; import java.io.UnsupportedEncodingException; public class TarHeader { // private static Logger log = Logger.getLogger(TarHeader.class); private File baseFilePath; private int fileNameLength; private final char[] fileName = new char[100]; private final char[] fileMode = new char[8]; private final char[] fileOwnerUserID = new char[8]; private final char[] fileOwnerGroupID = new char[8]; private final char[] fileSize = new char[12]; private final char[] lastModificationTime = new char[12]; private final char[] linkIndicator = new char[1]; private final char[] nameOfLinkedFile = new char[100]; private static final char[] padding = new char[255]; public TarHeader() { } public TarHeader(File theFile, File theBaseFilePath) { this(); baseFilePath = theBaseFilePath; this.setFileName(theFile, baseFilePath); this.setFileMode(); this.setFileOwnerUserID(); this.setFileOwnerGroupID(); this.setFileSize(theFile); this.setLastModificationTime(theFile); this.setLinkIndicator(theFile); } public TarHeader(String fileName, int fileSize, boolean isDirectory) { this(); this.setFileName(fileName); this.setFileMode(); this.setFileOwnerUserID(); this.setFileOwnerGroupID(); this.setFileSize(fileSize); this.setLastModificationTime(System.currentTimeMillis()); this.setLinkIndicator(isDirectory); } public void read(byte[] buffer) { String fn = new String(buffer, 0, 512); fn.getChars(0, 100, fileName, 0); fileNameLength = fn.indexOf((char) 0); fn.getChars(100, 108, fileMode, 0); fn.getChars(108, 116, fileOwnerUserID, 0); fn.getChars(116, 124, fileOwnerGroupID, 0); fn.getChars(124, 136, fileSize, 0); fn.getChars(136, 148, lastModificationTime, 0); // fn.getChars(148, 156, checksum, 0); we ignore the checksum fn.getChars(156, 157, linkIndicator, 0); fn.getChars(157, 257, nameOfLinkedFile, 0); } // S E T - Methods public void setFileName(File theFile, File theBaseFilePath) { String filePath = theFile.getAbsolutePath(); String basePath = theBaseFilePath.getAbsolutePath(); if (!filePath.startsWith(basePath)) throw new RuntimeException("File \"" + filePath + "\" is outside of archive base path \"" + basePath + "\"!"); String tarFileName = filePath.substring(basePath.length(), filePath.length()); tarFileName = tarFileName.replace('\\', '/'); if (tarFileName.startsWith("/")) tarFileName = tarFileName.substring(1, tarFileName.length()); if (theFile.isDirectory()) tarFileName = tarFileName + "/"; setFileName(tarFileName); } public void setFileName(String newFileName) { char[] theFileName = newFileName.toCharArray(); fileNameLength = newFileName.length(); for (int i = 0; i < fileName.length; i++) { if (i < theFileName.length) { fileName[i] = theFileName[i]; } else { fileName[i] = 0; } } } public void setFileMode() { " 777 ".getChars(0, 7, fileMode, 0); } public void setFileOwnerUserID() { " 0 ".getChars(0, 7, fileOwnerUserID, 0); } public void setFileOwnerGroupID() { " 0 ".getChars(0, 7, fileOwnerGroupID, 0); } public void setFileSize(File theFile) { long fileSizeLong = 0; if (!theFile.isDirectory()) { fileSizeLong = theFile.length(); } setFileSize(fileSizeLong); } public void setFileSize(long fileSize) { char[] fileSizeCharArray = Long.toString(fileSize, 8).toCharArray(); int offset = 11 - fileSizeCharArray.length; for (int i = 0; i < 12; i++) { if (i < offset) { this.fileSize[i] = ' '; } else if (i == 11) { this.fileSize[i] = ' '; } else { this.fileSize[i] = fileSizeCharArray[i - offset]; } } } public void setLastModificationTime(File theFile) { setLastModificationTime(theFile.lastModified()); } public void setLastModificationTime(long lastModifiedTime) { lastModifiedTime /= 1000; char[] fileLastModifiedTimeCharArray = Long.toString(lastModifiedTime, 8).toCharArray(); for (int i = 0; i < fileLastModifiedTimeCharArray.length; i++) { lastModificationTime[i] = fileLastModifiedTimeCharArray[i]; } if (fileLastModifiedTimeCharArray.length < 12) { for (int i = fileLastModifiedTimeCharArray.length; i < 12; i++) { lastModificationTime[i] = ' '; } } } public void setLinkIndicator(File theFile) { setLinkIndicator(theFile.isDirectory()); } public void setLinkIndicator(boolean isDirectory) { if (isDirectory) { linkIndicator[0] = '5'; } else { linkIndicator[0] = '0'; } } // G E T - Methods public String getFileName() { return new String(fileName, 0, fileNameLength); } public int getFileNameLength() { return fileNameLength; } public char[] getFileMode() { return fileMode; } public char[] getFileOwnerUserID() { return fileOwnerUserID; } public char[] getFileOwnerGroupID() { return fileOwnerGroupID; } public char[] getFileSize() { return fileSize; } public int getFileSizeInt() { return Integer.parseInt(new String(fileSize).trim(), 8); } public char[] getLastModificationTime() { return lastModificationTime; } public char[] getLinkIndicator() { return linkIndicator; } public char[] getNameOfLinkedFile() { return nameOfLinkedFile; } public char[] getPadding() { return padding; } /** *

* Checksum field content:
* Header checksum, stored as an octal number in ASCII. To compute the * checksum, set the checksum field to all spaces, then sum all bytes in the * header using unsigned arithmetic. This field should be stored as six * octal digits followed by a null and a space character. Note that many * early implementations of tar used signed arithmetic for the checksum * field, which can cause inter- operability problems when transferring * archives between systems. Modern robust readers compute the checksum both * ways and accept the header if either computation matches.
*
definition source *

* * @param header * array containing a tar header at offset 0 (512 bytes of size) * with prepared checksum field (filled with spaces) */ public void correctCheckSum(byte[] header) { // Compute the checksum // theoretical max = 512 bytes * 255 = 130560 = o377000 int checksum = 0; for (int i = 0; i < 512; i++) { // compute the checksum with unsigned arithmetic checksum = checksum + (header[i] & 0xFF); } String s = Integer.toOctalString(checksum); while (s.length() < 6) s = '0' + s; byte[] checksumBin = (s).getBytes(); System.arraycopy(checksumBin, 0, header, 148, 6); header[154] = 0; } public byte[] getBytes() { StringBuffer sb = new StringBuffer(512); sb.append(fileName); sb.append(fileMode); sb.append(fileOwnerUserID); sb.append(fileOwnerGroupID); sb.append(fileSize); sb.append(lastModificationTime); sb.append(" "); // empty/prepared checksum sb.append(linkIndicator); sb.append(nameOfLinkedFile); sb.append(padding); byte[] result; try { result = sb.toString().getBytes("US-ASCII"); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); // should never happen } if (result.length != 512) throw new RuntimeException("Invalid tar header size: " + result.length); correctCheckSum(result); return result; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/tar/TarRecord.java0000644000175000017500000000507012122526606027576 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities.tar; import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import mobac.utilities.Utilities; /** * A tar record contains the data of the file to be stored. The data size has to * be dividable by 512 (internal tar block length). * */ public class TarRecord { private byte[] fileData; public TarRecord(File theFile) throws IOException { fileData = new byte[calculateFileSizeInTar(theFile)]; this.setRecordContent(theFile); } public TarRecord(byte[] data) throws IOException { this(data, 0, data.length); } public TarRecord(byte[] data, int off, int len) throws IOException { fileData = new byte[calculateFileSizeInTar(len)]; System.arraycopy(data, off, fileData, 0, len); } public static int calculateFileSizeInTar(File theFile) { long fl = theFile.length(); if (fl > Integer.MAX_VALUE) throw new RuntimeException("File size too large"); return calculateFileSizeInTar((int) fl); } public static int calculateFileSizeInTar(int fileLength) { if (fileLength < 512) { return 512; } else { int mod = fileLength % 512; // align buffer size on 512 byte block length if (mod != 0) fileLength += 512 - mod; return fileLength; } } public void setRecordContent(File theFile) throws IOException { FileInputStream inputFile = null; DataInputStream dIn; try { inputFile = new FileInputStream(theFile); dIn = new DataInputStream(inputFile); dIn.readFully(fileData, 0, (int) theFile.length()); dIn.close(); } finally { Utilities.closeStream(inputFile); } } public byte[] getRecordContent() { return fileData; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/tar/TarIndexTable.java0000644000175000017500000000322512122526606030377 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities.tar; import java.util.Hashtable; public class TarIndexTable { /** * Maps tile name to TAR block index (each block has 512 bytes). */ private Hashtable hashTable; public TarIndexTable(int initialCapacity) { hashTable = new Hashtable(initialCapacity); } public void addTarEntry(String filename, long streamPos) { assert ((streamPos & 0x1F) == 0); int tarBlockIndex = (int) (streamPos >> 9); hashTable.put(filename, new Integer(tarBlockIndex)); } public long getEntryOffset(String filename) { Integer tarBlockIndex = hashTable.get(filename); if (tarBlockIndex == null) return -1; long offset = ((long) (tarBlockIndex)) << 9; return offset; } public int size() { return hashTable.size(); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/stream/0000755000175000017500000000000012122526606025551 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/stream/CountingOutputStream.java0000644000175000017500000000306612122526606032604 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities.stream; import java.io.FilterOutputStream; import java.io.IOException; import java.io.OutputStream; public class CountingOutputStream extends FilterOutputStream { private long bytesWritten = 0; public CountingOutputStream(OutputStream out) { super(out); } @Override public void write(int b) throws IOException { out.write(b); bytesWritten++; } @Override public void write(byte[] b, int off, int len) throws IOException { out.write(b, off, len); bytesWritten += len; } @Override public void write(byte[] b) throws IOException { out.write(b); bytesWritten += b.length; } public long getBytesWritten() { return bytesWritten; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/stream/ArrayOutputStream.java0000644000175000017500000000445312122526606032075 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities.stream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; /** * A simple fixed-size version of {@link ByteArrayOutputStream}. */ public class ArrayOutputStream extends OutputStream { protected byte[] buf; protected int pos = 0; /** * @param size * Size of the buffer available for writing. */ public ArrayOutputStream(int size) { buf = new byte[size]; } /** * @param array * Byte array used for writing to */ public ArrayOutputStream(byte[] array) { buf = array; } /** * * @param array * Byte array used for writing to * @param off * offset in array */ public ArrayOutputStream(byte[] array, int off) { buf = array; pos = off; } public byte[] toByteArray() { byte[] data = new byte[pos]; System.arraycopy(buf, 0, data, 0, pos); return data; } public void reset() { pos = 0; } @Override public void write(byte[] b, int off, int len) throws IOException { int newPos = pos + len; if (newPos > buf.length) throw new IOException("End of buffer reached"); System.arraycopy(b, off, buf, pos, len); pos = newPos; } @Override public void write(byte[] b) throws IOException { write(b, 0, b.length); } @Override public void write(int b) throws IOException { write(new byte[] { (byte) b }, 0, 1); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/stream/ThrottledInputStream.java0000644000175000017500000000332512122526606032564 0ustar paulliupaulliu/* * XNap - A P2P framework and client. * * See the file AUTHORS for copyright information. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package mobac.utilities.stream; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; /** * The global throtteled InputStream. All downloads should pipe their data through this stream. */ public class ThrottledInputStream extends FilterInputStream { // --- Data Field(s) --- private static ThrottleSupport ts = new ThrottleSupport(); private int unused = 0; // --- Constructor(s) --- /** * @param in * {@link InputStream} with implemented/working {@link InputStream#available()} method. */ public ThrottledInputStream(InputStream in) { super(in); } // --- Method(s) --- public static void setBandwidth(long newValue) { ts.setBandwidth(newValue); } public int read(byte[] b, int off, int len) throws IOException { int allowedlen = ts.allocate(len); if (allowedlen < len) { allowedlen = Math.min(allowedlen + unused, len); } int read = in.read(b, off, allowedlen); unused = len - read; return read; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/stream/ZipStoreOutputStream.java0000644000175000017500000000362712122526606032600 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities.stream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.zip.CRC32; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class ZipStoreOutputStream extends ZipOutputStream { private CRC32 crc = new CRC32(); public ZipStoreOutputStream(OutputStream out) { super(out); } public ZipStoreOutputStream(File f) throws FileNotFoundException { super(new FileOutputStream(f)); } /** * * Warning this method is not thread safe! * * @param name file name including path in the zip * @param data * @throws IOException */ public void writeStoredEntry(String name, byte[] data) throws IOException { ZipEntry ze = new ZipEntry(name); ze.setMethod(ZipEntry.STORED); ze.setCompressedSize(data.length); ze.setSize(data.length); crc.reset(); crc.update(data); ze.setCrc(crc.getValue()); putNextEntry(ze); write(data); closeEntry(); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/stream/ThrottleSupport.java0000644000175000017500000000607512122526606031626 0ustar paulliupaulliu/* * XNap - A P2P framework and client. * * See the file AUTHORS for copyright information. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package mobac.utilities.stream; import org.apache.log4j.Logger; /** * Provides a throttle implementation based on time ticks. Clients can allocate a limited amount of bytes for each tick. * If all bandwidth has been allocated clients are stalled until the next tick. */ public class ThrottleSupport { // --- Constant(s) --- /** * The default length of a tick. */ public static final long TICK_LENGTH = 512; // = 2^9 // --- Data field(s) --- private static Logger logger = Logger.getLogger(ThrottleSupport.class); /** * bytes per tick */ protected long bandwidth = 0; protected long allocated = 0; protected long tick = 0; protected Object lock = new Object(); // --- Constructor(s) --- public ThrottleSupport() { } /** * Sets the maximum bandwidth. * * @param bandwidth * byte / s */ public void setBandwidth(long bandwidth) { synchronized (lock) { this.bandwidth = (bandwidth * TICK_LENGTH) / 1024; } } /** * Returns the number of bytes that the calling thread is allowed to send. Blocks until at least one byte could be * allocated. * * @return -1, if interrupted; */ public int allocate(int bytes) { if (bytes == 0) return 0; synchronized (lock) { while (true) { if (bandwidth == 0) { // no limit return bytes; } long currentTick = System.currentTimeMillis() >> 9; if (currentTick > tick) { logger.debug("* new tick: " + bandwidth + " to allocate *"); tick = currentTick; allocated = 0; lock.notifyAll(); } if (bytes < bandwidth - allocated) { // we still have some bandwidth left allocated += bytes; logger.debug("returning " + bytes + " allocated now " + allocated); return bytes; } if (bandwidth - allocated > 0) { // don't have enough, but return all we have left bytes = (int) (bandwidth - allocated); allocated = bandwidth; logger.debug("returning " + bytes + " allocated now " + allocated); return bytes; } // we could not allocate any bandwidth, wait until the next // tick is started // this is a bit too long long t = TICK_LENGTH - (System.currentTimeMillis() % TICK_LENGTH); if (t > 0) { try { logger.debug("waiting for " + t); lock.wait(t); } catch (InterruptedException e) { return -1; } } } } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/stream/LittleEndianOutputStream.java0000644000175000017500000000462012122526606033367 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities.stream; import java.io.FilterOutputStream; import java.io.IOException; import java.io.OutputStream; public class LittleEndianOutputStream extends FilterOutputStream { public LittleEndianOutputStream(OutputStream out) { super(out); } /** * Write an int, 32-bits. Like DataOutputStream.writeInt. * * @param v * the int to write * * @throws IOException * if write fails. */ public final void writeInt(int v) throws IOException { byte[] work = new byte[4]; work[0] = (byte) (v & 0xFF); work[1] = (byte) ((v >> 8) & 0xFF); work[2] = (byte) ((v >> 16) & 0xFF); work[3] = (byte) ((v >> 24) & 0xFF); out.write(work, 0, 4); } /** * Write a double. * * @param v * the double to write. Like DataOutputStream.writeDouble. * * @throws IOException * if write fails. */ public final void writeDouble(double v) throws IOException { writeLong(Double.doubleToLongBits(v)); } /** * Write a long, 64-bits. like DataOutputStream.writeLong. * * @param v * the long to write * * @throws IOException * if write fails. */ public final void writeLong(long v) throws IOException { byte[] work = new byte[8]; work[0] = (byte) v; work[1] = (byte) (v >> 8); work[2] = (byte) (v >> 16); work[3] = (byte) (v >> 24); work[4] = (byte) (v >> 32); work[5] = (byte) (v >> 40); work[6] = (byte) (v >> 48); work[7] = (byte) (v >> 56); out.write(work); } } ././@LongLink0000000000000000000000000000015100000000000011562 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/stream/RandomAccessFileOutputStream.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/stream/RandomAccessFileOutputStream.0000644000175000017500000000360312122526606033313 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities.stream; import java.io.IOException; import java.io.OutputStream; import java.io.RandomAccessFile; /** * Allows to write to an {@link RandomAccessFile} through an * {@link OutputStream}. * *

* Notes: *

    *
  • Closing this stream does not have any effect on the underlying * {@link RandomAccessFile}.
  • *
  • Seeking or changing the {@link RandomAccessFile} file position directly * affects {@link RandomAccessFileOutputStream}.
  • *
* */ public class RandomAccessFileOutputStream extends OutputStream { private final RandomAccessFile file; public RandomAccessFileOutputStream(RandomAccessFile f) { this.file = f; } @Override public void write(int b) throws IOException { file.write(b); } @Override public void write(byte[] b, int off, int len) throws IOException { file.write(b, off, len); } @Override public void write(byte[] b) throws IOException { file.write(b); } public RandomAccessFile getFile() { return file; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/Charsets.java0000644000175000017500000000211412122526606026673 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities; import java.nio.charset.Charset; public class Charsets { public static final Charset UTF_8 = Charset.forName("UTF-8"); public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1"); } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/ExtensionClassLoader.java0000644000175000017500000000736112122526606031221 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities; import java.io.File; import java.io.FileNotFoundException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.security.AccessController; import java.security.PrivilegedAction; import mobac.utilities.file.RegexFileFilter; import org.apache.log4j.Logger; /** * Allows to load JAR files at runtime including their JNI libraries. */ public class ExtensionClassLoader extends URLClassLoader { private static final Logger log = Logger.getLogger(ExtensionClassLoader.class); private File jarDir; private ExtensionClassLoader(URL[] urls, File jarDir) throws MalformedURLException { super(urls); this.jarDir = jarDir; } /** * Creates an {@link ExtensionClassLoader} for loading JARs at runtime that * have JNI dependencies. * * @param dirList * list of directories to search in. The first directory * containing at least one jar matching the * regexFilePattern is taken. The other directories * are ignored. * @param regexFilePattern * jar/jni regex search pattern * @return The {@link ClassLoader} that is able to load classes from the * loaded JARs and the correspondant JNI libraries * @throws MalformedURLException * @throws FileNotFoundException */ public static ExtensionClassLoader create(File[] dirList, String regexFilePattern) throws FileNotFoundException { File[] jarFiles = null; File jarDir = null; for (File dir : dirList) { if (dir == null || !dir.isDirectory()) continue; File[] files = dir.listFiles(new RegexFileFilter(regexFilePattern)); if (files.length > 0) { log.debug("Directory: \"" + dir.getAbsolutePath() + "\""); log.debug("Pattern: \"" + regexFilePattern + "\""); jarFiles = files; jarDir = dir; break; } } if (jarFiles == null) throw new FileNotFoundException("No directory containing \"" + regexFilePattern + "\" found."); final URL[] urls = new URL[jarFiles.length]; for (int i = 0; i < urls.length; i++) { try { urls[i] = new URL("jar", "", "file:" + jarFiles[i].getAbsolutePath() + "!/"); } catch (MalformedURLException e) { log.error("", e); } } final File jarDir_ = jarDir; ExtensionClassLoader ecl = AccessController .doPrivileged(new PrivilegedAction() { public ExtensionClassLoader run() { try { return new ExtensionClassLoader(urls, jarDir_); } catch (MalformedURLException e) { throw new RuntimeException(e); } } }); return ecl; } @Override protected String findLibrary(String libname) { String mappedLibname = System.mapLibraryName(libname); File f = new File(jarDir, mappedLibname); if (f.isFile()) return f.getAbsolutePath(); else return null; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/GBC.java0000644000175000017500000001104612122526606025516 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ // License: GPL. Copyright 2007 by Immanuel Scholz and others package mobac.utilities; import java.awt.Component; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.Insets; import javax.swing.Box; /** * A wrapper for GridBagConstraints which has sane default static creators and * member functions to chain calling. * * @author imi */ public class GBC extends GridBagConstraints { private static final long serialVersionUID = 1L; /** * Use public static creator functions to create an GBC. */ private GBC() { } /** * Create a standard constraint (which is not the last). * * @return A standard constraint with no filling. */ public static GBC std() { GBC c = new GBC(); c.anchor = WEST; return c; } /** * Create the constraint for the last elements on a line. * * @return A constraint which indicates the last item on a line. */ public static GBC eol() { GBC c = std(); c.gridwidth = REMAINDER; return c; } /** * Create the constraint for the last elements on a line and on a paragraph. * This is merely a shortcut for eol().insets(0,0,0,10) * * @return A constraint which indicates the last item on a line. */ public static GBC eop() { return eol().insets(0, 0, 0, 10); } /** * Try to fill both, horizontal and vertical * * @return This constraint for chaining. */ public GBC fill() { return fill(BOTH); } public GBC toggleEol() { if (gridwidth == GBC.REMAINDER) gridwidth = 1; else gridwidth = GBC.REMAINDER; return this; } public GBC gridwidth(int value) { gridwidth = value; return this; } public GBC gridheight(int value) { gridheight = value; return this; } public GBC gridx(int value) { gridx = value; return this; } public GBC gridxy(int x, int y) { gridx = x; gridy = y; return this; } public GBC gridy(int value) { gridy = value; return this; } /** * Set fill to the given value * * @param value * The filling value, either NONE, HORIZONTAL, VERTICAL or BOTH * @return This constraint for chaining. */ public GBC fill(int value) { fill = value; if (value == HORIZONTAL || value == BOTH) weightx = 1.0; if (value == VERTICAL || value == BOTH) weighty = 1.0; return this; } public GBC fillH() { return fill(GBC.HORIZONTAL); } /** * Set the anchor of this GBC to a. * * @param a * The new anchor, e.g. GBC.CENTER or GBC.EAST. * @return This constraint for chaining. */ public GBC anchor(int a) { anchor = a; return this; } /** * Adds insets to this GBC. * * @param left * The left space of the insets * @param top * The top space of the insets * @param right * The right space of the insets * @param bottom * The bottom space of the insets * @return This constraint for chaining. */ public GBC insets(int left, int top, int right, int bottom) { insets = new Insets(top, left, bottom, right); return this; } /** * This is a helper to easily create a glue with a minimum default value. * * @param x * If higher than 0, this will be a horizontal glue with x as * minimum horizontal strut. * @param y * If higher than 0, this will be a vertical glue with y as * minimum vertical strut. */ public static Component glue(int x, int y) { short maxx = x > 0 ? Short.MAX_VALUE : 0; short maxy = y > 0 ? Short.MAX_VALUE : 0; return new Box.Filler(new Dimension(x, y), new Dimension(x, y), new Dimension(maxx, maxy)); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/MyMath.java0000644000175000017500000001145212122526606026323 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities; public class MyMath { /** * * Rounds down to the nearest multiple of toNearest * * @param value * positive value * @param toNearest * positive value * @return */ public static int roundDownToNearest(int value, int toNearest) { int remainder = value % toNearest; value -= remainder; return value; } /** * * Rounds up to the nearest multiple of toNearest * * @param value * positive value * @param toNearest * positive value * @return */ public static int roundUpToNearest(int value, int toNearest) { int remainder = value % toNearest; if (remainder == 0) return value; value += (toNearest - remainder); return value; } /** * * @param value * @return */ public static int ceil(double value) { return (int) Math.ceil(value); } /** * Divides value by divisor and performs the function "ceil" on the fractional result. * Warning: This method works only with positive input values! *

* Internally only integer arithmetics is used (no floating point arithmetics) *

* * @param value * positive value * @param divisor * positive value * @return */ public static int divCeil(int value, int divisor) { int result = value / divisor; int remainder = value % divisor; if (remainder != 0) result++; return result; } /** * Divides value by divisor and performs the function "ceil" on the fractional * result.Warning: This method works only with positive input values! *

* Internally only integer arithmetics is used (no floating point arithmetics) *

* * @param value * positive value * @param divisor * positive value * @return */ public static long divCeil(long value, long divisor) { long result = value / divisor; if (value % divisor != 0) result++; return result; } /** * Divides value by divisor and performs the function "round" on the fractional result. * Warning: This method works only with positive input values! *

* Internally only integer arithmetics is used (no floating point arithmetics) *

* * @param value * positive value * @param divisor * positive value * @return */ public static int divRound(int value, int divisor) { int result = value / divisor; int remainder = value % divisor; if (remainder > (divisor >> 1)) result++; return result; } /** * Divides value by divisor and performs the function "round" on the fractional result. * Warning: This method works only with positive input values! *

* Internally only integer arithmetics is used (no floating point arithmetics) *

* * @param value * positive value * @param divisor * positive value * @return */ public static long divRound(long value, long divisor) { long result = value / divisor; long remainder = value % divisor; if (remainder > (divisor >> 1)) result++; return result; } /** * Examples: * *
	 *     0.1 to     1.0
	 *     0.5 to     1.0
	 *     0.9 to     1.0
	 *     1.1 to     1.0
	 *     1.9 to     2.0
	 *     9.9 to    10.0
	 *    15.5 to    20.0
	 *    88.0 to    90.0
	 *   363.0 to   400.0 
	 *  1155.0 to  1000.0
	 *  1655.0 to  2000.0
	 * 13455.0 to 10000.0
	 * 17755.0 to 20000.0
	 * 
* * @param val * @return array containing the rounded value */ public static double prettyRound(double val) { if (val < 1.0) return Math.ceil(val); int l10 = (int) Math.pow(10, Math.floor(Math.log10(val))); double x = val / l10; x = Math.round(x); x = x * l10; return x; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/Utilities.java0000644000175000017500000005357612127544350027115 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities; import java.awt.Color; import java.awt.Graphics2D; import java.awt.event.ActionEvent; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.Closeable; import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.RandomAccessFile; import java.io.Writer; import java.net.HttpURLConnection; import java.net.URISyntaxException; import java.net.URL; import java.nio.channels.FileChannel; import java.security.CodeSource; import java.security.ProtectionDomain; import java.sql.SQLException; import java.sql.Statement; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.text.ParseException; import java.text.ParsePosition; import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Properties; import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.imageio.ImageIO; import javax.swing.Action; import javax.swing.ImageIcon; import javax.swing.JComponent; import mobac.Main; import mobac.exceptions.MOBACOutOfMemoryException; import mobac.program.Logging; import mobac.program.interfaces.MapSource; import mobac.program.model.TileImageType; import mobac.utilities.file.DirectoryFileFilter; import org.apache.log4j.Logger; public class Utilities { public static final Color COLOR_TRANSPARENT = new Color(0, 0, 0, 0); public static final DecimalFormatSymbols DFS_ENG = new DecimalFormatSymbols(Locale.ENGLISH); public static final DecimalFormatSymbols DFS_LOCAL = new DecimalFormatSymbols(); public static final DecimalFormat FORMAT_6_DEC = new DecimalFormat("#0.######"); public static final DecimalFormat FORMAT_6_DEC_ENG = new DecimalFormat("#0.######", DFS_ENG); public static final DecimalFormat FORMAT_2_DEC = new DecimalFormat("0.00"); private static final DecimalFormat cDmsMinuteFormatter = new DecimalFormat("00"); private static final DecimalFormat cDmsSecondFormatter = new DecimalFormat("00.0"); private static final Logger log = Logger.getLogger(Utilities.class); public static final long SECONDS_PER_HOUR = TimeUnit.HOURS.toSeconds(1); public static final long SECONDS_PER_DAY = TimeUnit.DAYS.toSeconds(1); public static boolean testJaiColorQuantizerAvailable() { try { Class c = Class.forName("javax.media.jai.operator.ColorQuantizerDescriptor"); if (c != null) return true; } catch (NoClassDefFoundError e) { return false; } catch (Throwable t) { log.error("Error in testJaiColorQuantizerAvailable():", t); return false; } return true; } public static BufferedImage createEmptyTileImage(MapSource mapSource) { int tileSize = mapSource.getMapSpace().getTileSize(); Color color = mapSource.getBackgroundColor(); int imageType; if (color.getAlpha() == 255) imageType = BufferedImage.TYPE_INT_RGB; else imageType = BufferedImage.TYPE_INT_ARGB; BufferedImage emptyImage = new BufferedImage(tileSize, tileSize, imageType); Graphics2D g = emptyImage.createGraphics(); try { g.setColor(color); g.fillRect(0, 0, tileSize, tileSize); } finally { g.dispose(); } return emptyImage; } public static BufferedImage safeCreateBufferedImage(int width, int height, int imageType) { try { return new BufferedImage(width, height, imageType); } catch (OutOfMemoryError e) { int bytesPerPixel = getBytesPerPixel(imageType); if (bytesPerPixel < 0) throw e; long requiredMemory = ((long) width) * ((long) height) * bytesPerPixel; String message = String.format( "Available free memory not sufficient for creating image of size %dx%d pixels", width, height); throw new MOBACOutOfMemoryException(requiredMemory, message); } } /** * * @param imageType * as used for {@link BufferedImage#BufferedImage(int, int, int)} * @return */ public static int getBytesPerPixel(int bufferedImageType) { switch (bufferedImageType) { case BufferedImage.TYPE_INT_ARGB: case BufferedImage.TYPE_INT_ARGB_PRE: case BufferedImage.TYPE_INT_BGR: case BufferedImage.TYPE_4BYTE_ABGR: case BufferedImage.TYPE_4BYTE_ABGR_PRE: return 4; case BufferedImage.TYPE_3BYTE_BGR: return 3; case BufferedImage.TYPE_USHORT_GRAY: case BufferedImage.TYPE_USHORT_565_RGB: case BufferedImage.TYPE_USHORT_555_RGB: return 2; case BufferedImage.TYPE_BYTE_GRAY: case BufferedImage.TYPE_BYTE_BINARY: case BufferedImage.TYPE_BYTE_INDEXED: return 1; } return -1; } public static byte[] createEmptyTileData(MapSource mapSource) { BufferedImage emptyImage = createEmptyTileImage(mapSource); ByteArrayOutputStream buf = new ByteArrayOutputStream(4096); try { ImageIO.write(emptyImage, mapSource.getTileImageType().getFileExt(), buf); } catch (IOException e) { throw new RuntimeException(e); } byte[] emptyTileData = buf.toByteArray(); return emptyTileData; } private static final byte[] PNG = new byte[] { (byte) 0x89, 'P', 'N', 'G', 0x0D, 0x0A, 0x1A, 0x0A }; private static final byte[] JPG = new byte[] { (byte) 0xFF, (byte) 0xD8, (byte) 0xFF, (byte) 0xE0, (byte) 0x00, 0x10, 'J', 'F', 'I', 'F' }; private static final byte[] GIF_1 = "GIF87a".getBytes(); private static final byte[] GIF_2 = "GIF89a".getBytes(); public static TileImageType getImageType(byte[] imageData) { if (imageData == null) return null; if (startsWith(imageData, PNG)) return TileImageType.PNG; if (startsWith(imageData, JPG)) return TileImageType.JPG; if (startsWith(imageData, GIF_1) || startsWith(imageData, GIF_2)) return TileImageType.GIF; return null; } public static boolean startsWith(byte[] data, byte[] startTest) { if (data.length < startTest.length) return false; for (int i = 0; i < startTest.length; i++) if (data[i] != startTest[i]) return false; return true; } /** * Checks if the available JAXB version is at least v2.1 */ public static boolean checkJAXBVersion() { try { // We are trying to load the class javax.xml.bind.JAXB which has // been introduced with JAXB 2.1. Previous version do not contain // this class and will therefore throw an exception. Class c = Class.forName("javax.xml.bind.JAXB"); return (c != null); } catch (ClassNotFoundException e) { return false; } } public static InputStream loadResourceAsStream(String resourcePath) throws IOException { return Main.class.getResourceAsStream("resources/" + resourcePath); } public static String loadTextResource(String resourcePath) throws IOException { DataInputStream in = new DataInputStream(Main.class.getResourceAsStream("resources/" + resourcePath)); byte[] buf; buf = new byte[in.available()]; in.readFully(buf); in.close(); String text = new String(buf, Charsets.UTF_8); return text; } /** * * @param imageName * imagePath resource path relative to the class {@link Main} * @return */ public static ImageIcon loadResourceImageIcon(String imageName) { URL url = Main.class.getResource("resources/images/" + imageName); return new ImageIcon(url); } public static URL getResourceImageUrl(String imageName) { return Main.class.getResource("resources/images/" + imageName); } public static void loadProperties(Properties p, URL url) throws IOException { InputStream propIn = url.openStream(); try { p.load(propIn); } finally { closeStream(propIn); } } public static void loadProperties(Properties p, File f) throws IOException { InputStream propIn = new FileInputStream(f); try { p.load(propIn); } finally { closeStream(propIn); } } public static void sleep(long millis) { try { Thread.sleep(millis); } catch (InterruptedException e) { throw new RuntimeException(e); } } /** * Checks if the current {@link Thread} has been interrupted and if so a {@link InterruptedException}. Therefore it * behaves similar to {@link Thread#sleep(long)} without actually slowing down anything by sleeping a certain amount * of time. * * @throws InterruptedException */ public static void checkForInterruption() throws InterruptedException { if (Thread.currentThread().isInterrupted()) throw new InterruptedException(); } /** * Checks if the current {@link Thread} has been interrupted and if so a {@link RuntimeException} will be thrown. * This method is useful for long lasting operations that do not allow to throw an {@link InterruptedException}. * * @throws RuntimeException */ public static void checkForInterruptionRt() throws RuntimeException { if (Thread.currentThread().isInterrupted()) throw new RuntimeException(new InterruptedException()); } public static void closeFile(RandomAccessFile file) { if (file == null) return; try { file.close(); } catch (IOException e) { } } public static void closeStream(InputStream in) { if (in == null) return; try { in.close(); } catch (IOException e) { } } public static void close(Closeable c) { if (c == null) return; try { c.close(); } catch (IOException e) { } } public static void closeStream(OutputStream out) { if (out == null) return; try { out.close(); } catch (IOException e) { } } public static void closeWriter(Writer writer) { if (writer == null) return; try { writer.close(); } catch (IOException e) { } } public static void closeReader(OutputStream reader) { if (reader == null) return; try { reader.close(); } catch (IOException e) { } } public static void closeStatement(Statement statement) { if (statement == null) return; try { statement.close(); } catch (SQLException e) { } } public static double parseLocaleDouble(String text) throws ParseException { ParsePosition pos = new ParsePosition(0); Number n = Utilities.FORMAT_6_DEC.parse(text, pos); if (n == null) throw new ParseException("Unknown error", 0); if (pos.getIndex() != text.length()) throw new ParseException("Text ends with unparsable characters", pos.getIndex()); return n.doubleValue(); } public static void showTooltipNow(JComponent c) { Action toolTipAction = c.getActionMap().get("postTip"); if (toolTipAction != null) { ActionEvent postTip = new ActionEvent(c, ActionEvent.ACTION_PERFORMED, ""); toolTipAction.actionPerformed(postTip); } } /** * Formats a byte value depending on the size to "Bytes", "KiBytes", "MiByte" and "GiByte" * * @param bytes * @return Formatted {@link String} */ public static String formatBytes(long bytes) { if (bytes < 1000) return Long.toString(bytes) + " " + I18nUtils.localizedStringForKey("Bytes"); if (bytes < 1000000) return FORMAT_2_DEC.format(bytes / 1024d) + " " + I18nUtils.localizedStringForKey("KiByte"); if (bytes < 1000000000) return FORMAT_2_DEC.format(bytes / 1048576d) + " " + I18nUtils.localizedStringForKey("MiByte"); return FORMAT_2_DEC.format(bytes / 1073741824d) + " " + I18nUtils.localizedStringForKey("GiByte"); } public static String formatDurationSeconds(long seconds) { long x = seconds; long days = x / SECONDS_PER_DAY; x %= SECONDS_PER_DAY; int years = (int) (days / 365); days -= (years * 365); int months = (int) (days * 12d / 365d); String m = (months == 1) ? "month" : "months"; if (years > 5) return String.format("%d years", years); if (years > 0) { String y = (years == 1) ? "year" : "years"; return String.format("%d %s %d %s", years, y, months, m); } String d = (days == 1) ? "day" : "days"; if (months > 0) { days -= months * (365d / 12d); return String.format("%d %s %d %s", months, m, days, d); } long hours = TimeUnit.SECONDS.toHours(x); String h = (hours == 1) ? "hour" : "hours"; x -= hours * SECONDS_PER_HOUR; if (days > 0) return String.format("%d %s %d %s", days, d, hours, h); long minutes = TimeUnit.SECONDS.toMinutes(x); String min = (minutes == 1) ? "minute" : "minutes"; if (hours > 0) return String.format("%d %s %d %s", hours, h, minutes, min); else return String.format("%d %s", minutes, min); } public static void mkDir(File dir) throws IOException { if (dir.isDirectory()) return; if (!dir.mkdir()) throw new IOException("Failed to create directory \"" + dir.getAbsolutePath() + "\""); } public static void mkDirs(File dir) throws IOException { if (dir.isDirectory()) return; if (dir.mkdirs()) return; if (Logging.isCONFIGURED()) Logging.LOG.error("mkDirs creation failed first time - one retry left"); // Wait some time and then retry it. // See for details: // http://javabyexample.wisdomplug.com/component/content/article/37-core-java/48-is-mkdirs-thread-safe.html // Hopefully this will fix the different bugs reported for this method try { Thread.sleep(100); } catch (InterruptedException e) { } if (dir.mkdirs()) return; throw new IOException("Failed to create directory \"" + dir.getAbsolutePath() + "\""); } public static void fileCopy(File sourceFile, File destFile) throws IOException { FileChannel source = null; FileChannel destination = null; FileInputStream fis = null; FileOutputStream fos = null; try { fis = new FileInputStream(sourceFile); fos = new FileOutputStream(destFile); source = fis.getChannel(); destination = fos.getChannel(); destination.transferFrom(source, 0, source.size()); } finally { fis.close(); fos.close(); if (source != null) { source.close(); } if (destination != null) { destination.close(); } } } public static byte[] getFileBytes(File file) throws IOException { int size = (int) file.length(); byte[] buffer = new byte[size]; DataInputStream in = new DataInputStream(new FileInputStream(file)); try { in.readFully(buffer); return buffer; } finally { closeStream(in); } } /** * Fully reads data from in to an internal buffer until the end of in has been reached. Then the buffer is * returned. * * @param in * data source to be read * @return buffer all data available in in * @throws IOException */ public static byte[] getInputBytes(InputStream in) throws IOException { int initialBufferSize = in.available(); if (initialBufferSize <= 0) initialBufferSize = 32768; ByteArrayOutputStream buffer = new ByteArrayOutputStream(initialBufferSize); byte[] b = new byte[1024]; int ret = 0; while ((ret = in.read(b)) >= 0) { buffer.write(b, 0, ret); } return buffer.toByteArray(); } /** * Fully reads data from in the read data is discarded. * * @param in * @throws IOException */ public static void readFully(InputStream in) throws IOException { byte[] b = new byte[4096]; while ((in.read(b)) >= 0) { } } /** * Lists all direct sub directories of dir * * @param dir * @return list of directories */ public static File[] listSubDirectories(File dir) { return dir.listFiles(new DirectoryFileFilter()); } public static List listSubDirectoriesRec(File dir, int maxDepth) { List dirList = new LinkedList(); addSubDirectories(dirList, dir, maxDepth); return dirList; } public static void addSubDirectories(List dirList, File dir, int maxDepth) { File[] subDirs = dir.listFiles(new DirectoryFileFilter()); for (File f : subDirs) { dirList.add(f); if (maxDepth > 0) addSubDirectories(dirList, f, maxDepth - 1); } } public static String prettyPrintLatLon(double coord, boolean isCoordKindLat) { boolean neg = coord < 0.0; String c; if (isCoordKindLat) { c = (neg ? "S" : "N"); } else { c = (neg ? "W" : "E"); } double tAbsCoord = Math.abs(coord); int tDegree = (int) tAbsCoord; double tTmpMinutes = (tAbsCoord - tDegree) * 60; int tMinutes = (int) tTmpMinutes; double tSeconds = (tTmpMinutes - tMinutes) * 60; return c + tDegree + "\u00B0" + cDmsMinuteFormatter.format(tMinutes) + "\'" + cDmsSecondFormatter.format(tSeconds) + "\""; } public static void setHttpProxyHost(String host) { if (host != null && host.length() > 0) System.setProperty("http.proxyHost", host); else System.getProperties().remove("http.proxyHost"); } public static void setHttpProxyPort(String port) { if (port != null && port.length() > 0) System.setProperty("http.proxyPort", port); else System.getProperties().remove("http.proxyPort"); } /** * Returns the file path for the selected class. If the class is located inside a JAR file the return value contains * the directory that contains the JAR file. If the class file is executed outside of an JAR the root directory * holding the class/package structure is returned. * * @param mainClass * @return * @throws URISyntaxException */ public static File getClassLocation(Class mainClass) { ProtectionDomain pDomain = mainClass.getProtectionDomain(); CodeSource cSource = pDomain.getCodeSource(); File f; try { URL loc = cSource.getLocation(); // file:/c:/almanac14/examples/ f = new File(loc.toURI()); } catch (Exception e) { throw new RuntimeException("Unable to determine program directory: ", e); } if (f.isDirectory()) { // Class is executed from class/package structure from file system return f; } else { // Class is executed from inside of a JAR -> f references the JAR // file return f.getParentFile(); } } /** * Saves data to the file specified by filename. * * @param filename * @param data * @throws IOException */ public static void saveBytes(String filename, byte[] data) throws IOException { FileOutputStream fo = null; try { fo = new FileOutputStream(filename); fo.write(data); } finally { closeStream(fo); } } /** * Saves data to the file specified by filename. * * @param filename * @param data * @return Data has been saved successfully? */ public static boolean saveBytesEx(String filename, byte[] data) { FileOutputStream fo = null; try { fo = new FileOutputStream(filename); fo.write(data); return true; } catch (IOException e) { return false; } finally { closeStream(fo); } } /** * Tries to delete a file or directory and throws an {@link IOException} if that fails. * * @param fileToDelete * @throws IOException * Thrown if fileToDelete can not be deleted. */ public static void deleteFile(File fileToDelete) throws IOException { if (!fileToDelete.delete()) throw new IOException("Deleting of \"" + fileToDelete + "\" failed."); } public static void renameFile(File oldFile, File newFile) throws IOException { if (!oldFile.renameTo(newFile)) throw new IOException("Failed to rename file: " + oldFile + " to " + newFile); } public static int getJavaMaxHeapMB() { try { return (int) (Runtime.getRuntime().maxMemory() / 1048576l); } catch (Exception e) { return -1; } } public static byte[] downloadHttpFile(String url) throws IOException { HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection(); int responseCode = conn.getResponseCode(); if (responseCode != HttpURLConnection.HTTP_OK) throw new IOException("Invalid HTTP response: " + responseCode + " for url " + conn.getURL()); InputStream in = conn.getInputStream(); try { return Utilities.getInputBytes(in); } finally { in.close(); } } public static void copyFile(File source, File target) throws IOException { FileChannel in = null; FileChannel out = null; try { in = (new FileInputStream(source)).getChannel(); out = (new FileOutputStream(target)).getChannel(); in.transferTo(0, source.length(), out); } finally { close(in); close(out); } } /** * * @param value * positive value * @return 0 if no bit is set else the highest bit that is one in value */ public static int getHighestBitSet(int value) { int bit = 0x40000000; for (int i = 31; i > 0; i--) { int test = bit & value; if (test != 0) return i; bit >>= 1; } return 0; } /** * * @param revsision * SVN revision string like "1223", "1224M" or "1616:1622M" * @return parsed svn revision */ public static int parseSVNRevision(String revision) { revision = revision.trim(); int index = revision.lastIndexOf(':'); if (index >= 0) { revision = revision.substring(index + 1).trim(); } Matcher m = Pattern.compile("(\\d+)[^\\d]*").matcher(revision); if (!m.matches()) return -1; return Integer.parseInt(m.group(1)); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/jdbc/0000755000175000017500000000000012127544350025161 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/jdbc/DriverProxy.java0000644000175000017500000000575712122526606030336 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities.jdbc; import java.sql.Connection; import java.sql.Driver; import java.sql.DriverManager; import java.sql.DriverPropertyInfo; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; import java.util.Properties; import org.apache.log4j.Logger; /** * Proxies all calls to {@link Driver} that has been loaded using a custom {@link ClassLoader}. This is necessary as the * SQL {@link DriverManager} does only accept drivers loaded by the SystemClassLoader. */ public class DriverProxy implements Driver { private static Logger log = Logger.getLogger(DriverProxy.class); private final Driver driver; @SuppressWarnings("unchecked") public DriverProxy(String className, ClassLoader classLoader) throws ClassNotFoundException, InstantiationException, IllegalAccessException { Class c = (Class) classLoader.loadClass(className); driver = c.newInstance(); log.info("SQL driver loaded: v" + driver.getMajorVersion() + "." + driver.getMinorVersion() + " [" + driver.getClass().getName() + "]"); } public static void loadSQLDriver(String className, ClassLoader classLoader) throws ClassNotFoundException, InstantiationException, IllegalAccessException, SQLException { DriverProxy driver = new DriverProxy(className, classLoader); DriverManager.registerDriver(driver); } public boolean acceptsURL(String url) throws SQLException { return driver.acceptsURL(url); } public Connection connect(String url, Properties info) throws SQLException { return driver.connect(url, info); } public int getMajorVersion() { return driver.getMajorVersion(); } public int getMinorVersion() { return driver.getMinorVersion(); } public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException { return driver.getPropertyInfo(url, info); } public boolean jdbcCompliant() { return driver.jdbcCompliant(); } /** * Required for Java 7 */ public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException { throw new SQLFeatureNotSupportedException(); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/jdbc/SQLiteLoader.java0000644000175000017500000000553112127544350030320 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities.jdbc; import java.sql.Connection; import java.sql.SQLException; import javax.swing.JOptionPane; import mobac.utilities.I18nUtils; import org.apache.log4j.Logger; /** * Dynamic loading of SqliteJDBC http://www.zentus.com/sqlitejdbc/ */ public class SQLiteLoader { private static final Logger log = Logger.getLogger(SQLiteLoader.class); private static boolean SQLITE_LOADED = false; private static final String SQLITE_DRIVERNAME1 = "SQLite.JDBCDriver"; private static final String SQLITE_DRIVERNAME2 = "org.sqlite.JDBC"; public static boolean loadSQLiteOrShowError() { try { SQLiteLoader.loadSQLite(); return true; } catch (Exception e) { JOptionPane.showMessageDialog(null, SQLiteLoader.getMsgSqliteMissing(), I18nUtils.localizedStringForKey("msg_environment_slqite_lib_missing_title"), JOptionPane.ERROR_MESSAGE); return false; } } public static String getMsgSqliteMissing() { return I18nUtils.localizedStringForKey("msg_environment_slqite_lib_missing"); } public static synchronized void loadSQLite() throws SQLException { try { SQLiteLoader.loadSQLite(SQLITE_DRIVERNAME1); } catch (Exception e) { } SQLiteLoader.loadSQLite(SQLITE_DRIVERNAME2); } protected static synchronized void loadSQLite(String driverClassName) throws SQLException { if (SQLITE_LOADED) return; try { // Load the sqlite library Class.forName(driverClassName); SQLITE_LOADED = true; log.debug("SQLite library loaded. Driver class name: " + driverClassName); return; } catch (Throwable t) { SQLException e = new SQLException("Loading of SQLite library failed (" + driverClassName + "): " + t.getMessage(), t); log.error(e.getMessage()); throw e; } } public static void closeConnection(Connection conn) { if (conn == null) return; try { conn.close(); } catch (Exception e) { log.error("Failed to close SQL connection: " + e.getMessage()); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/Juli2Log4jHandler.java0000644000175000017500000000574112122526606030313 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities; import java.text.MessageFormat; import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.LogRecord; import org.apache.log4j.Logger; import org.apache.log4j.Priority; /** * A JULI (java.util.logging) handler that redirects java.util.logging messages * to Log4J http://wiki.apache.org/myfaces/Trinidad_and_Common_Logging
* User: josh Date: Jun 4, 2008 Time: 3:31:21 PM * * http://shrubbery.mynetgear.net/wiki/Routing_java.util. * logging_messages_to_Log4J */ public class Juli2Log4jHandler extends Handler { public void publish(LogRecord record) { org.apache.log4j.Logger log4j = getTargetLogger(record.getSourceClassName()); Priority priority = toLog4j(record.getLevel()); log4j.log(priority, toLog4jMessage(record), record.getThrown()); } static Logger getTargetLogger(String loggerName) { return Logger.getLogger(loggerName); } public static Logger getTargetLogger(Class clazz) { return getTargetLogger(clazz.getName()); } private String toLog4jMessage(LogRecord record) { String message = record.getMessage(); // Format message try { Object parameters[] = record.getParameters(); if (parameters != null && parameters.length != 0) { // Check for the first few parameters ? if (message.indexOf("{0}") >= 0 || message.indexOf("{1}") >= 0 || message.indexOf("{2}") >= 0 || message.indexOf("{3}") >= 0) { message = MessageFormat.format(message, parameters); } } } catch (Exception ex) { // ignore Exception } return message; } private org.apache.log4j.Level toLog4j(Level level) {// converts levels if (Level.SEVERE == level) { return org.apache.log4j.Level.ERROR; } else if (Level.WARNING == level) { return org.apache.log4j.Level.WARN; } else if (Level.INFO == level) { return org.apache.log4j.Level.INFO; } else if (Level.OFF == level) { return org.apache.log4j.Level.OFF; } return org.apache.log4j.Level.OFF; } @Override public void flush() { // nothing to do } @Override public void close() { // nothing to do } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/MapDataFileParser.java0000644000175000017500000001225312122526606030410 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.regex.Matcher; import java.util.regex.Pattern; import mobac.gui.mapview.JMapViewer; import mobac.mapsources.mapspace.MercatorPower2MapSpace; import mobac.program.interfaces.MapSpace; public class MapDataFileParser { private static final String K = "[\\s ]*,[\\s ]*"; private static final String HEAD_REGEX = "^OziExplorer Map Data File Version (\\d\\.\\d)"; private static final String POINT_REGEX = "^Point(\\d\\d)@xy@(\\d+)@(\\d+)@in@deg@" + "(\\d+)@(\\d+(?:\\.\\d+)?)@(N|S)@(\\d+)@(\\d+(?:\\.\\d+)?)@(E|W)@grid@@@" + ".*"; private static final String MMPLL_REGEX = "^MMPLL,(\\d)@(\\d+\\.\\d+)@(\\d+\\.\\d+)"; public MapDataFileParser(File mapFile) throws IOException, MapFileFormatException { this(new FileInputStream(mapFile)); } public MapDataFileParser(InputStream in) throws IOException, MapFileFormatException { BufferedReader br = new BufferedReader(new InputStreamReader(in)); String line = br.readLine(); Matcher m = Pattern.compile(HEAD_REGEX).matcher(line); if (!m.matches()) throw new MapFileFormatException("OziExplorer Map Data File Version not found"); String fileVersion = m.group(1); line = br.readLine(); // System.out.println(POINT_REGEX.replace("@", K)); Pattern pointP = Pattern.compile(POINT_REGEX.replaceAll("\\@", K)); Pattern mmpllP = Pattern.compile(MMPLL_REGEX.replaceAll("\\@", K)); ArrayList mapPoints = new ArrayList(); while (line != null) { String cLine = line; line = br.readLine(); m = pointP.matcher(cLine); if (m.matches()) { MapPoint p = new MapPoint(); // p.num = Integer.parseInt(m.group(1)); p.x = Integer.parseInt(m.group(2)); p.y = Integer.parseInt(m.group(3)); double lat = Integer.parseInt(m.group(4)) + (Double.parseDouble(m.group(5)) / 60.0); if ("S".equalsIgnoreCase(m.group(6))) lat = -lat; p.lat = lat; double lon = Integer.parseInt(m.group(7)) + (Double.parseDouble(m.group(8)) / 60.0); if ("W".equalsIgnoreCase(m.group(9))) lon = -lon; p.lon = lon; mapPoints.add(p); // System.out.println(m.group(0)); continue; } m = mmpllP.matcher(cLine); if (m.matches()) { MapPoint p = new MapPoint(); p.lon = Double.parseDouble(m.group(2)); p.lat = Double.parseDouble(m.group(3)); mapPoints.add(p); } } System.out.println("File version: " + fileVersion); // System.out.println("Callibration / map border points:"); double lat_max = Double.MIN_VALUE; double lon_max = Double.MIN_VALUE; double lat_min = Double.MAX_VALUE; double lon_min = Double.MAX_VALUE; for (MapPoint p : mapPoints) { // System.out.println("\t" + p); lat_max = Math.max(lat_max, p.lat); lon_max = Math.max(lon_max, p.lon); lat_min = Math.min(lat_min, p.lat); lon_min = Math.min(lon_min, p.lon); } System.out.println(String.format("Max point (lat/lon): %4f %4f", lat_max, lon_max)); System.out.println(String.format("Min point (lat/lon): %4f %4f", lat_min, lon_min)); MapSpace ms = MercatorPower2MapSpace.INSTANCE_256; int x1 = ms.cLonToX(lon_max, JMapViewer.MAX_ZOOM); int x2 = ms.cLonToX(lon_min, JMapViewer.MAX_ZOOM); int diff = Math.abs(x1 - x2); for (int i = 1; i < 10; i++) { System.out.println((JMapViewer.MAX_ZOOM - i) + " : " + diff); diff /= 2; } br.close(); } public static class MapPoint { // int num; int x; int y; double lat; double lon; public String toString() { return String.format("%6f %6f", lat, lon); } } public static class MapFileFormatException extends Exception { private static final long serialVersionUID = 1L; public MapFileFormatException(String message, Throwable cause) { super(message, cause); } public MapFileFormatException(String message) { super(message); } } public static void main(String[] args) { try { File f = new File("atlases/Test_2009-10-01_164148/Test1/Test1 14/Test1 14.map"); MapDataFileParser p = new MapDataFileParser(f); System.out.println(p); } catch (Exception e) { e.printStackTrace(); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/GUIExceptionHandler.java0000644000175000017500000003041212127544350030723 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities; import java.awt.AWTEvent; import java.awt.BorderLayout; import java.awt.Desktop; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Toolkit; import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.ClipboardOwner; import java.awt.datatransfer.StringSelection; import java.awt.datatransfer.Transferable; import java.io.PrintWriter; import java.io.StringWriter; import javax.swing.JCheckBox; import javax.swing.JEditorPane; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.UIManager; import javax.swing.event.HyperlinkEvent; import javax.swing.event.HyperlinkListener; import mobac.program.Logging; import mobac.program.ProgramInfo; import mobac.program.interfaces.ExceptionExtendedInfo; import org.apache.log4j.Logger; import com.sleepycat.je.ExceptionEvent; import com.sleepycat.je.ExceptionListener; public class GUIExceptionHandler implements Thread.UncaughtExceptionHandler, ExceptionListener { private static final GUIExceptionHandler instance = new GUIExceptionHandler(); private static final Logger log = Logger.getLogger(GUIExceptionHandler.class); private static final double MB_DIV = 1024d * 1024d; private static final String URL_BUGTRACKER = "http://sourceforge.net/p/mobac/bugs/"; static { Thread.setDefaultUncaughtExceptionHandler(instance); } public static void registerForCurrentThread() { Thread t = Thread.currentThread(); log.trace("Registering MOBAC exception handler for thread \"" + t.getName() + "\" [" + t.getId() + "]"); t.setUncaughtExceptionHandler(instance); } public static GUIExceptionHandler getInstance() { return instance; } private GUIExceptionHandler() { super(); } /** * Implementation for {@link com.sleepycat.je.ExceptionListener} */ public void exceptionThrown(ExceptionEvent paramExceptionEvent) { Exception e = paramExceptionEvent.getException(); log.error("Exception in tile store: " + paramExceptionEvent.toString(), e); showExceptionDialog(e); } /** * Implementation for {@link Thread.UncaughtExceptionHandler} */ public void uncaughtException(Thread t, Throwable e) { processException(t, e); } public static void processException(Throwable e) { processException(Thread.currentThread(), e); } public static void processFatalExceptionSimpleDialog(String dialogMessage, Throwable e) { log.error(dialogMessage + ": " + e.getMessage(), e); String[] options = { I18nUtils.localizedStringForKey("Exit"), I18nUtils.localizedStringForKey("dlg_download_show_error_report") }; int a = JOptionPane.showOptionDialog(null, dialogMessage, I18nUtils.localizedStringForKey("Error"), 0, JOptionPane.ERROR_MESSAGE, null, options, options[0]); if (a == 1) GUIExceptionHandler.showExceptionDialog(e); System.exit(1); } public static void processException(Thread thread, Throwable t) { log.error("Uncaught exception: ", t); showExceptionDialog(thread, t, null); } public static void processException(Thread thread, Throwable t, AWTEvent newEvent) { String eventText = newEvent.toString(); log.error("Uncaught exception on processing event " + eventText, t); if (eventText.length() > 100) { String[] parts = eventText.split(","); StringWriter sw = new StringWriter(eventText.length() + 20); sw.write(parts[0]); int len = parts[0].length(); for (int i = 1; i < parts.length; i++) { String s = parts[i]; if (s.length() + len > 80) { sw.write("\n\t"); len = 0; } sw.write(s); } eventText = "Event: " + sw.toString(); } showExceptionDialog(thread, t, eventText); } public static String prop(String key) { String s = System.getProperty(key); if (s != null) return s; else return ""; } public static void showExceptionDialog(Throwable t) { showExceptionDialog(null, Thread.currentThread(), t, null); } public static void showExceptionDialog(String message, Throwable t) { showExceptionDialog(message, Thread.currentThread(), t, null); } public static void showExceptionDialog(Thread thread, Throwable t, String additionalInfo) { showExceptionDialog(null, thread, t, additionalInfo); } public static synchronized void showExceptionDialog(String message, Thread thread, Throwable t, String additionalInfo) { try { if (t != null) { // Recursive check - in case the Exception was thrown in a Component.paint() method // this may lead to an infinite recursion with one message dialog per recursion loop String thisClassName = GUIExceptionHandler.class.getName(); for (StackTraceElement ste : t.getStackTrace()) { if (ste.getClassName().startsWith(thisClassName) && "showExceptionDialog".equals(ste.getMethodName())) { log.error("Recursive error loop detected - aborting"); return; } } } StringBuilder sb = new StringBuilder(2048); if (message != null) sb.append("Error message: " + message + "\n"); sb.append("Version: " + ProgramInfo.getCompleteTitle()); sb.append("\nPlatform: " + prop("os.name") + " (" + prop("os.version") + ")"); String windowManager = System.getProperty("sun.desktop"); if (windowManager != null) sb.append(" (" + windowManager + ")"); String dist = OSUtilities.getLinuxDistributionName(); if (dist != null) sb.append("\nDistribution name: " + dist); sb.append("\nJava VM: " + prop("java.vm.name") + " (" + prop("java.runtime.version") + ")"); Runtime r = Runtime.getRuntime(); sb.append(String.format("\nMax heap size: %3.2f MiB", r.maxMemory() / MB_DIV)); // sb.append("\nMapsources rev: " + MapSourcesUpdater.getCurrentMapSourcesRev()); sb.append("\nCPU cores: " + Runtime.getRuntime().availableProcessors()); if (thread != null) sb.append("\n\nThread: " + thread.getName()); if (additionalInfo != null) sb.append("\n\n" + additionalInfo); if (t instanceof ExceptionExtendedInfo) { ExceptionExtendedInfo ei = (ExceptionExtendedInfo) t; sb.append("\n"); sb.append(ei.getExtendedInfo()); } String guiText; String dialogTitle; JPanel panel = new JPanel(new BorderLayout()); if (t != null) { sb.append("\n\nError hierarchy:"); Throwable tmp = t; while (tmp != null) { sb.append("\n " + tmp.getClass().getSimpleName() + ": " + tmp.getMessage()); tmp = tmp.getCause(); } String exceptionName = t.getClass().getSimpleName(); dialogTitle = "Unexpected Exception: " + exceptionName; StringWriter stack = new StringWriter(); t.printStackTrace(new PrintWriter(stack)); sb.append("\n\n#############################################################\n\n"); sb.append(stack.getBuffer().toString()); sb.append("\n#############################################################"); guiText = "An unexpected exception occurred (" + exceptionName + ")
" + "

Please create a ticket in the bug tracker " + "on SourceForge.net
" + "Please include a detailed description of your performed actions
" + "before the error occurred.

Be sure to include the following information:"; } else { dialogTitle = "System report"; guiText = "This is a user generated system report.
" + "

It can be used for providing detailed version information
" + "in case a new ticket in the bug tracker is created " + "on SourceForge.net
" + "Please include a detailed description of your problem
" + "and what steps are necessary to reproduce the problem.
" + "

"; } JEditorPane text = new JEditorPane("text/html", ""); text.setOpaque(true); text.setBackground(UIManager.getColor("JFrame.background")); text.setEditable(false); text.addHyperlinkListener(new HyperlinkListener() { public void hyperlinkUpdate(HyperlinkEvent e) { if (e.getEventType() != HyperlinkEvent.EventType.ACTIVATED) return; try { Desktop.getDesktop().browse(e.getURL().toURI()); } catch (Exception e1) { log.error("", e1); } } }); panel.add(text, BorderLayout.NORTH); try { StringSelection contents = new StringSelection(sb.toString()); ClipboardOwner owner = new ClipboardOwner() { public void lostOwnership(Clipboard clipboard, Transferable contents) { } }; Toolkit.getDefaultToolkit().getSystemClipboard().setContents(contents, owner); guiText += "

(The following text has already been copied to your clipboard.)

"; } catch (RuntimeException x) { log.error("", x); } text.setText("" + guiText + ""); JCheckBox quickMOBACcb = new JCheckBox("Do not continue and quit program by pressing OK"); JTextArea info = new JTextArea(sb.toString(), 20, 60); info.setCaretPosition(0); info.setEditable(false); info.setMinimumSize(new Dimension(200, 150)); panel.add(new JScrollPane(info), BorderLayout.CENTER); panel.add(quickMOBACcb, BorderLayout.SOUTH); panel.setMinimumSize(new Dimension(700, 300)); panel.validate(); JOptionPane.showMessageDialog(null, panel, dialogTitle, JOptionPane.ERROR_MESSAGE); if (quickMOBACcb.isSelected()) { log.warn("User selected to quit MOBAC after an exception"); System.exit(1); } } catch (Exception e1) { e1.printStackTrace(); } } public static void installToolkitEventQueueProxy() { boolean isLikeJava7 = Float.parseFloat(System.getProperty("java.specification.version")) > 1.6; EventQueueProxy eventQueueProxy = new EventQueueProxy(); // Bug handling. See // http://stackoverflow.com/questions/3158254/how-to-replace-the-awt-eventqueue-with-own-implementation try { if (isLikeJava7) EventQueue.invokeAndWait(eventQueueProxy); else eventQueueProxy.run(); } catch (Exception e) { log.error("", e); } } /** * Catching all Runtime Exceptions in Swing * * http://ruben42.wordpress.com/2009/03/30/catching-all-runtime-exceptions-in-swing/ */ protected static class EventQueueProxy extends EventQueue implements Runnable { /** * Installs the {@link EventQueueProxy} */ @Override public void run() { EventQueue queue = Toolkit.getDefaultToolkit().getSystemEventQueue(); queue.push(this); } protected void dispatchEvent(AWTEvent newEvent) { try { super.dispatchEvent(newEvent); } catch (Throwable e) { if (e instanceof ArrayIndexOutOfBoundsException) { StackTraceElement[] st = e.getStackTrace(); if (st.length > 0) { if ("sun.font.FontDesignMetrics".equals(st[0].getClassName())) { log.error("Ignored JRE bug exception " + e.getMessage() + " caused by : " + st[0]); // This is a known JRE bug - we just ignore it return; } } } GUIExceptionHandler.processException(Thread.currentThread(), e); } } } public static void main(String[] args) { for (;;) { try { Logging.configureConsoleLogging(); UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); throw new RuntimeException("Test", new Exception("Inner")); } catch (Exception e) { showExceptionDialog("Test 123", e); } catch (Error e) { showExceptionDialog(e); } break; } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/I18nUtils.java0000644000175000017500000001005012136352442026655 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnection; import java.util.Locale; import java.util.PropertyResourceBundle; import java.util.ResourceBundle; import java.util.ResourceBundle.Control; import mobac.Main; import mobac.program.model.Settings; public class I18nUtils { // MP: return application's resource strings private static ResourceBundle STRING_RESOURCE = null; public static String localizedStringForKey(String key, Object... args) { if (STRING_RESOURCE == null) I18nUtils.updateLocalizedStringFormSettings(); String str = null; try { str = STRING_RESOURCE.getString(key); if (args.length > 0) str = String.format(str, args); } catch (Exception e) { str = key; } if (str == null) { // always return a valid string str = ""; } return str; } public static synchronized void updateLocalizedStringFormSettings() { Settings settings = Settings.getInstance(); // force to use Simplify-Chinese Locale, will update later Locale locale = null; if (settings != null) { locale = new Locale(settings.localeLanguage, settings.localeCountry); } else { locale = Locale.getDefault(); } STRING_RESOURCE = ResourceBundle.getBundle("mobac.resources.text.localize", locale, new UTF8Control()); } /** * http://stackoverflow.com/questions/4659929/how-to-use-utf-8-in-resource-properties-with-resourcebundle */ public static class UTF8Control extends Control { public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload) throws IllegalAccessException, InstantiationException, IOException { // The below is a copy of the default implementation. String bundleName = toBundleName(baseName, locale); String resourceName = toResourceName(bundleName, "properties"); ResourceBundle bundle = null; InputStream stream = null; if (reload) { URL url = loader.getResource(resourceName); if (url != null) { URLConnection connection = url.openConnection(); if (connection != null) { connection.setUseCaches(false); stream = connection.getInputStream(); } } } else { stream = loader.getResourceAsStream(resourceName); } if (stream != null) { try { // Only this line is changed to make it to read properties files as UTF-8. bundle = new PropertyResourceBundle(new InputStreamReader(stream, Charsets.UTF_8)); } finally { stream.close(); } } return bundle; } } public static InputStream getI18nResourceAsStream(String name, String extension) { Settings s = Settings.getInstance(); String country = s.localeCountry; String language = s.localeLanguage; InputStream in; in = Main.class.getResourceAsStream(String.format("%s_%s_%s.%s", name, language, country, extension)); if (in != null) return in; in = Main.class.getResourceAsStream(String.format("%s_%s.%s", name, language, extension)); if (in != null) return in; in = Main.class.getResourceAsStream(String.format("%s.%s", name, extension)); return in; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/file/0000755000175000017500000000000012122526606025175 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/file/DeleteFileFilter.java0000644000175000017500000000430312122526606031210 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities.file; import java.io.File; import java.io.FileFilter; /** * A {@link FileFilter} that deletes every file in the directory specified by * the {@link File} on which {@link File#listFiles(FileFilter)} using * {@link DeleteFileFilter} is executed. Therefore the {@link FileFilter} * concept is abused as {@link File} enumerator. *

* Example: new File("C:/Temp").listFiles(new DeleteFileFilter()); * deletes all files but no directories in the directory C:\Temp. *

*/ public class DeleteFileFilter implements FileFilter { int countSuccess = 0; int countFailed = 0; int countError = 0; public boolean accept(File file) { try { if (file.isDirectory()) // We only delete files return false; boolean success = file.delete(); if (success) countSuccess++; else countFailed++; } catch (Exception e) { countError++; } // We don't care about the filter result return false; } public int getCountSuccess() { return countSuccess; } public int getCountFailed() { return countFailed; } public int getCountError() { return countError; } @Override public String toString() { return "Delete file filter status (success, failed, error): " + countSuccess + " / " + countFailed + " / " + countError + " files"; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/file/GpxFileFilter.java0000644000175000017500000000257112122526606030551 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities.file; import java.io.File; import javax.swing.filechooser.FileFilter; public class GpxFileFilter extends FileFilter { private boolean onlyGpx11; public GpxFileFilter(boolean onlyGpx11) { this.onlyGpx11 = onlyGpx11; } @Override public boolean accept(File f) { return f.isDirectory() || f.getName().endsWith(".gpx"); } @Override public String getDescription() { if (onlyGpx11) return "GPX 1.1 files (*.gpx)"; else return "GPX 1.0/1.1 files (*.gpx)"; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/file/RegexFileFilter.java0000644000175000017500000000233012122526606031056 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities.file; import java.io.File; import java.io.FileFilter; import java.util.regex.Pattern; public class RegexFileFilter implements FileFilter { private Pattern p; public RegexFileFilter(String regex) { p = Pattern.compile(regex); } public boolean accept(File pathname) { return p.matcher(pathname.getName()).matches(); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/file/DirInfoFileFilter.java0000644000175000017500000000261212122526606031341 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities.file; import java.io.File; import java.io.FileFilter; import mobac.utilities.Utilities; public class DirInfoFileFilter implements FileFilter { long dirSize = 0; int fileCount = 0; public DirInfoFileFilter() { } public boolean accept(File f) { if (f.isDirectory()) return false; Utilities.checkForInterruptionRt(); dirSize += f.length(); fileCount++; return false; } public long getDirSize() { return dirSize; } public int getFileCount() { return fileCount; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/file/NamePatternFileFilter.java0000644000175000017500000000261112122526606032224 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities.file; import java.io.File; import java.io.FileFilter; import java.util.regex.Matcher; import java.util.regex.Pattern; public class NamePatternFileFilter implements FileFilter { protected final Pattern pattern; public NamePatternFileFilter(Pattern pattern) { this.pattern = pattern; } public NamePatternFileFilter(String regex) { this.pattern = Pattern.compile(regex); } public boolean accept(File pathname) { Matcher m = pattern.matcher(pathname.getName()); return m.matches(); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/file/FileExtFilter.java0000644000175000017500000000234112122526606030546 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities.file; import java.io.File; import java.io.FileFilter; public class FileExtFilter implements FileFilter { private final String acceptedFileExt; public FileExtFilter(String acceptedFileExt) { this.acceptedFileExt = acceptedFileExt; } public boolean accept(File pathname) { return pathname.getName().endsWith(acceptedFileExt); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/file/DirectoryFileFilter.java0000644000175000017500000000216412122526606031755 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities.file; import java.io.File; import java.io.FileFilter; /** * A {@link FileFilter} only returning directories. */ public class DirectoryFileFilter implements FileFilter { public boolean accept(File f) { return f.isDirectory(); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/debug/0000755000175000017500000000000012122526606025344 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/debug/MySocketImplFactory.java0000644000175000017500000002215712122526606032126 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities.debug; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.HttpURLConnection; import java.net.InetAddress; import java.net.Socket; import java.net.SocketAddress; import java.net.SocketException; import java.net.SocketImpl; import java.net.SocketImplFactory; import java.net.URL; import mobac.program.Logging; import org.apache.log4j.Level; import org.apache.log4j.Logger; /** * Proxies the default {@link SocketImpl} using reflection. This allows to trace * all calls into the log file. * * Requires SunJRE/SunJDK! */ public class MySocketImplFactory implements SocketImplFactory { private static Logger log = Logger.getLogger(MySocketImplFactory.class); /** * @param args */ public static void main(String[] args) { try { install(); Logging.configureConsoleLogging(Level.TRACE); HttpURLConnection conn = (HttpURLConnection) new URL("http://google.de") .openConnection(); conn.connect(); byte[] data = new byte[1024]; new DataInputStream(conn.getInputStream()).readFully(data); System.out.println(new String(data)); Thread.sleep(1000); System.gc(); Thread.sleep(1000); } catch (Exception e) { e.printStackTrace(); } } public static void install() throws IOException { try { Socket.setSocketImplFactory(new MySocketImplFactory()); } catch (IOException e) { throw e; } catch (Exception e) { throw new IOException("Unable to install " + MySocketImplFactory.class.getSimpleName(), e); } } private final Constructor constructor; private final Method accept; private final Method bind; private final Method available; private final Method create; private final Method connect1; private final Method connect2; private final Method connect3; private final Method close; private final Method getInputStream; private final Method getOutputStream; private final Method sendUrgentData; private final Method listen; public MySocketImplFactory() throws ClassNotFoundException, SecurityException, NoSuchMethodException { super(); Class c = Class.forName("java.net.PlainSocketImpl"); constructor = c.getDeclaredConstructor(); constructor.setAccessible(true); accept = c.getDeclaredMethod("accept", SocketImpl.class); accept.setAccessible(true); bind = c.getDeclaredMethod("bind", InetAddress.class, Integer.TYPE); bind.setAccessible(true); available = c.getDeclaredMethod("available"); available.setAccessible(true); create = c.getDeclaredMethod("create", Boolean.TYPE); create.setAccessible(true); connect1 = c.getDeclaredMethod("connect", InetAddress.class, Integer.TYPE); connect1.setAccessible(true); connect2 = c.getDeclaredMethod("connect", SocketAddress.class, Integer.TYPE); connect2.setAccessible(true); connect3 = c.getDeclaredMethod("connect", String.class, Integer.TYPE); connect3.setAccessible(true); getInputStream = c.getDeclaredMethod("getInputStream"); getInputStream.setAccessible(true); getOutputStream = c.getDeclaredMethod("getOutputStream"); getOutputStream.setAccessible(true); close = c.getDeclaredMethod("close"); close.setAccessible(true); sendUrgentData = c.getDeclaredMethod("sendUrgentData", Integer.TYPE); sendUrgentData.setAccessible(true); listen = c.getDeclaredMethod("listen", Integer.TYPE); listen.setAccessible(true); } public SocketImpl createSocketImpl() { try { return new MySocketImpl(); } catch (Exception e) { throw new RuntimeException(e); } } private class MySocketImpl extends SocketImpl { private final SocketImpl si; private final int socketId; private MySocketImpl() throws IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException { si = (SocketImpl) constructor.newInstance(); socketId = si.hashCode(); log.trace("[" + socketId + "] new SocketImpl created"); } @Override protected void finalize() throws Throwable { close(); super.finalize(); } @Override protected void accept(SocketImpl s) throws IOException { log.trace("[" + socketId + "] accept(...)"); try { accept.invoke(si, s); } catch (Exception e) { if (e instanceof IOException) throw (IOException) e; throw new RuntimeException(e); } } @Override protected int available() throws IOException { // log.trace("[" + socketId + "] available()"); try { return ((Integer) bind.invoke(si)).intValue(); } catch (Exception e) { if (e instanceof IOException) throw (IOException) e; throw new RuntimeException(e); } } @Override protected void bind(InetAddress host, int port) throws IOException { log.trace("[" + socketId + "] bind()"); try { bind.invoke(si, host, port); } catch (Exception e) { if (e instanceof IOException) throw (IOException) e; throw new RuntimeException(e); } } @Override protected void close() throws IOException { log.trace("[" + socketId + "] close()"); try { close.invoke(si); } catch (Exception e) { if (e instanceof IOException) throw (IOException) e; throw new RuntimeException(e); } } @Override protected void connect(InetAddress address, int port) throws IOException { log.trace("[" + socketId + "] connect1(..)"); try { connect1.invoke(si, address, port); } catch (Exception e) { if (e instanceof IOException) throw (IOException) e; throw new RuntimeException(e); } } @Override protected void connect(SocketAddress address, int timeout) throws IOException { log.trace("[" + socketId + "] connect2(..)"); try { connect2.invoke(si, address, timeout); } catch (Exception e) { if (e instanceof IOException) throw (IOException) e; throw new RuntimeException(e); } } @Override protected void connect(String host, int port) throws IOException { log.trace("[" + socketId + "] connect3(..)"); try { connect3.invoke(si, host, port); } catch (Exception e) { if (e instanceof IOException) throw (IOException) e; throw new RuntimeException(e); } } @Override protected void create(boolean stream) throws IOException { log.trace("[" + socketId + "] create(..)"); try { create.invoke(si, stream); } catch (Exception e) { if (e instanceof IOException) throw (IOException) e; throw new RuntimeException(e); } } @Override protected InputStream getInputStream() throws IOException { // log.trace("[" + socketId + "] getInputStream()"); try { return (InputStream) getInputStream.invoke(si); } catch (Exception e) { if (e instanceof IOException) throw (IOException) e; throw new RuntimeException(e); } } public Object getOption(int optID) throws SocketException { // log.trace("[" + socketId + "] getOption(..)"); return si.getOption(optID); } @Override protected OutputStream getOutputStream() throws IOException { // log.trace("[" + socketId + "] getOutputStream()"); try { return (OutputStream) getOutputStream.invoke(si); } catch (Exception e) { if (e instanceof IOException) throw (IOException) e; throw new RuntimeException(e); } } @Override protected void listen(int backlog) throws IOException { log.trace("[" + socketId + "] listen(..)"); try { listen.invoke(si, backlog); } catch (Exception e) { if (e instanceof IOException) throw (IOException) e; throw new RuntimeException(e); } } @Override protected void sendUrgentData(int data) throws IOException { // log.trace("[" + socketId + "] sendUrgentData"); try { sendUrgentData.invoke(si, data); } catch (Exception e) { if (e instanceof IOException) throw (IOException) e; throw new RuntimeException(e); } } public void setOption(int optID, Object value) throws SocketException { // log.trace("[" + socketId + "] setOption"); si.setOption(optID, value); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/collections/0000755000175000017500000000000012122526606026574 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/collections/SoftHashMap.java0000644000175000017500000000510012122526606031610 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities.collections; import java.lang.ref.SoftReference; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Set; /** * A HashMap that uses internally SoftReferences for the value (if the app is * running out of memory the values stored in a {@link SoftReference} will be * automatically freed. * * Therefore it may happen that this map "looses" values. * * @param * @param */ public class SoftHashMap implements Map { HashMap> map; public SoftHashMap(int initialCapacity) { map = new HashMap>(initialCapacity); } public V get(Object key) { SoftReference ref = map.get(key); return (ref != null) ? ref.get() : null; } public V put(K key, V value) { SoftReference ref = map.put(key, new SoftReference(value)); return (ref != null) ? ref.get() : null; } public V remove(Object key) { SoftReference ref = map.remove(key); return (ref != null) ? ref.get() : null; } public void clear() { map.clear(); } public boolean containsKey(Object key) { return map.containsKey(key); } public boolean containsValue(Object value) { return map.containsValue(value); } public boolean isEmpty() { return map.isEmpty(); } public Set keySet() { return map.keySet(); } public int size() { return map.size(); } public Set> entrySet() { throw new RuntimeException("Not implemented"); } public void putAll(Map m) { throw new RuntimeException("Not implemented"); } public Collection values() { throw new RuntimeException("Not implemented"); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/GBCTable.java0000644000175000017500000000461412122526606026471 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities; import java.awt.Insets; public class GBCTable { public static final int DEFAULT_ROW_SPACING = 4, DEFAULT_COL_SPACING = 8; private final int colSpacing, rowSpacing; private final GBC gbc = GBC.std(); private int x, y, yBegin; public GBCTable() { this(DEFAULT_ROW_SPACING, DEFAULT_COL_SPACING); } public GBCTable(int spacing) { this(spacing, spacing); } public GBCTable(int rowSpacing, int colSpacing) { this.rowSpacing = rowSpacing; this.colSpacing = colSpacing; begin(); } public GBC begin() { return begin(1, 1); } public GBC begin(int x, int y) { this.x = x; this.y = yBegin = y; reset(); return gbc; } public GBC incX() { return nextCol(1); } public GBC nextCol(int x) { this.x += x; y = yBegin; reset(); return gbc; } public GBC incY() { return nextRow(1); } public GBC nextRow(int y) { this.y += y; reset(); return gbc; } /** * Ensures the {@link gbc} object was not modified. Reseting the values is cheaper than creating a new object. */ private void reset() { gbc.gridwidth = gbc.gridheight = 1; gbc.weightx = gbc.weighty = 0d; gbc.fill = GBC.HORIZONTAL; gbc.anchor = GBC.WEST; if (gbc.insets == null) { gbc.insets = new Insets(0, 0, 0, 0); } else { gbc.insets.top = gbc.insets.bottom = gbc.insets.left = gbc.insets.right = 0; } if ((gbc.gridx = x) > 1) { gbc.insets.left = colSpacing; } if ((gbc.gridy = y) > 1) { gbc.insets.top = rowSpacing; } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/geo/0000755000175000017500000000000012122526606025030 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/geo/CoordinateTileFormat.java0000644000175000017500000000606412122526606031757 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities.geo; import java.text.FieldPosition; import java.text.NumberFormat; import java.text.ParsePosition; import mobac.gui.MainGUI; import mobac.program.interfaces.MapSpace; import org.apache.log4j.Logger; public class CoordinateTileFormat extends NumberFormat { protected static Logger log = Logger.getLogger(CoordinateTileFormat.class); private final boolean isLongitude; public CoordinateTileFormat(boolean isLongitude) { this.isLongitude = isLongitude; } @Override public StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition pos) { MainGUI gui = MainGUI.getMainGUI(); MapSpace mapSpace = gui.getSelectedMapSource().getMapSpace(); int zoom = gui.previewMap.getZoom(); int tileNum = 0; if (isLongitude) tileNum = mapSpace.cLonToX(number, zoom); else tileNum = mapSpace.cLatToY(number, zoom); toAppendTo.append(String.format("%d / z%d ", tileNum / mapSpace.getTileSize(), zoom)); return toAppendTo; } @Override public StringBuffer format(long number, StringBuffer toAppendTo, FieldPosition pos) { throw new RuntimeException("Not implemented"); } @Override public Number parse(String source, ParsePosition parsePosition) { MainGUI gui = MainGUI.getMainGUI(); MapSpace mapSpace = gui.getSelectedMapSource().getMapSpace(); try { String[] tokens = source.trim().split("/"); int zoom = 0; int tileNum = 0; if (tokens.length == 2) { String s = tokens[1].trim(); if (s.startsWith("z")) s = s.substring(1); zoom = Integer.parseInt(s); } else { zoom = gui.previewMap.getZoom(); } if (tokens.length > 0) { String s = tokens[0]; s = s.trim(); if ((s.indexOf('.') < 0) && (s.indexOf(',') < 0)) { tileNum = Integer.parseInt(s); tileNum *= mapSpace.getTileSize(); } else { double num = Double.parseDouble(s); tileNum = (int) (num * mapSpace.getTileSize()); } } parsePosition.setIndex(source.length()); if (isLongitude) return mapSpace.cXToLon(tileNum, zoom); return mapSpace.cYToLat(tileNum, zoom); } catch (Exception e) { parsePosition.setErrorIndex(0); log.error("e"); return null; } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/geo/CoordinateDm2Format.java0000644000175000017500000000565312122526606031507 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities.geo; import java.math.RoundingMode; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.text.FieldPosition; import java.text.NumberFormat; import java.text.ParseException; import java.text.ParsePosition; import org.apache.log4j.Logger; public class CoordinateDm2Format extends NumberFormat { protected static Logger log = Logger.getLogger(CoordinateDms2Format.class); NumberFormat degFmt; NumberFormat minFmt; NumberFormat minFmtParser; public CoordinateDm2Format(DecimalFormatSymbols dfs) { degFmt = new DecimalFormat("00°", dfs); minFmt = new DecimalFormat("00.00''", dfs); minFmt.setRoundingMode(RoundingMode.FLOOR); minFmtParser = new DecimalFormat("##.##", dfs); } @Override public StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition pos) { int degrees; if (number >= 0) degrees = (int) Math.floor(number); else degrees = (int) Math.ceil(number); double minutes = Math.abs((number - degrees) * 60); if (number < 0 && degrees == 0) toAppendTo.append("-"); toAppendTo.append(degFmt.format(degrees) + " "); toAppendTo.append(minFmt.format(minutes)); return toAppendTo; } @Override public StringBuffer format(long number, StringBuffer toAppendTo, FieldPosition pos) { throw new RuntimeException("Not implemented"); } @Override public Number parse(String source) throws ParseException { return parse(source, new ParsePosition(0)); } @Override public Number parse(String source, ParsePosition parsePosition) { String[] tokens = source.trim().split("[°\\']"); if (tokens.length != 2) return null; try { String degStr = tokens[0].trim(); int deg = Integer.parseInt(degStr); double min = minFmtParser.parse(tokens[1].trim()).doubleValue(); double coord; if (degStr.startsWith("-")) coord = deg - min / 60.0; else coord = deg + min / 60.0; return new Double(coord); } catch (Exception e) { parsePosition.setErrorIndex(0); log.error("e"); return null; } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/geo/GeoUtils.java0000644000175000017500000000255112122526606027431 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities.geo; import java.util.Locale; public class GeoUtils { public static String getDegMinFormat(double coord, boolean isLatitude) { boolean neg = (coord < 0.0); coord = Math.abs(coord); int deg = (int) coord; double min = (coord - deg) * 60.0; String degMinFormat = "%d, %3.6f, %c"; char dirC; if (isLatitude) dirC = (neg ? 'S' : 'N'); else dirC = (neg ? 'W' : 'E'); return String.format(Locale.ENGLISH, degMinFormat, deg, min, dirC); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/geo/CoordinateDms2Format.java0000644000175000017500000000645712122526606031675 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities.geo; import java.math.RoundingMode; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.text.FieldPosition; import java.text.NumberFormat; import java.text.ParseException; import java.text.ParsePosition; import org.apache.log4j.Logger; public class CoordinateDms2Format extends NumberFormat { protected static Logger log = Logger.getLogger(CoordinateDms2Format.class); NumberFormat degFmt; NumberFormat minFmt; NumberFormat secFmt; NumberFormat secFmtParser; public CoordinateDms2Format(DecimalFormatSymbols dfs) { degFmt = new DecimalFormat("00°", dfs); minFmt = new DecimalFormat("00''", dfs); minFmt.setRoundingMode(RoundingMode.FLOOR); secFmt = new DecimalFormat("00.00\"", dfs); secFmt.setRoundingMode(RoundingMode.FLOOR); secFmtParser = new DecimalFormat("##.##", dfs); } @Override public StringBuffer format(double numberOrg, StringBuffer toAppendTo, FieldPosition pos) { double number = numberOrg; int degrees; int minutes; double seconds; if (number >= 0) degrees = (int) Math.floor(number); else degrees = (int) Math.ceil(number); number = Math.abs((number - degrees) * 60); minutes = (int) Math.floor(number); seconds = (number - minutes) * 60; if (numberOrg < 0 && degrees == 0) toAppendTo.append("-"); toAppendTo.append(degFmt.format(degrees) + " "); toAppendTo.append(minFmt.format(minutes) + " "); toAppendTo.append(secFmt.format(seconds)); return toAppendTo; } @Override public StringBuffer format(long number, StringBuffer toAppendTo, FieldPosition pos) { throw new RuntimeException("Not implemented"); } @Override public Number parse(String source) throws ParseException { return parse(source, new ParsePosition(0)); } @Override public Number parse(String source, ParsePosition parsePosition) { String[] tokens = source.trim().split("[°\\'\\\"]"); if (tokens.length != 3) return null; try { String degStr = tokens[0].trim(); int deg = Integer.parseInt(degStr); int min = Integer.parseInt(tokens[1].trim()); double sec = secFmtParser.parse(tokens[2].trim()).doubleValue(); double coord; if (degStr.startsWith("-")) coord = deg - sec / 3600 - min / 60.0; else coord = deg + sec / 3600 + min / 60.0; return new Double(coord); } catch (Exception e) { parsePosition.setErrorIndex(0); log.error("e"); return null; } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/OSUtilities.java0000644000175000017500000001371412127544350027345 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.FilenameFilter; import java.util.regex.Pattern; import javax.naming.NameNotFoundException; import javax.swing.JOptionPane; import org.apache.log4j.Logger; public class OSUtilities { static Logger log = Logger.getLogger(OSUtilities.class); public enum OperatingSystem { Windows, Linux, MacOs, MacOsX, Solaris, Unknown }; public enum DesktopType { Windows, Gnome, Kde, Unknown { @Override public String toString() { return super.toString() + " (" + System.getProperty("sun.desktop") + ")"; } } }; public static OperatingSystem detectOs() { String osName = System.getProperty("os.name").toLowerCase(); if (osName.indexOf("windows") > -1) return OperatingSystem.Windows; if (osName.indexOf("linux") > -1) return OperatingSystem.Linux; if (osName.indexOf("mac os x") > -1) return OperatingSystem.MacOsX; if (osName.indexOf("mac os") > -1) return OperatingSystem.MacOs; if (osName.indexOf("sunos") > -1) return OperatingSystem.Solaris; return OperatingSystem.Unknown; } public static DesktopType detectDesktopType() { String desktopName = System.getProperty("sun.desktop"); if (desktopName == null) return DesktopType.Unknown; desktopName = desktopName.toLowerCase().trim(); if (desktopName.startsWith("windows")) return DesktopType.Windows; if (desktopName.startsWith("gnome")) return DesktopType.Gnome; if (desktopName.startsWith("kde")) return DesktopType.Kde; log.error("Unknown desktop type: " + desktopName); return DesktopType.Unknown; } public static void openFolderBrowser(File directory) throws NameNotFoundException { if (!directory.isDirectory()) throw new NameNotFoundException("Directory does not exist or is not a directory"); String[] strCmd = null; try { String dirPath = directory.getCanonicalPath(); DesktopType dt = detectDesktopType(); switch (dt) { case Windows: strCmd = new String[] { "rundll32.exe", "url.dll,FileProtocolHandler", "\"" + dirPath + "\"" }; break; case Gnome: strCmd = new String[] { "nautilus", dirPath }; break; case Kde: strCmd = new String[] { "konqueror", dirPath }; break; default: OperatingSystem os = detectOs(); switch (os) { case MacOsX: strCmd = new String[] { "/usr/bin/open", dirPath }; break; case Linux: strCmd = new String[] { "/usr/bin/xdg-open", dirPath }; break; default: JOptionPane.showMessageDialog(null, String.format(I18nUtils.localizedStringForKey("msg_environment_not_support"), dt, os), I18nUtils.localizedStringForKey("msg_environment_not_support_title"), JOptionPane.ERROR_MESSAGE); return; } } for (String s : strCmd) log.trace("exec/params: " + s); Runtime.getRuntime().exec(strCmd); } catch (Exception e) { StringBuilder sb = new StringBuilder(512); sb.append(I18nUtils.localizedStringForKey("msg_environment_failed_open_output")); sb.append(e.getMessage()); sb.append(String.format(I18nUtils.localizedStringForKey("msg_environment_use_commond"), strCmd[0])); for (int i = 1; i < strCmd.length; i++) { sb.append(String.format(I18nUtils.localizedStringForKey("msg_environment_commond_param"), i, strCmd[i])); } sb.append(""); String msg = sb.toString(); JOptionPane.showMessageDialog(null, msg, I18nUtils.localizedStringForKey("msg_environment_failed_open_output_title"), JOptionPane.ERROR_MESSAGE); log.error(msg, e); } } /** * Reads the Linux distribution name (last line) from the first file that matches the pattern * *
	 * /etc/*-release
	 * 
* * @return Linux distrbution name or null */ public static String getLinuxDistributionName() { try { File etcDir = new File("/etc"); if (!etcDir.exists()) return null; File[] files = etcDir.listFiles(new FilenameFilter() { Pattern pattern = Pattern.compile(".*-release"); public boolean accept(File dir, String name) { return pattern.matcher(name).matches(); } }); if (files.length == 0) return null; BufferedReader br = new BufferedReader(new FileReader(files[0])); String result = null; String line = null; line = br.readLine(); while (line != null) { result = line; line = br.readLine(); } br.close(); if (result != null) { int index = result.indexOf('='); if (index > 0) result = result.substring(index + 1); if (result.startsWith("\"") && result.endsWith("\"")) result = result.substring(1, result.length() - 2); } return result; } catch (Exception e) { log.trace("", e); return null; } } /** * Replies true if we are currently running on OSX * * @return true if we are currently running on OSX */ public static boolean isPlatformOsx() { String os = System.getProperty("os.name"); return os != null && os.toLowerCase().startsWith("mac os x"); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/writer/0000755000175000017500000000000012122526606025572 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/writer/NullPrintWriter.java0000644000175000017500000000213412122526606031561 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities.writer; import java.io.FileNotFoundException; import java.io.PrintWriter; public class NullPrintWriter extends PrintWriter { public NullPrintWriter() throws FileNotFoundException { super(new NullWriter()); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/writer/NullWriter.java0000644000175000017500000000227312122526606030550 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities.writer; import java.io.IOException; import java.io.Writer; public class NullWriter extends Writer { @Override public void close() throws IOException { } @Override public void flush() throws IOException { } @Override public void write(char[] cbuf, int off, int len) throws IOException { } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/imageio/0000755000175000017500000000000012122526606025670 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/imageio/PngXxlWriter.java0000644000175000017500000001666612122526606031167 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities.imageio; /* * PNGWriter.java * * Copyright (c) 2007 Matthias Mann - www.matthiasmann.de * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * */ import static mobac.utilities.imageio.PngConstants.*; import java.awt.Rectangle; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.DataBuffer; import java.awt.image.DataBufferByte; import java.awt.image.DataBufferInt; import java.awt.image.DirectColorModel; import java.io.BufferedOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.zip.CRC32; import java.util.zip.Deflater; import java.util.zip.DeflaterOutputStream; import javax.activation.UnsupportedDataTypeException; /** * A PNG writer that is able to write extra large PNG images using incremental * writing. *

* The image is processed incremental in "tile lines" - e.g. an PNG image of * 30000 x 20000 pixels (width x height) can be written by 200 "tile lines" of * size 30000 x 100 pixels. Each tile line can be written via the method * {@link #writeTileLine(BufferedImage)}. After writing the last line you have * to call {@link #finish()} which will write the final PNG structure * information into the {@link OutputStream}. *

*

* Please note that this writer creates 24bit/truecolor PNGs. Transparency and * alpha masks are not supported. *

* Bases on the PNGWriter written by Matthias Mann - www.matthiasmann.de * * @author r_x */ public class PngXxlWriter { private static final int BUFFER_SIZE = 128 * 1024; private int width; private int height; private DataOutputStream dos; ImageDataChunkWriter imageDataChunkWriter; /** * Creates an PNG writer instance for an image with the specified width and * height. * * @param width * width of the PNG image to be written * @param height * height of the PNG image to be written * @param os * destination to write the PNG image data to * @throws IOException */ public PngXxlWriter(int width, int height, OutputStream os) throws IOException { this.width = width; this.height = height; this.dos = new DataOutputStream(os); dos.write(SIGNATURE); PngChunk cIHDR = new PngChunk(IHDR); cIHDR.writeInt(this.width); cIHDR.writeInt(this.height); cIHDR.writeByte(8); // 8 bit per component cIHDR.writeByte(COLOR_TRUECOLOR); cIHDR.writeByte(COMPRESSION_DEFLATE); cIHDR.writeByte(FILTER_SET_1); cIHDR.writeByte(INTERLACE_NONE); cIHDR.writeTo(dos); imageDataChunkWriter = new ImageDataChunkWriter(dos); } /** * * @param tileLineImage * @throws IOException */ public void writeTileLine(BufferedImage tileLineImage) throws IOException { int tileLineHeight = tileLineImage.getHeight(); int tileLineWidth = tileLineImage.getWidth(); if (width != tileLineWidth) throw new RuntimeException("Invalid width"); ColorModel cm = tileLineImage.getColorModel(); if (!(cm instanceof DirectColorModel)) throw new UnsupportedDataTypeException( "Image uses wrong color model. Only DirectColorModel is supported!"); // We process the image line by line, from head to bottom Rectangle rect = new Rectangle(0, 0, tileLineWidth, 1); DataOutputStream imageDataStream = imageDataChunkWriter.getStream(); byte[] curLine = new byte[width * 3]; for (int line = 0; line < tileLineHeight; line++) { rect.y = line; DataBuffer db = tileLineImage.getData(rect).getDataBuffer(); if (db.getNumBanks() > 1) throw new UnsupportedDataTypeException("Image data has more than one data bank"); if (db instanceof DataBufferByte) curLine = ((DataBufferByte) db).getData(); else if (db instanceof DataBufferInt) { int[] intLine = ((DataBufferInt) db).getData(); int c = 0; for (int i = 0; i < intLine.length; i++) { int pixel = intLine[i]; curLine[c++] = (byte) (pixel >> 16 & 0xFF); curLine[c++] = (byte) (pixel >> 8 & 0xFF); curLine[c++] = (byte) (pixel & 0xFF); } } else throw new UnsupportedDataTypeException(db.getClass().getName()); imageDataStream.write(FILTER_TYPE_NONE); imageDataStream.write(curLine); } } public void finish() throws IOException { imageDataChunkWriter.finish(); PngChunk cIEND = new PngChunk(IEND); cIEND.writeTo(dos); cIEND.close(); dos.flush(); } static class ImageDataChunkWriter extends OutputStream { DeflaterOutputStream dfos; DataOutputStream stream; DataOutputStream out; CRC32 crc = new CRC32(); public ImageDataChunkWriter(DataOutputStream out) throws IOException { this.out = out; dfos = new DeflaterOutputStream(new BufferedOutputStream(this, BUFFER_SIZE), new Deflater(Deflater.BEST_COMPRESSION)); stream = new DataOutputStream(dfos); } public DataOutputStream getStream() { return stream; } public void finish() throws IOException { stream.flush(); stream.close(); dfos.finish(); dfos = null; } @Override public void write(byte[] b, int off, int len) throws IOException { crc.reset(); out.writeInt(len); out.writeInt(IDAT); out.write(b, off, len); crc.update("IDAT".getBytes()); crc.update(b, off, len); out.writeInt((int) crc.getValue()); } @Override public void write(byte[] b) throws IOException { write(b, 0, b.length); } @Override public void write(int b) throws IOException { throw new IOException("Simgle byte writing not supported"); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/imageio/PngConstants.java0000644000175000017500000000517712122526606031166 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities.imageio; /** * Common constants used in the PNG file format. http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html#C.IHDR */ public class PngConstants { /** * PNG magic file bytes */ public static final byte[] SIGNATURE = { (byte) 137, 80, 78, 71, 13, 10, 26, 10 }; /** * Chunk header identifiers */ public static final int IHDR = (int) 0x49484452; // png header public static final int TEXT = (int) 0x74455874; // textual information public static final int PLTE = (int) 0x504C5445; // color palette public static final int IDAT = (int) 0x49444154; // image data public static final int IEND = (int) 0x49454E44; // end of file /** * Each pixel is a grayscale sample. Allowed bit depths: 1,2,4,8,16 */ public static final byte COLOR_GRAYSCALE = 0; /** * Each pixel is an R,G,B triple. Allowed bit depths: 8,16 */ public static final byte COLOR_TRUECOLOR = 2; /** * Each pixel is a palette index; a PLTE chunk must appear. Allowed bit depths: 1,2,4,8 */ public static final byte COLOR_PALETTE = 3; /** * Each pixel is a grayscale sample, followed by an alpha sample. Allowed bit depths: 8,16 */ public static final byte COLOR_GRAYSCALE_ALPHA = 4; /** * Each pixel is an R,G,B triple, followed by an alpha sample. Allowed bit depths: 6 8,16 */ public static final byte COLOR_TRUECOLOR_ALPHA = 6; public static final byte COMPRESSION_DEFLATE = 0; public static final byte FILTER_SET_1 = 0; public static final byte INTERLACE_NONE = 0; public static final byte FILTER_TYPE_NONE = 0; public static final byte FILTER_TYPE_SUB = 1; public static final byte FILTER_TYPE_UP = 2; public static final byte FILTER_TYPE_AVERAGE = 0; public static final byte FILTER_TYPE_PAETH = 4; } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/imageio/PngChunk.java0000644000175000017500000000322412122526606030251 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.utilities.imageio; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.zip.CRC32; import java.util.zip.CheckedOutputStream; class PngChunk extends DataOutputStream { final CRC32 crc; final ByteArrayOutputStream baos; PngChunk(int chunkType) throws IOException { this(chunkType, new ByteArrayOutputStream(), new CRC32()); } private PngChunk(int chunkType, ByteArrayOutputStream baos, CRC32 crc) throws IOException { super(new CheckedOutputStream(baos, crc)); this.crc = crc; this.baos = baos; writeInt(chunkType); } public void writeTo(DataOutputStream out) throws IOException { flush(); out.writeInt(baos.size() - 4); baos.writeTo(out); out.writeInt((int) crc.getValue()); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/utilities/imageio/Png4BitWriter.java0000644000175000017500000001536612122526606031212 0ustar paulliupaulliu/* * Copyright (c) 2007 Matthias Mann - www.matthiasmann.de * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * */ package mobac.utilities.imageio; import static mobac.utilities.imageio.PngConstants.COLOR_PALETTE; import static mobac.utilities.imageio.PngConstants.COMPRESSION_DEFLATE; import static mobac.utilities.imageio.PngConstants.FILTER_SET_1; import static mobac.utilities.imageio.PngConstants.FILTER_TYPE_NONE; import static mobac.utilities.imageio.PngConstants.IDAT; import static mobac.utilities.imageio.PngConstants.IEND; import static mobac.utilities.imageio.PngConstants.IHDR; import static mobac.utilities.imageio.PngConstants.INTERLACE_NONE; import static mobac.utilities.imageio.PngConstants.PLTE; import static mobac.utilities.imageio.PngConstants.SIGNATURE; import static mobac.utilities.imageio.PngConstants.TEXT; import java.awt.Color; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.IndexColorModel; import java.io.DataOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.zip.Deflater; import java.util.zip.DeflaterOutputStream; import mobac.utilities.MyMath; /** * 4 Bit PNG Writer *

* Writes a color png image with pallette containing 16 colors. Currently the image data is saved without any PNG * filtering. *

* * Bases on the PNGWriter written by Matthias Mann - www.matthiasmann.de * * @author r_x */ public class Png4BitWriter { public static void writeImage(File file, BufferedImage image) throws IOException { FileOutputStream out = new FileOutputStream(file); try { writeImage(out, image); } finally { out.close(); } } /** * * @param out * @param image * Must be an image with {@link ColorModel} {@link IndexColorModel} * @throws IOException */ public static void writeImage(OutputStream out, BufferedImage image) throws IOException { writeImage(out, image, Deflater.BEST_COMPRESSION); } /** * * @param out * @param image * Must be an image with {@link ColorModel} {@link IndexColorModel} * @param compression * deflater method used for compression - possible values are for example * {@link Deflater#BEST_COMPRESSION}, {@link Deflater#BEST_SPEED},{@link Deflater#NO_COMPRESSION} * @throws IOException */ public static void writeImage(OutputStream out, BufferedImage image, int compression) throws IOException { writeImage(out, image, compression, null); } /** * * @param out * Must be an image with {@link ColorModel} {@link IndexColorModel} * @param image * deflater method used for compression - possible values are for example * {@link Deflater#BEST_COMPRESSION}, {@link Deflater#BEST_SPEED},{@link Deflater#NO_COMPRESSION} * @param description * PNG comment text (meta info) * @throws IOException */ public static void writeImage(OutputStream out, BufferedImage image, int compression, String description) throws IOException { DataOutputStream dos = new DataOutputStream(out); int width = image.getWidth(); int height = image.getHeight(); ColorModel cm = image.getColorModel(); if (!(cm instanceof IndexColorModel)) throw new UnsupportedOperationException("Image format not compatible"); IndexColorModel palette = (IndexColorModel) cm; dos.write(SIGNATURE); PngChunk cIHDR = new PngChunk(IHDR); cIHDR.writeInt(width); cIHDR.writeInt(height); cIHDR.writeByte(4); // 4 bit per component cIHDR.writeByte(COLOR_PALETTE); cIHDR.writeByte(COMPRESSION_DEFLATE); cIHDR.writeByte(FILTER_SET_1); cIHDR.writeByte(INTERLACE_NONE); cIHDR.writeTo(dos); if (description != null) { PngChunk cTxT = new PngChunk(TEXT); cTxT.write("Description".getBytes()); cTxT.write(0); cTxT.write(description.getBytes()); cTxT.writeTo(dos); } PngChunk cPLTE = new PngChunk(PLTE); int paletteEntries = palette.getMapSize(); byte[] r = new byte[paletteEntries]; byte[] g = new byte[paletteEntries]; byte[] b = new byte[paletteEntries]; palette.getReds(r); palette.getGreens(g); palette.getBlues(b); int colorCount = Math.min(paletteEntries, 16); for (int i = 0; i < colorCount; i++) { cPLTE.writeByte(r[i]); cPLTE.writeByte(g[i]); cPLTE.writeByte(b[i]); } cPLTE.writeTo(dos); PngChunk cIDAT = new PngChunk(IDAT); DeflaterOutputStream dfos = new DeflaterOutputStream(cIDAT, new Deflater(compression)); int lineLen = MyMath.divCeil(width, 2); byte[] lineOut = new byte[lineLen]; int[] samples = null; for (int line = 0; line < height; line++) { dfos.write(FILTER_TYPE_NONE); // Get the samples for the next line - each byte is one sample/pixel samples = image.getRaster().getPixels(0, line, width, 1, samples); int sx = 0; int iMax = samples.length - 2; for (int i = 0; i < samples.length; i += 2) { // Now we are packing two samples of 4 bit into one byte int sample1 = samples[i]; int sample2 = (i <= iMax) ? samples[i + 1] : 0; int s1 = sample1 & 0x0F; int s2 = sample2 & 0x0F; if ((s1 != sample1) || (s2 != sample2)) throw new RuntimeException("sample has more than 4 bit!"); lineOut[sx++] = (byte) ((s1 << 4) | s2); } dfos.write(lineOut); } dfos.finish(); cIDAT.writeTo(dos); PngChunk cIEND = new PngChunk(IEND); cIEND.writeTo(dos); cIEND.close(); dos.flush(); } protected static void writeColor(DataOutputStream dos, Color c) throws IOException { dos.writeByte(c.getRed()); dos.writeByte(c.getGreen()); dos.writeByte(c.getBlue()); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/optional/0000755000175000017500000000000012127544350024071 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/optional/JavaAdvancedImaging.java0000644000175000017500000000425012127544350030540 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.optional; import java.awt.Color; import java.awt.Graphics; import java.awt.image.BufferedImage; import javax.media.jai.RenderedOp; import javax.media.jai.operator.ColorQuantizerDescriptor; /** * Centralizes all methods that require the optional Java Advanced Imaging * library. * */ public class JavaAdvancedImaging { // private static final Logger log = // Logger.getLogger(JavaAdvancedImaging.class); public static BufferedImage colorReduceMedianCut(BufferedImage image, int colorCount) { int pixelBits = image.getColorModel().getPixelSize(); if (pixelBits != 24) { /* * For preventing the javax.media.jai.util.ImagingException: All * factories fail for the operation "ColorQuantizer" we have to * create a "compatible" (e.g. TYPE_3BYTE_BGR) BufferedImage */ BufferedImage trueColorImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_3BYTE_BGR); Graphics g = trueColorImage.getGraphics(); g.drawImage(image, 0, 0, null); g.dispose(); image = trueColorImage; } RenderedOp ro = ColorQuantizerDescriptor.create(image, ColorQuantizerDescriptor.MEDIANCUT, // new Integer(colorCount), // Max number of colors null, null, new Integer(1), Integer.valueOf(1), null); return ro.getAsBufferedImage(); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/0000755000175000017500000000000012174511554023032 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/settings/0000755000175000017500000000000012171650636024674 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/settings/SettingsGUIPaper.java0000644000175000017500000005331312127544346030702 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.settings; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.io.File; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.ButtonGroup; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JFileChooser; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.JSpinner; import javax.swing.SpinnerNumberModel; import javax.swing.border.TitledBorder; import javax.swing.filechooser.FileFilter; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import mobac.gui.mapview.WgsGrid.WgsDensity; import mobac.program.model.PaperSize; import mobac.program.model.PaperSize.Format; import mobac.program.model.Settings; import mobac.program.model.SettingsPaperAtlas; import mobac.program.model.UnitSystem; import mobac.utilities.GBCTable; import mobac.utilities.I18nUtils; public class SettingsGUIPaper extends JPanel { private static final long serialVersionUID = -8265562215604604074L; private static void setModel(SpinnerNumberModel model, double min, double max, Double step) { model.setMaximum(max); model.setMinimum(min); model.setStepSize(step); double value = model.getNumber().doubleValue(); value = Math.max(Math.min(value, max), min); model.setValue(value); } private static void setEditor(JSpinner jSpinner, String pattern) { jSpinner.setEditor(new JSpinner.NumberEditor(jSpinner, pattern)); } private static JPanel createSection(TitledBorder border) { JPanel jPanel = new JPanel(new GridBagLayout()); jPanel.setBorder(border); return jPanel; } private final JButton jButtonDefaults = new JButton(); private final JButton jButtonExport = new JButton(); private final JButton jButtonImport = new JButton(); private final JCheckBox jCheckBoxCompass = new JCheckBox(); private final JCheckBox jCheckBoxLandscape = new JCheckBox(); private final JCheckBox jCheckBoxPageNumbers = new JCheckBox("", true); private final JCheckBox jCheckBoxScaleBar = new JCheckBox(); private final JCheckBox jCheckBoxWgsGrid = new JCheckBox("", true); private final JFileChooser jFileChooser = new JFileChooser(); private final TitledBorder titledBorderActions = SettingsGUI.createSectionBorder(""); private final TitledBorder titledBorderAdditions = SettingsGUI.createSectionBorder(""); private final TitledBorder titledBorderAdvanced = SettingsGUI.createSectionBorder(""); private final TitledBorder titledBorderMargins = SettingsGUI.createSectionBorder(""); private final TitledBorder titledBorderSize = SettingsGUI.createSectionBorder(""); private final JPanel jPanelActions = createSection(titledBorderActions), jPanelAdditions = createSection(titledBorderAdditions), jPanelAdvanced = createSection(titledBorderAdvanced), jPanelMargins = createSection(titledBorderMargins), jPanelSize = createSection(titledBorderSize); private final JComboBox jComboBoxFormat = new JComboBox(Format.values()); private final JComboBox jComboBoxWgsDensity = new JComboBox(WgsDensity.values()); private final JRadioButton jRadioButtonCustom = new JRadioButton("", true); private final JRadioButton jRadioButtonDefault = new JRadioButton("", true); private final JRadioButton jRadioButtonSelection = new JRadioButton("", true); private final SpinnerNumberModel modelCompression = new SpinnerNumberModel(SettingsPaperAtlas.COMPRESSION_DEFAULT, SettingsPaperAtlas.COMPRESSION_MIN, SettingsPaperAtlas.COMPRESSION_MAX, 1); private final SpinnerNumberModel modelCrop = new SpinnerNumberModel(SettingsPaperAtlas.CROP_DEFAULT, SettingsPaperAtlas.CROP_MIN, SettingsPaperAtlas.CROP_MAX, 1), modelDpi = new SpinnerNumberModel( SettingsPaperAtlas.DPI_DEFAULT, SettingsPaperAtlas.DPI_MIN, SettingsPaperAtlas.DPI_MAX, 1); private final SpinnerNumberModel modelHeight = new SpinnerNumberModel(0.0, 0.0, 0.0, 1.0); private final SpinnerNumberModel modelWidth = new SpinnerNumberModel(0.0, 0.0, 0.0, 1.0); private final SpinnerNumberModel modelMarginBottom = new SpinnerNumberModel(0.0, 0.0, 0.0, 1.0); private final SpinnerNumberModel modelMarginLeft = new SpinnerNumberModel(0.0, 0.0, 0.0, 1.0); private final SpinnerNumberModel modelMarginRight = new SpinnerNumberModel(0.0, 0.0, 0.0, 1.0); private final SpinnerNumberModel modelMarginTop = new SpinnerNumberModel(0.0, 0.0, 0.0, 1.0); private final SpinnerNumberModel modelOverlap = new SpinnerNumberModel(0.0, 0.0, 0.0, 1.0); private final JSpinner jSpinnerDpi = new JSpinner(modelDpi), jSpinnerWidth = new JSpinner(modelWidth), jSpinnerHeight = new JSpinner(modelHeight), jSpinnerMarginTop = new JSpinner(modelMarginTop), jSpinnerMarginLeft = new JSpinner(modelMarginLeft), jSpinnerMarginBottom = new JSpinner(modelMarginBottom), jSpinnerMarginRight = new JSpinner(modelMarginRight), jSpinnerOverlap = new JSpinner(modelOverlap), jSpinnerCrop = new JSpinner(modelCrop), jSpinnerCompression = new JSpinner(modelCompression); private final JLabel jLabelCompression = new JLabel(), jLabelDpi = new JLabel(), jLabelWidth = new JLabel(), jLabelHeight = new JLabel(), jLabelMarginTop = new JLabel(), jLabelMarginLeft = new JLabel(), jLabelMarginBottom = new JLabel(), jLabelMarginRight = new JLabel(), jLabelOverlap = new JLabel(), jLabelCrop = new JLabel(); private String importError, exportError, errorReason, errorTitle, xmlFileFilter; private UnitSystem unitSystem; public SettingsGUIPaper() { super(new GridBagLayout()); jSpinnerCrop.setEditor(new JSpinner.NumberEditor(jSpinnerCrop, "#0'%'")); setUnitSystem(UnitSystem.Metric); i18n(); jFileChooser.setFileFilter(new FileFilter() { @Override public boolean accept(File f) { return f.isDirectory() || f.getName().endsWith(".xml"); } @Override public String getDescription() { return xmlFileFilter; } }); jButtonImport.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { importFromXml(); } }); jButtonExport.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { exportToXml(); } }); jButtonDefaults.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { resetToDefaults(); } }); jComboBoxFormat.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Format format = (Format) jComboBoxFormat.getSelectedItem(); double width = unitSystem.pointsToUnits(format.width); double height = unitSystem.pointsToUnits(format.height); modelWidth.setValue(width); modelHeight.setValue(height); } }); jCheckBoxWgsGrid.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { boolean enabled = e.getStateChange() != ItemEvent.DESELECTED; jComboBoxWgsDensity.setEnabled(enabled); } }); jRadioButtonCustom.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { boolean enabled = e.getStateChange() != ItemEvent.DESELECTED; jLabelWidth.setEnabled(enabled); jLabelHeight.setEnabled(enabled); jSpinnerWidth.setEnabled(enabled); jSpinnerHeight.setEnabled(enabled); } }); jRadioButtonDefault.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { boolean enabled = e.getStateChange() != ItemEvent.DESELECTED; jComboBoxFormat.setEnabled(enabled); jCheckBoxLandscape.setEnabled(enabled); } }); ButtonGroup buttonGroup = new ButtonGroup(); buttonGroup.add(jRadioButtonSelection); buttonGroup.add(jRadioButtonDefault); buttonGroup.add(jRadioButtonCustom); GBCTable gbc = new GBCTable(); jPanelSize.add(jRadioButtonDefault, gbc.begin()); jPanelSize.add(jRadioButtonCustom, gbc.incY()); jPanelSize.add(jRadioButtonSelection, gbc.incY()); jPanelSize.add(jComboBoxFormat, gbc.incX()); jPanelSize.add(jLabelWidth, gbc.incY()); jPanelSize.add(jLabelHeight, gbc.incY()); jPanelSize.add(jCheckBoxLandscape, gbc.incX()); jPanelSize.add(jSpinnerWidth, gbc.incY()); jPanelSize.add(jSpinnerHeight, gbc.incY()); jPanelSize.add(Box.createGlue(), gbc.incX().gridheight(3).fill()); jPanelMargins.add(jLabelMarginTop, gbc.begin()); jPanelMargins.add(jLabelMarginBottom, gbc.incY()); jPanelMargins.add(jSpinnerMarginTop, gbc.incX()); jPanelMargins.add(jSpinnerMarginBottom, gbc.incY()); jPanelMargins.add(jLabelMarginLeft, gbc.incX()); jPanelMargins.add(jLabelMarginRight, gbc.incY()); jPanelMargins.add(jSpinnerMarginLeft, gbc.incX()); jPanelMargins.add(jSpinnerMarginRight, gbc.incY()); jPanelMargins.add(Box.createHorizontalGlue(), gbc.incX().fillH()); jPanelAdditions.add(jCheckBoxWgsGrid, gbc.begin()); jPanelAdditions.add(jCheckBoxPageNumbers, gbc.incY().gridwidth(2)); jPanelAdditions.add(jCheckBoxScaleBar, gbc.incY()); jPanelAdditions.add(jComboBoxWgsDensity, gbc.incX()); gbc.incY(); jPanelAdditions.add(jCheckBoxCompass, gbc.incY()); jPanelAdditions.add(Box.createHorizontalGlue(), gbc.incX().fillH()); jPanelAdvanced.add(jLabelDpi, gbc.begin()); jPanelAdvanced.add(jLabelCompression, gbc.incY()); jPanelAdvanced.add(jSpinnerDpi, gbc.incX()); jPanelAdvanced.add(jSpinnerCompression, gbc.incY()); jPanelAdvanced.add(jLabelOverlap, gbc.incX()); jPanelAdvanced.add(jLabelCrop, gbc.incY()); jPanelAdvanced.add(jSpinnerOverlap, gbc.incX()); jPanelAdvanced.add(jSpinnerCrop, gbc.incY()); jPanelAdvanced.add(Box.createHorizontalGlue(), gbc.incX().fillH()); jPanelActions.add(jButtonImport, gbc.begin()); jPanelActions.add(jButtonExport, gbc.incX()); jPanelActions.add(jButtonDefaults, gbc.incX()); jPanelActions.add(Box.createHorizontalGlue(), gbc.incX().fillH()); gbc = new GBCTable(0); setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); add(jPanelSize, gbc.begin()); add(jPanelMargins, gbc.incY()); add(jPanelAdditions, gbc.incX().fillH()); add(jPanelAdvanced, gbc.incY().fillH()); add(jPanelActions, gbc.begin(1, 3).gridwidth(2).fillH()); add(Box.createGlue(), gbc.incY().gridwidth(2).fill()); } private void importFromXml() { int state = jFileChooser.showOpenDialog(SettingsGUIPaper.this); if (state == JFileChooser.APPROVE_OPTION) { File file = jFileChooser.getSelectedFile(); JAXBContext context; try { context = JAXBContext.newInstance(SettingsPaperAtlas.class); Unmarshaller um = context.createUnmarshaller(); SettingsPaperAtlas s = (SettingsPaperAtlas) um.unmarshal(file); loadSettings(s); } catch (JAXBException ex) { String text = importError + file.getName() + "\n" + errorReason + ex.getMessage(); JOptionPane.showMessageDialog(SettingsGUIPaper.this, text, errorTitle, JOptionPane.ERROR_MESSAGE); } } } private void exportToXml() { int state = jFileChooser.showSaveDialog(SettingsGUIPaper.this); if (state == JFileChooser.APPROVE_OPTION) { File file = jFileChooser.getSelectedFile(); JAXBContext context; try { context = JAXBContext.newInstance(SettingsPaperAtlas.class); Marshaller m = context.createMarshaller(); SettingsPaperAtlas s = new SettingsPaperAtlas(); applySettings(s); m.marshal(s, file); } catch (JAXBException ex) { String text = exportError + file.getName() + "\n" + errorReason + ex.getMessage(); JOptionPane.showMessageDialog(SettingsGUIPaper.this, text, errorTitle, JOptionPane.ERROR_MESSAGE); } } } private void resetToDefaults() { loadSettings(new SettingsPaperAtlas()); } private void i18n() { setName(I18nUtils.localizedStringForKey("set_paper_title")); titledBorderActions.setTitle(I18nUtils.localizedStringForKey("set_paper_actions")); titledBorderAdditions.setTitle(I18nUtils.localizedStringForKey("set_paper_additions")); titledBorderAdvanced.setTitle(I18nUtils.localizedStringForKey("set_paper_advanced")); titledBorderMargins.setTitle(I18nUtils.localizedStringForKey("set_paper_margins")); titledBorderSize.setTitle(I18nUtils.localizedStringForKey("set_paper_size")); jComboBoxFormat.setToolTipText(I18nUtils.localizedStringForKey("set_paper_size_default_format_tips")); jComboBoxWgsDensity.setToolTipText(I18nUtils.localizedStringForKey("set_paper_wgs_grid_density_tips")); jRadioButtonSelection.setText(I18nUtils.localizedStringForKey("set_paper_size_selection")); jRadioButtonSelection.setToolTipText(I18nUtils.localizedStringForKey("set_paper_size_selection_tips")); jRadioButtonDefault.setText(I18nUtils.localizedStringForKey("set_paper_size_default")); jRadioButtonDefault.setToolTipText(I18nUtils.localizedStringForKey("set_paper_size_default_tips")); jRadioButtonCustom.setText(I18nUtils.localizedStringForKey("set_paper_size_custom")); jRadioButtonCustom.setToolTipText(I18nUtils.localizedStringForKey("set_paper_size_custom_tips")); jCheckBoxScaleBar.setText(I18nUtils.localizedStringForKey("set_paper_scale_bar")); jCheckBoxScaleBar.setToolTipText(I18nUtils.localizedStringForKey("set_paper_scale_tips")); jCheckBoxCompass.setText(I18nUtils.localizedStringForKey("set_paper_compass")); jCheckBoxCompass.setToolTipText(I18nUtils.localizedStringForKey("set_paper_compass_tips")); jCheckBoxLandscape.setText(I18nUtils.localizedStringForKey("set_paper_size_default_landscape")); jCheckBoxLandscape.setToolTipText(I18nUtils.localizedStringForKey("set_paper_size_default_landscape_tips")); jCheckBoxWgsGrid.setText(I18nUtils.localizedStringForKey(I18nUtils.localizedStringForKey("set_paper_wgs_grid"))); jCheckBoxWgsGrid.setToolTipText(I18nUtils.localizedStringForKey("set_paper_wgs_grid_tips")); jCheckBoxPageNumbers.setText(I18nUtils.localizedStringForKey("set_paper_paper_nubmer")); jCheckBoxPageNumbers.setToolTipText(I18nUtils.localizedStringForKey("set_paper_paper_nubmer_tips")); jLabelCompression.setText(I18nUtils.localizedStringForKey("set_paper_advanced_compression")); String compression = I18nUtils.localizedStringForKey("set_paper_advanced_compression_tips"); jLabelCompression.setToolTipText(compression); jSpinnerCompression.setToolTipText(compression); jLabelDpi.setText(I18nUtils.localizedStringForKey("set_paper_advanced_dpi")); String dpi = I18nUtils.localizedStringForKey("set_paper_advanced_dpi_tips"); jLabelDpi.setToolTipText(dpi); jSpinnerDpi.setToolTipText(dpi); jLabelWidth.setText(I18nUtils.localizedStringForKey("set_paper_size_custom_width")); String width = I18nUtils.localizedStringForKey("set_paper_size_custom_width_tips"); jLabelWidth.setToolTipText(width); jSpinnerWidth.setToolTipText(width); jLabelHeight.setText(I18nUtils.localizedStringForKey("set_paper_size_custom_height")); String height = I18nUtils.localizedStringForKey("set_paper_size_custom_height_tips"); jLabelHeight.setToolTipText(height); jSpinnerHeight.setToolTipText(height); String margin = I18nUtils.localizedStringForKey("set_paper_margins_tips"); jLabelMarginTop.setText(I18nUtils.localizedStringForKey("set_paper_margins_top")); jLabelMarginTop.setToolTipText(margin); jSpinnerMarginTop.setToolTipText(margin); jLabelMarginLeft.setText(I18nUtils.localizedStringForKey("set_paper_margins_left")); jLabelMarginLeft.setToolTipText(margin); jSpinnerMarginLeft.setToolTipText(margin); jLabelMarginBottom.setText(I18nUtils.localizedStringForKey("set_paper_margins_bottom")); jLabelMarginBottom.setToolTipText(margin); jSpinnerMarginBottom.setToolTipText(margin); jLabelMarginRight.setText(I18nUtils.localizedStringForKey("set_paper_margins_right")); jLabelMarginRight.setToolTipText(margin); jSpinnerMarginRight.setToolTipText(margin); jLabelOverlap.setText(I18nUtils.localizedStringForKey("set_paper_advanced_overlap")); String overlap = I18nUtils.localizedStringForKey("set_paper_advanced_overlap_tips"); jLabelOverlap.setToolTipText(overlap); jSpinnerOverlap.setToolTipText(overlap); jLabelCrop.setText(I18nUtils.localizedStringForKey("set_paper_advanced_crop")); String crop = I18nUtils.localizedStringForKey("set_paper_advanced_crop_tips"); jLabelCrop.setToolTipText(crop); jSpinnerCrop.setToolTipText(crop); jButtonImport.setText(I18nUtils.localizedStringForKey("set_paper_actions_import_xml")); jButtonImport.setToolTipText(I18nUtils.localizedStringForKey("set_paper_actions_import_xml_tip")); jButtonExport.setText(I18nUtils.localizedStringForKey("set_paper_actions_export_xml")); jButtonExport.setToolTipText(I18nUtils.localizedStringForKey("set_paper_actions_export_xml_tip")); jButtonDefaults.setText(I18nUtils.localizedStringForKey("set_paper_actions_restore_default")); jButtonDefaults.setToolTipText(I18nUtils.localizedStringForKey("set_paper_actions_restore_default_tips")); importError = I18nUtils.localizedStringForKey("set_paper_actions_error_import"); exportError = I18nUtils.localizedStringForKey("set_paper_actions_error_export"); errorReason = I18nUtils.localizedStringForKey("set_paper_actions_error_reason"); errorTitle = I18nUtils.localizedStringForKey("set_paper_actions_error_title"); xmlFileFilter = I18nUtils.localizedStringForKey("set_paper_actions_xml_filter"); } private void setUnitSystem(UnitSystem unitSystem) { if (unitSystem.equals(this.unitSystem)) return; this.unitSystem = unitSystem; Double step = 0.1d; double min, max; min = unitSystem.pointsToUnits(SettingsPaperAtlas.MARGIN_MIN); max = unitSystem.pointsToUnits(SettingsPaperAtlas.MARGIN_MAX); setModel(modelMarginBottom, min, max, step); setModel(modelMarginLeft, min, max, step); setModel(modelMarginRight, min, max, step); setModel(modelMarginTop, min, max, step); min = unitSystem.pointsToUnits(SettingsPaperAtlas.PAPER_SIZE_MIN); max = unitSystem.pointsToUnits(SettingsPaperAtlas.PAPER_SIZE_MAX); setModel(modelWidth, min, max, step); setModel(modelHeight, min, max, step); min = unitSystem.pointsToUnits(SettingsPaperAtlas.OVERLAP_MIN); max = unitSystem.pointsToUnits(SettingsPaperAtlas.OVERLAP_MAX); setModel(modelOverlap, min, max, step); String pattern = "#0.00 " + unitSystem.unitTiny; setEditor(jSpinnerWidth, pattern); setEditor(jSpinnerHeight, pattern); setEditor(jSpinnerMarginTop, pattern); setEditor(jSpinnerMarginLeft, pattern); setEditor(jSpinnerMarginBottom, pattern); setEditor(jSpinnerMarginRight, pattern); setEditor(jSpinnerOverlap, pattern); } private PaperSize getPaperSize() { if (jRadioButtonDefault.isSelected()) { Format format = (Format) jComboBoxFormat.getSelectedItem(); boolean landscape = jCheckBoxLandscape.isSelected(); return new PaperSize(format, landscape); } if (jRadioButtonCustom.isSelected()) { double width = modelWidth.getNumber().doubleValue(); double height = modelHeight.getNumber().doubleValue(); width = unitSystem.unitsToPoints(width); height = unitSystem.unitsToPoints(height); return new PaperSize(width, height); } return null; } private void setPaperSize(PaperSize paperSize) { if (paperSize == null) { jRadioButtonSelection.setSelected(true); return; } if (paperSize.format != null) { jRadioButtonDefault.setSelected(true); jComboBoxFormat.setSelectedIndex(paperSize.format.ordinal()); jCheckBoxLandscape.setSelected(paperSize.landscape); } else { jRadioButtonCustom.setSelected(true); } } public void loadSettings(Settings s) { setUnitSystem(s.unitSystem); loadSettings(s.paperAtlas); } public void loadSettings(SettingsPaperAtlas s) { setPaperSize(s.paperSize); modelMarginTop.setValue(unitSystem.pointsToUnits(s.marginTop)); modelMarginLeft.setValue(unitSystem.pointsToUnits(s.marginLeft)); modelMarginBottom.setValue(unitSystem.pointsToUnits(s.marginBottom)); modelMarginRight.setValue(unitSystem.pointsToUnits(s.marginRight)); jCheckBoxScaleBar.setSelected(s.scaleBar); jCheckBoxCompass.setSelected(s.compass); jComboBoxWgsDensity.setSelectedItem(s.wgsDensity); jCheckBoxWgsGrid.setSelected(s.wgsEnabled); jCheckBoxPageNumbers.setSelected(s.pageNumbers); modelCrop.setValue(s.crop); modelOverlap.setValue(unitSystem.pointsToUnits(s.overlap)); modelCompression.setValue(s.compression); modelDpi.setValue(s.dpi); } public void applySettings(Settings s) { applySettings(s.paperAtlas); } public void applySettings(SettingsPaperAtlas s) { s.paperSize = getPaperSize(); s.marginTop = unitSystem.unitsToPoints(modelMarginTop.getNumber().doubleValue()); s.marginLeft = unitSystem.unitsToPoints(modelMarginLeft.getNumber().doubleValue()); s.marginBottom = unitSystem.unitsToPoints(modelMarginBottom.getNumber().doubleValue()); s.marginRight = unitSystem.unitsToPoints(modelMarginRight.getNumber().doubleValue()); s.scaleBar = jCheckBoxScaleBar.isSelected(); s.compass = jCheckBoxCompass.isSelected(); s.wgsDensity = (WgsDensity) jComboBoxWgsDensity.getSelectedItem(); s.wgsEnabled = jCheckBoxWgsGrid.isSelected(); s.pageNumbers = jCheckBoxPageNumbers.isSelected(); s.crop = modelCrop.getNumber().intValue(); s.overlap = unitSystem.unitsToPoints(modelOverlap.getNumber().doubleValue()); s.compression = modelCompression.getNumber().intValue(); s.dpi = modelDpi.getNumber().intValue(); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/settings/SettingsGUITileStore.java0000644000175000017500000002376512127544346031555 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.settings; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.LinkedList; import java.util.List; import javax.swing.BorderFactory; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSeparator; import javax.swing.SwingUtilities; import javax.swing.border.BevelBorder; import mobac.mapsources.MapSourcesManager; import mobac.program.interfaces.MapSource; import mobac.program.tilestore.TileStore; import mobac.program.tilestore.TileStoreInfo; import mobac.program.tilestore.berkeleydb.DelayedInterruptThread; import mobac.utilities.I18nUtils; import mobac.utilities.Utilities; public class SettingsGUITileStore extends JPanel { public final JCheckBox tileStoreEnabled; private final JPanel tileStoreInfoPanel; private List tileStoreInfoList = new LinkedList(); private JLabel totalTileCountLabel; private JLabel totalTileSizeLabel; protected DelayedInterruptThread tileStoreAsyncThread = null; public SettingsGUITileStore(SettingsGUI gui) { super(); gui.addTab(I18nUtils.localizedStringForKey("set_tile_store_title"), this); tileStoreEnabled = new JCheckBox(I18nUtils.localizedStringForKey("set_tile_store_enable_checkbox")); JPanel tileStorePanel = new JPanel(new BorderLayout()); tileStorePanel.setBorder(SettingsGUI.createSectionBorder(I18nUtils.localizedStringForKey("set_tile_store_settings"))); tileStorePanel.add(tileStoreEnabled, BorderLayout.CENTER); tileStoreInfoPanel = new JPanel(new GridBagLayout()); // tileStoreInfoPanel.setBorder(createSectionBorder("Information")); prepareTileStoreInfoPanel(); setLayout(new BorderLayout()); add(tileStorePanel, BorderLayout.NORTH); JScrollPane scrollPane = new JScrollPane(tileStoreInfoPanel, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); tileStoreInfoPanel.setMinimumSize(new Dimension(200, 300)); // scrollPane.setMinimumSize(new Dimension(100, 100)); scrollPane.setPreferredSize(new Dimension(520, 100)); scrollPane.setBorder(SettingsGUI.createSectionBorder(I18nUtils.localizedStringForKey("set_tile_store_information"))); add(scrollPane, BorderLayout.CENTER); } /** * * @param updateStoreName * name of the tile store to update or null in case of all tile stores to be updated */ private void updateTileStoreInfoPanel(String updateStoreName) { try { TileStore tileStore = TileStore.getInstance(); long totalTileCount = 0; long totalTileSize = 0; for (final TileSourceInfoComponents info : tileStoreInfoList) { String storeName = info.name; Utilities.checkForInterruption(); int count; long size; if (updateStoreName == null || info.name.equals(updateStoreName)) { TileStoreInfo tsi = tileStore.getStoreInfo(storeName); count = tsi.getTileCount(); size = tsi.getStoreSize(); info.count = count; info.size = size; final String mapTileCountText = (count < 0) ? "??" : Integer.toString(count); final String mapTileSizeText = Utilities.formatBytes(size); SwingUtilities.invokeLater(new Runnable() { public void run() { info.countLabel.setText("" + mapTileCountText + ""); info.sizeLabel.setText("" + mapTileSizeText + ""); } }); } else { count = info.count; size = info.size; } totalTileCount += count; totalTileSize += size; } final String totalTileCountText = "" + Long.toString(totalTileCount) + ""; final String totalTileSizeText = "" + Utilities.formatBytes(totalTileSize) + ""; SwingUtilities.invokeLater(new Runnable() { public void run() { totalTileCountLabel.setText(totalTileCountText); totalTileSizeLabel.setText(totalTileSizeText); } }); } catch (InterruptedException e) { SettingsGUI.log.debug("Tile store information retrieval was canceled"); } } synchronized void updateTileStoreInfoPanelAsync(final String storeName) { if (tileStoreAsyncThread != null) return; // An update is currently running tileStoreAsyncThread = new DelayedInterruptThread("TileStoreInfoRetriever") { @Override public void run() { if (storeName == null) SettingsGUI.log.debug("Updating tilestore information in background"); else SettingsGUI.log.debug("Updating tilestore information for \"" + storeName + "\" in background"); updateTileStoreInfoPanel(storeName); SettingsGUI.log.debug("Updating tilestore information finished"); tileStoreAsyncThread = null; } }; tileStoreAsyncThread.start(); } private void prepareTileStoreInfoPanel() { final GridBagConstraints gbc_mapSource = new GridBagConstraints(); gbc_mapSource.insets = new Insets(5, 10, 5, 10); gbc_mapSource.anchor = GridBagConstraints.WEST; final GridBagConstraints gbc_mapTiles = new GridBagConstraints(); gbc_mapTiles.insets = gbc_mapSource.insets; gbc_mapTiles.anchor = GridBagConstraints.EAST; final GridBagConstraints gbc_eol = new GridBagConstraints(); gbc_eol.gridwidth = GridBagConstraints.REMAINDER; TileStore tileStore = TileStore.getInstance(); MapSourcesManager mapSourcesManager = MapSourcesManager.getInstance(); tileStoreInfoPanel.add(new JLabel(I18nUtils.localizedStringForKey("set_tile_store_info_mapsrc")), gbc_mapSource); tileStoreInfoPanel.add(new JLabel(I18nUtils.localizedStringForKey("set_tile_store_info_tiles")), gbc_mapTiles); tileStoreInfoPanel.add(new JLabel(I18nUtils.localizedStringForKey("set_tile_store_info_size")), gbc_eol); ImageIcon trash = Utilities.loadResourceImageIcon("trash.png"); for (String name : tileStore.getAllStoreNames()) { String mapTileCountText = " ? "; String mapTileSizeText = " ? "; MapSource mapSource = mapSourcesManager.getSourceByName(name); final JLabel mapSourceNameLabel; if (mapSource != null) mapSourceNameLabel = new JLabel(name); else mapSourceNameLabel = new JLabel(name + I18nUtils.localizedStringForKey("set_tile_store_info_disabled_subfix")); final JLabel mapTileCountLabel = new JLabel(mapTileCountText); final JLabel mapTileSizeLabel = new JLabel(mapTileSizeText); final JButton deleteButton = new JButton(trash); TileSourceInfoComponents info = new TileSourceInfoComponents(); info.name = name; info.countLabel = mapTileCountLabel; info.sizeLabel = mapTileSizeLabel; tileStoreInfoList.add(info); deleteButton.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3)); deleteButton.setToolTipText(String.format(I18nUtils.localizedStringForKey("set_tile_store_info_delete_tips"), name)); deleteButton.addActionListener(new ClearTileCacheAction(name)); tileStoreInfoPanel.add(mapSourceNameLabel, gbc_mapSource); tileStoreInfoPanel.add(mapTileCountLabel, gbc_mapTiles); tileStoreInfoPanel.add(mapTileSizeLabel, gbc_mapTiles); tileStoreInfoPanel.add(deleteButton, gbc_eol); } JSeparator hr = new JSeparator(JSeparator.HORIZONTAL); hr.setBorder(BorderFactory.createEtchedBorder(BevelBorder.LOWERED)); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.HORIZONTAL; tileStoreInfoPanel.add(hr, gbc); JLabel totalMapLabel = new JLabel(I18nUtils.localizedStringForKey("set_tile_store_info_total")); totalTileCountLabel = new JLabel("??"); totalTileSizeLabel = new JLabel("??"); tileStoreInfoPanel.add(totalMapLabel, gbc_mapSource); tileStoreInfoPanel.add(totalTileCountLabel, gbc_mapTiles); tileStoreInfoPanel.add(totalTileSizeLabel, gbc_mapTiles); } public void stopThread() { Thread t = tileStoreAsyncThread; if (t != null) t.interrupt(); } private static class TileSourceInfoComponents { JLabel sizeLabel; JLabel countLabel; String name; int count = -1; long size = 0; } private class ClearTileCacheAction implements ActionListener { String storeName; public ClearTileCacheAction(String storeName) { this.storeName = storeName; } public void actionPerformed(ActionEvent e) { final JButton b = (JButton) e.getSource(); b.setEnabled(false); b.setToolTipText(I18nUtils.localizedStringForKey("set_tile_store_info_deleteing_tips")); Thread t = new DelayedInterruptThread("TileStore_" + storeName + "_DeleteThread") { @Override public void run() { try { TileStore ts = TileStore.getInstance(); ts.clearStore(storeName); SettingsGUITileStore.this.updateTileStoreInfoPanelAsync(storeName); SettingsGUITileStore.this.repaint(); } catch (Exception e) { SettingsGUI.log.error("An error occured while cleaning tile cache: ", e); } } }; t.start(); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/settings/SettingsGUIWgsGrid.java0000644000175000017500000001265112127544346031201 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.settings; import java.awt.Color; import java.awt.Dimension; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JColorChooser; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JSpinner; import javax.swing.SpinnerNumberModel; import mobac.gui.dialogs.FontChooser; import mobac.program.model.Settings; import mobac.program.model.SettingsWgsGrid; import mobac.utilities.GBCTable; import mobac.utilities.I18nUtils; public class SettingsGUIWgsGrid extends JPanel { private static final long serialVersionUID = -3067609813682787669L; private final FontChooser fontChooser = new FontChooser(); private final JButton jButtonFont = new JButton(FontChooser.encodeFont(FontChooser.DEFAULT)); private final JCheckBox jCheckBoxCompressLabels = new JCheckBox(); private final JPanel jPanelColor = new JPanel(); private final SpinnerNumberModel modelWidth = new SpinnerNumberModel(0.5d, 0.5d, 5.0d, 0.5d); private final JSpinner jSpinnerWidth = new JSpinner(modelWidth); private JLabel jLabelColor = new JLabel(), jLabelFont = new JLabel(), jLabelWidth = new JLabel(); private String title; public SettingsGUIWgsGrid() { super(new GridBagLayout()); i18n(); jButtonFont.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { fontChooser.show(); if (fontChooser.wasCanceled()) { return; } String text = FontChooser.encodeFont(fontChooser.getFont()); jButtonFont.setText(text); } }); jPanelColor.setPreferredSize(new Dimension(64, 18)); jPanelColor.setOpaque(true); jPanelColor.setBorder(BorderFactory.createEtchedBorder()); jPanelColor.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { Color color = jPanelColor.getBackground(); color = JColorChooser.showDialog(jPanelColor, title, color); if (color != null) { jPanelColor.setBackground(color); } } public void mouseEntered(MouseEvent e) { jPanelColor.setBorder(BorderFactory.createRaisedBevelBorder()); } public void mouseExited(MouseEvent e) { jPanelColor.setBorder(BorderFactory.createEtchedBorder()); } }); GBCTable gbc = new GBCTable(); add(jLabelColor, gbc.begin()); add(jLabelWidth, gbc.incY()); add(jPanelColor, gbc.incX()); add(jSpinnerWidth, gbc.incY()); add(jLabelFont, gbc.incX()); add(jCheckBoxCompressLabels, gbc.incY().gridwidth(3)); add(jButtonFont, gbc.incX()); add(Box.createHorizontalGlue(), gbc.incX().fillH()); } public void i18n() { jCheckBoxCompressLabels.setText(I18nUtils.localizedStringForKey("set_display_grid_compress")); jCheckBoxCompressLabels.setToolTipText(I18nUtils.localizedStringForKey("set_display_grid_compress_tips")); setBorder(SettingsGUI.createSectionBorder(I18nUtils.localizedStringForKey("set_display_grid"))); title = I18nUtils.localizedStringForKey("set_display_grid_title");//TODO: recovery jLabelWidth.setText(I18nUtils.localizedStringForKey("set_display_grid_width")); String width = I18nUtils.localizedStringForKey("set_display_grid_width_tips"); jLabelWidth.setToolTipText(width); jSpinnerWidth.setToolTipText(width); jLabelColor.setText(I18nUtils.localizedStringForKey("set_display_grid_color")); String color = I18nUtils.localizedStringForKey("set_display_grid_color_tips"); jLabelColor.setToolTipText(color); jPanelColor.setToolTipText(color); jLabelFont.setText(I18nUtils.localizedStringForKey("set_display_grid_font")); String font = I18nUtils.localizedStringForKey("set_display_grid_font_tips"); jLabelFont.setToolTipText(font); jButtonFont.setToolTipText(font); } public void applySettings(Settings s) { applySettings(s.wgsGrid); } public void applySettings(SettingsWgsGrid s) { s.compressLabels = jCheckBoxCompressLabels.isSelected(); s.font = fontChooser.getFont(); s.color = jPanelColor.getBackground(); s.width = modelWidth.getNumber().floatValue(); } public void loadSettings(Settings s) { loadSettings(s.wgsGrid); } public void loadSettings(SettingsWgsGrid s) { jCheckBoxCompressLabels.setSelected(s.compressLabels); fontChooser.setFont(s.font); jButtonFont.setText(FontChooser.encodeFont(s.font)); jPanelColor.setBackground(s.color); modelWidth.setValue((double) s.width); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/settings/SettingsGUI.java0000644000175000017500000010702612171650636027712 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.settings; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.File; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Arrays; import java.util.Locale; import java.util.Vector; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSpinner; import javax.swing.JTabbedPane; import javax.swing.JTextField; import javax.swing.KeyStroke; import javax.swing.SpinnerNumberModel; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.border.Border; import javax.swing.border.CompoundBorder; import javax.swing.border.EmptyBorder; import javax.swing.border.EtchedBorder; import javax.swing.border.TitledBorder; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.xml.bind.JAXBException; import mobac.StartMOBAC; import mobac.exceptions.UpdateFailedException; import mobac.gui.MainGUI; import mobac.gui.actions.OpenInWebbrowser; import mobac.gui.components.JDirectoryChooser; import mobac.gui.components.JMapSizeCombo; import mobac.gui.components.JTimeSlider; import mobac.mapsources.DefaultMapSourcesManager; import mobac.mapsources.MapSourcesManager; import mobac.mapsources.loader.MapPackManager; import mobac.program.Logging; import mobac.program.ProgramInfo; import mobac.program.interfaces.MapSource; import mobac.program.model.MapSourcesListModel; import mobac.program.model.ProxyType; import mobac.program.model.Settings; import mobac.program.model.UnitSystem; import mobac.program.tilestore.TileStore; import mobac.utilities.GBC; import mobac.utilities.GUIExceptionHandler; import mobac.utilities.I18nUtils; import mobac.utilities.Utilities; import org.apache.log4j.Level; import org.apache.log4j.Logger; public class SettingsGUI extends JDialog { private static final long serialVersionUID = -5227934684609357198L; public static Logger log = Logger.getLogger(SettingsGUI.class); private static final Integer[] THREADCOUNT_LIST = { 1, 2, 4, 6 }; private static final long MBIT1 = 1000000 / 8; private enum Bandwidth { UNLIMITED(I18nUtils.localizedStringForKey("set_net_bandwidth_unlimited"), 0), // MBit1("1 MBit", MBIT1), // MBit5("5 MBit", MBIT1 * 5), // MBit10("10 MBit", MBIT1 * 10), // MBit15("15 MBit", MBIT1 * 15), // MBit20("20 MBit", MBIT1 * 20); public final long limit; public final String description; private Bandwidth(String description, long limit) { this.description = description; this.limit = limit; } @Override public String toString() { return description; } }; private enum SupportLocale { SupportLocaleEn(new Locale("en"), "English"), // default SupportLocaleFrFR(new Locale("fr", "FR"), "Français"), // French SupportLocaleJaJP(new Locale("ja", "JP"), "日本語"), // Japanese SupportLocaleZhCN(new Locale("zh", "CN"), "简体中文"), // Chinese (simplified) SupportLocaleZhTW(new Locale("zh", "TW"), "繁體中文"); // Chinese (Taiwan) private final Locale locale; private final String displayName; private SupportLocale(Locale locale, String displayName) { this.locale = locale; this.displayName = displayName; } public static SupportLocale localeOf(String lang, String contry) { for (SupportLocale l : SupportLocale.values()) { if (l.locale.getLanguage().equals(lang) && l.locale.getCountry().equals(contry)) { return l; } } return SupportLocaleEn; } @Override public String toString() { return displayName; } }; private final Settings settings = Settings.getInstance(); private JComboBox unitSystem; private JComboBox languageCombo; private JButton mapSourcesOnlineUpdate; private JTextField osmHikingTicket; private SettingsGUITileStore tileStoreTab; private JTimeSlider defaultExpirationTime; private JTimeSlider minExpirationTime; private JTimeSlider maxExpirationTime; private JMapSizeCombo mapSize; private JSpinner mapOverlapTiles; private JTextField atlasOutputDirectory; private JComboBox threadCount; private JComboBox bandwidth; private JComboBox proxyType; private JTextField proxyHost; private JTextField proxyPort; private JTextField proxyUserName; private JTextField proxyPassword; private JCheckBox ignoreDlErrors; private JButton okButton; private JButton cancelButton; private JTabbedPane tabbedPane; private JList enabledMapSources; private MapSourcesListModel enabledMapSourcesModel; private JList disabledMapSources; private MapSourcesListModel disabledMapSourcesModel; private final SettingsGUIPaper paperAtlas; private final SettingsGUIWgsGrid display; public static void showSettingsDialog(final JFrame owner) { SwingUtilities.invokeLater(new Runnable() { public void run() { new SettingsGUI(owner); } }); } private SettingsGUI(JFrame owner) { super(owner); setIconImages(MainGUI.MOBAC_ICONS); GUIExceptionHandler.registerForCurrentThread(); setDefaultCloseOperation(DISPOSE_ON_CLOSE); setModal(true); setMinimumSize(new Dimension(300, 300)); paperAtlas = new SettingsGUIPaper(); display = new SettingsGUIWgsGrid(); createJFrame(); createTabbedPane(); createJButtons(); loadSettings(); addListeners(); pack(); // don't allow shrinking, but allow enlarging setMinimumSize(getSize()); Dimension dScreen = Toolkit.getDefaultToolkit().getScreenSize(); setLocation((dScreen.width - getWidth()) / 2, (dScreen.height - getHeight()) / 2); setVisible(true); } private void createJFrame() { setLayout(new BorderLayout()); setTitle(I18nUtils.localizedStringForKey("set_title")); } // Create tabbed pane public void createTabbedPane() { tabbedPane = new JTabbedPane(); tabbedPane.setBounds(0, 0, 492, 275); addDisplaySettingsPanel(); try { addMapSourceSettingsPanel(); } catch (URISyntaxException e) { log.error("", e); } addMapSourceManagerPanel(); addTileUpdatePanel(); tileStoreTab = new SettingsGUITileStore(this); addMapSizePanel(); addDirectoriesPanel(); addNetworkPanel(); tabbedPane.addTab(paperAtlas.getName(), paperAtlas); add(tabbedPane, BorderLayout.CENTER); } private JPanel createNewTab(String tabTitle) { JPanel tabPanel = new JPanel(); addTab(tabTitle, tabPanel); return tabPanel; } protected void addTab(String tabTitle, JPanel tabPanel) { tabPanel.setName(tabTitle); tabPanel.setBorder(new EmptyBorder(5, 5, 5, 5)); tabbedPane.add(tabPanel, tabTitle); } private void addDisplaySettingsPanel() { JPanel tab = createNewTab(I18nUtils.localizedStringForKey("set_display_title")); tab.setLayout(new GridBagLayout()); JPanel unitSystemPanel = new JPanel(new GridBagLayout()); unitSystemPanel .setBorder(createSectionBorder(I18nUtils.localizedStringForKey("set_display_unit_system_title"))); // Language Panel JPanel languagePanel = new JPanel(new GridBagLayout()); languagePanel.setBorder(createSectionBorder(I18nUtils.localizedStringForKey("set_display_language"))); languageCombo = new JComboBox(SupportLocale.values()); languageCombo.setToolTipText(I18nUtils.localizedStringForKey("set_display_language_choose_tips")); languageCombo.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Locale locale = ((SupportLocale) languageCombo.getSelectedItem()).locale; String currentLocaleStr = "" + settings.localeLanguage + settings.localeCountry; String LocaleStr = "" + locale.getLanguage() + locale.getCountry(); if (!currentLocaleStr.equals(LocaleStr) && isVisible()) { settings.localeLanguage = locale.getLanguage(); settings.localeCountry = locale.getCountry(); int result = JOptionPane.showConfirmDialog(null, I18nUtils.localizedStringForKey("set_display_language_restart_desc"), I18nUtils.localizedStringForKey("set_display_language_msg_title"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); I18nUtils.updateLocalizedStringFormSettings(); if (result == JOptionPane.YES_OPTION) { applySettings(); try { final String javaBin = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java"; final File currentJar = new File(SettingsGUI.class.getProtectionDomain().getCodeSource() .getLocation().toURI()); /* is it a jar file? */ if (currentJar.getName().endsWith(".jar")) { /* Build command: java -jar application.jar */ Runtime r = Runtime.getRuntime(); long maxMem = r.maxMemory(); final ArrayList command = new ArrayList(); command.add(javaBin); command.add("-jar"); command.add("-Xms64m"); if ((Long.MAX_VALUE == maxMem)) { command.add("-Xmx1024M"); } else { command.add("-Xmx" + (maxMem / 1048576) + "M"); } command.add(currentJar.getPath()); log.debug("restarting MOBAC using the following command: \n\t" + Arrays.toString(command.toArray())); final ProcessBuilder builder = new ProcessBuilder(command); builder.start(); } } catch (Exception ex) { } System.exit(0); } } } }); languagePanel.add(new JLabel(I18nUtils.localizedStringForKey("set_display_language_choose")), GBC.std()); languagePanel.add(languageCombo, GBC.std()); languagePanel.add(Box.createHorizontalGlue(), GBC.eol().fill(GBC.HORIZONTAL)); UnitSystem[] us = UnitSystem.values(); unitSystem = new JComboBox(us); unitSystemPanel .add(new JLabel(I18nUtils.localizedStringForKey("set_display_unit_system_scale_bar")), GBC.std()); unitSystemPanel.add(unitSystem, GBC.std()); unitSystemPanel.add(Box.createHorizontalGlue(), GBC.eol().fill(GBC.HORIZONTAL)); tab.add(unitSystemPanel, GBC.eol().fill(GBC.HORIZONTAL)); tab.add(display, GBC.eol().fill(GBC.HORIZONTAL)); tab.add(languagePanel, GBC.eol().fill(GBC.HORIZONTAL)); tab.add(Box.createVerticalGlue(), GBC.std().fill(GBC.VERTICAL)); } private void addMapSourceSettingsPanel() throws URISyntaxException { JPanel tab = createNewTab(I18nUtils.localizedStringForKey("set_mapsrc_config_title")); tab.setLayout(new GridBagLayout()); JPanel updatePanel = new JPanel(new GridBagLayout()); updatePanel.setBorder(createSectionBorder(I18nUtils.localizedStringForKey("set_mapsrc_config_online_update"))); mapSourcesOnlineUpdate = new JButton(I18nUtils.localizedStringForKey("set_mapsrc_config_online_update_btn")); mapSourcesOnlineUpdate.addActionListener(new MapPacksOnlineUpdateAction()); updatePanel.add(mapSourcesOnlineUpdate, GBC.std()); JPanel osmHikingPanel = new JPanel(new GridBagLayout()); osmHikingPanel.setBorder(createSectionBorder(I18nUtils.localizedStringForKey("set_mapsrc_config_osmhiking"))); osmHikingTicket = new JTextField(20); osmHikingPanel.add(new JLabel(I18nUtils.localizedStringForKey("set_mapsrc_config_osmhiking_purchased")), GBC.std()); osmHikingPanel.add(osmHikingTicket, GBC.std().insets(2, 0, 10, 0)); JLabel osmHikingTicketUrl = new JLabel(I18nUtils.localizedStringForKey("set_mapsrc_config_osmhiking_howto")); osmHikingTicketUrl.addMouseListener(new OpenInWebbrowser(I18nUtils .localizedStringForKey("set_mapsrc_config_osmhiking_howto_url"))); osmHikingPanel.add(osmHikingTicketUrl, GBC.eol()); tab.add(updatePanel, GBC.eol().fill(GBC.HORIZONTAL)); tab.add(osmHikingPanel, GBC.eol().fill(GBC.HORIZONTAL)); tab.add(Box.createVerticalGlue(), GBC.eol().fill(GBC.VERTICAL)); } private void addMapSourceManagerPanel() { JPanel tab = createNewTab(I18nUtils.localizedStringForKey("set_mapsrc_mgr_title")); tab.setLayout(new GridBagLayout()); JPanel leftPanel = new JPanel(new BorderLayout()); leftPanel.setBorder(createSectionBorder(I18nUtils.localizedStringForKey("set_mapsrc_mgr_title_enabled"))); JPanel centerPanel = new JPanel(new GridBagLayout()); JPanel rightPanel = new JPanel(new BorderLayout()); rightPanel.setBorder(createSectionBorder(I18nUtils.localizedStringForKey("set_mapsrc_mgr_title_disabled"))); JButton up = new JButton(Utilities.loadResourceImageIcon("arrow_blue_up.png")); up.setToolTipText(I18nUtils.localizedStringForKey("set_mapsrc_mgr_move_up_tips")); JButton down = new JButton(Utilities.loadResourceImageIcon("arrow_blue_down.png")); down.setToolTipText(I18nUtils.localizedStringForKey("set_mapsrc_mgr_move_down_tips")); JButton toLeft = new JButton(Utilities.loadResourceImageIcon("arrow_blue_left.png")); toLeft.setToolTipText(I18nUtils.localizedStringForKey("set_mapsrc_mgr_move_left_tips")); JButton toRight = new JButton(Utilities.loadResourceImageIcon("arrow_blue_right.png")); toRight.setToolTipText(I18nUtils.localizedStringForKey("set_mapsrc_mgr_move_right_tips")); Insets buttonInsets = new Insets(4, 4, 4, 4); Dimension buttonDimension = new Dimension(40, 40); up.setPreferredSize(buttonDimension); down.setPreferredSize(buttonDimension); toLeft.setPreferredSize(buttonDimension); toRight.setPreferredSize(buttonDimension); up.setMargin(buttonInsets); down.setMargin(buttonInsets); toLeft.setMargin(buttonInsets); toRight.setMargin(buttonInsets); toLeft.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { int[] idx = disabledMapSources.getSelectedIndices(); for (int i = 0; i < idx.length; i++) { MapSource ms = disabledMapSourcesModel.removeElement(idx[i] - i); enabledMapSourcesModel.addElement(ms); } } }); toRight.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { int[] idx = enabledMapSources.getSelectedIndices(); for (int i = 0; i < idx.length; i++) { MapSource ms = enabledMapSourcesModel.removeElement(idx[i] - i); disabledMapSourcesModel.addElement(ms); } disabledMapSourcesModel.sort(); } }); up.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { int[] idx = enabledMapSources.getSelectedIndices(); if (idx.length == 0) return; for (int i = 0; i < idx.length; i++) { int index = idx[i]; if (index == 0) return; if (enabledMapSourcesModel.moveUp(index)) idx[i]--; } enabledMapSources.setSelectedIndices(idx); enabledMapSources.ensureIndexIsVisible(idx[0]); } }); down.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { int[] idx = enabledMapSources.getSelectedIndices(); if (idx.length == 0) return; for (int i = idx.length - 1; i >= 0; i--) { int index = idx[i]; if (index == enabledMapSourcesModel.getSize() - 1) return; if (enabledMapSourcesModel.moveDown(index)) idx[i]++; } enabledMapSources.setSelectedIndices(idx); enabledMapSources.ensureIndexIsVisible(idx[idx.length - 1]); } }); GBC buttonGbc = GBC.eol(); centerPanel.add(Box.createVerticalStrut(25), GBC.eol()); centerPanel.add(toLeft, buttonGbc); centerPanel.add(toRight, buttonGbc); centerPanel.add(up, buttonGbc); centerPanel.add(down, buttonGbc); centerPanel.add(Box.createVerticalGlue(), GBC.std().fill()); MapSourcesManager msManager = MapSourcesManager.getInstance(); enabledMapSourcesModel = new MapSourcesListModel(msManager.getEnabledOrderedMapSources()); enabledMapSources = new JList(enabledMapSourcesModel); JScrollPane leftScrollPane = new JScrollPane(enabledMapSources, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); leftPanel.add(leftScrollPane, BorderLayout.CENTER); disabledMapSourcesModel = new MapSourcesListModel(msManager.getDisabledMapSources()); disabledMapSourcesModel.sort(); disabledMapSources = new JList(disabledMapSourcesModel); JScrollPane rightScrollPane = new JScrollPane(disabledMapSources, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); rightPanel.add(rightScrollPane, BorderLayout.CENTER); JPanel mapSourcesInnerPanel = new JPanel(); Color c = UIManager.getColor("List.background"); mapSourcesInnerPanel.setBackground(c); GBC lr = GBC.std().fill(); lr.weightx = 1.0; tab.add(leftPanel, lr); tab.add(centerPanel, GBC.std().fill(GBC.VERTICAL)); tab.add(rightPanel, lr); } private void addTileUpdatePanel() { JPanel backGround = createNewTab(I18nUtils.localizedStringForKey("set_tile_update_title")); backGround.setLayout(new GridBagLayout()); ChangeListener sliderChangeListener = new ChangeListener() { public void stateChanged(ChangeEvent e) { JTimeSlider slider = ((JTimeSlider) e.getSource()); long x = slider.getTimeSecondsValue(); JPanel panel = (JPanel) slider.getParent(); TitledBorder tb = (TitledBorder) panel.getBorder(); tb.setTitle(panel.getName() + ": " + Utilities.formatDurationSeconds(x)); panel.repaint(); } }; GBC gbc_ef = GBC.eol().fill(GBC.HORIZONTAL); JPanel defaultExpirationPanel = new JPanel(new GridBagLayout()); defaultExpirationPanel.setName(I18nUtils.localizedStringForKey("set_tile_update_default_expiration")); defaultExpirationPanel.setBorder(createSectionBorder("")); defaultExpirationTime = new JTimeSlider(); defaultExpirationTime.addChangeListener(sliderChangeListener); JLabel descr = new JLabel(I18nUtils.localizedStringForKey("set_tile_update_default_expiration_desc"), JLabel.CENTER); defaultExpirationPanel.add(descr, gbc_ef); defaultExpirationPanel.add(defaultExpirationTime, gbc_ef); JPanel maxExpirationPanel = new JPanel(new BorderLayout()); maxExpirationPanel.setName(I18nUtils.localizedStringForKey("set_tile_update_max_expiration")); maxExpirationPanel.setBorder(createSectionBorder("")); maxExpirationTime = new JTimeSlider(); maxExpirationTime.addChangeListener(sliderChangeListener); maxExpirationPanel.add(maxExpirationTime, BorderLayout.CENTER); JPanel minExpirationPanel = new JPanel(new BorderLayout()); minExpirationPanel.setName(I18nUtils.localizedStringForKey("set_tile_update_min_expiration")); minExpirationPanel.setBorder(createSectionBorder("")); minExpirationTime = new JTimeSlider(); minExpirationTime.addChangeListener(sliderChangeListener); minExpirationPanel.add(minExpirationTime, BorderLayout.CENTER); descr = new JLabel(I18nUtils.localizedStringForKey("set_tile_update_desc"), JLabel.CENTER); backGround.add(descr, gbc_ef); backGround.add(defaultExpirationPanel, gbc_ef); backGround.add(minExpirationPanel, gbc_ef); backGround.add(maxExpirationPanel, gbc_ef); backGround.add(Box.createVerticalGlue(), GBC.std().fill()); } private void addMapSizePanel() { JPanel backGround = createNewTab(I18nUtils.localizedStringForKey("set_map_size_title")); backGround.setLayout(new GridBagLayout()); mapSize = new JMapSizeCombo(); mapSize.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { log.trace("Map size: " + mapSize.getValue()); } }); JLabel mapSizeLabel = new JLabel(I18nUtils.localizedStringForKey("set_map_size_max_size_of_rect")); JLabel mapSizeText = new JLabel(I18nUtils.localizedStringForKey("set_map_size_desc")); mapOverlapTiles = new JSpinner(new SpinnerNumberModel(0, 0, 5, 1)); JLabel mapOverlapTilesLabel = new JLabel(I18nUtils.localizedStringForKey("set_map_size_overlap_tiles")); JPanel leftPanel = new JPanel(new GridBagLayout()); leftPanel.setBorder(createSectionBorder(I18nUtils.localizedStringForKey("set_map_size_settings"))); GBC gbc = GBC.eol().insets(0, 5, 0, 5); leftPanel.add(mapSizeLabel, GBC.std()); leftPanel.add(mapSize, GBC.eol()); leftPanel.add(mapOverlapTilesLabel, GBC.std()); leftPanel.add(mapOverlapTiles, GBC.eol()); leftPanel.add(mapSizeText, gbc.fill(GBC.HORIZONTAL)); leftPanel.add(Box.createVerticalGlue(), GBC.std().fill(GBC.VERTICAL)); backGround.add(leftPanel, GBC.std().fill(GBC.HORIZONTAL).anchor(GBC.NORTHEAST)); backGround.add(Box.createVerticalGlue(), GBC.std().fill(GBC.VERTICAL)); } private void addDirectoriesPanel() { JPanel backGround = createNewTab(I18nUtils.localizedStringForKey("set_directory_title")); backGround.setLayout(new GridBagLayout()); JPanel atlasOutputDirPanel = new JPanel(new GridBagLayout()); atlasOutputDirPanel.setBorder(createSectionBorder(I18nUtils.localizedStringForKey("set_directory_output"))); atlasOutputDirectory = new JTextField(); atlasOutputDirectory.setToolTipText(String.format(I18nUtils.localizedStringForKey("set_directory_output_tips"), settings.getAtlasOutputDirectory())); JButton selectAtlasOutputDirectory = new JButton(I18nUtils.localizedStringForKey("set_directory_output_select")); selectAtlasOutputDirectory.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { JDirectoryChooser dc = new JDirectoryChooser(); dc.setCurrentDirectory(settings.getAtlasOutputDirectory()); if (dc.showDialog(SettingsGUI.this, I18nUtils.localizedStringForKey("set_directory_output_select_dlg_title")) != JFileChooser.APPROVE_OPTION) return; atlasOutputDirectory.setText(dc.getSelectedFile().getAbsolutePath()); } }); atlasOutputDirPanel.add(atlasOutputDirectory, GBC.std().fillH()); atlasOutputDirPanel.add(selectAtlasOutputDirectory, GBC.std()); backGround.add(atlasOutputDirPanel, GBC.eol().fillH()); backGround.add(Box.createVerticalGlue(), GBC.eol().fill(GBC.VERTICAL)); } private void addNetworkPanel() { JPanel backGround = createNewTab(I18nUtils.localizedStringForKey("set_net_title")); backGround.setLayout(new GridBagLayout()); GBC gbc_eolh = GBC.eol().fill(GBC.HORIZONTAL); JPanel panel = new JPanel(new GridBagLayout()); panel.setBorder(createSectionBorder(I18nUtils.localizedStringForKey("set_net_connection"))); threadCount = new JComboBox(THREADCOUNT_LIST); threadCount.setMaximumRowCount(THREADCOUNT_LIST.length); panel.add(threadCount, GBC.std().insets(5, 5, 5, 5).anchor(GBC.EAST)); panel.add(new JLabel(I18nUtils.localizedStringForKey("set_net_connection_desc")), GBC.eol() .fill(GBC.HORIZONTAL)); bandwidth = new JComboBox(Bandwidth.values()); bandwidth.setMaximumRowCount(bandwidth.getItemCount()); panel.add(bandwidth, GBC.std().insets(5, 5, 5, 5)); panel.add(new JLabel(I18nUtils.localizedStringForKey("set_net_bandwidth_desc")), GBC.eol().fill(GBC.HORIZONTAL)); backGround.add(panel, gbc_eolh); // panel = new JPanel(new GridBagLayout()); // panel.setBorder(createSectionBorder("HTTP User-Agent")); // backGround.add(panel, gbc_eolh); panel = new JPanel(new GridBagLayout()); panel.setBorder(createSectionBorder(I18nUtils.localizedStringForKey("set_net_proxy"))); final JLabel proxyTypeLabel = new JLabel(I18nUtils.localizedStringForKey("set_net_proxy_settings")); proxyType = new JComboBox(ProxyType.values()); proxyType.setSelectedItem(settings.getProxyType()); final JLabel proxyHostLabel = new JLabel(I18nUtils.localizedStringForKey("set_net_proxy_host")); proxyHost = new JTextField(settings.getCustomProxyHost()); final JLabel proxyPortLabel = new JLabel(I18nUtils.localizedStringForKey("set_net_proxy_port")); proxyPort = new JTextField(settings.getCustomProxyPort()); final JLabel proxyUserNameLabel = new JLabel(I18nUtils.localizedStringForKey("set_net_proxy_username")); proxyUserName = new JTextField(settings.getCustomProxyUserName()); final JLabel proxyPasswordLabel = new JLabel(I18nUtils.localizedStringForKey("set_net_proxy_password")); proxyPassword = new JTextField(settings.getCustomProxyPassword()); ActionListener al = new ActionListener() { public void actionPerformed(ActionEvent e) { boolean b = ProxyType.CUSTOM.equals(proxyType.getSelectedItem()); boolean c = ProxyType.CUSTOM_W_AUTH.equals(proxyType.getSelectedItem()); proxyHost.setEnabled(b || c); proxyPort.setEnabled(b || c); proxyHostLabel.setEnabled(b || c); proxyPortLabel.setEnabled(b || c); proxyUserName.setEnabled(c); proxyPassword.setEnabled(c); proxyUserNameLabel.setEnabled(c); proxyPasswordLabel.setEnabled(c); } }; al.actionPerformed(null); proxyType.addActionListener(al); panel.add(proxyTypeLabel, GBC.std()); panel.add(proxyType, gbc_eolh.insets(5, 2, 5, 2)); panel.add(proxyHostLabel, GBC.std()); panel.add(proxyHost, gbc_eolh); panel.add(proxyPortLabel, GBC.std()); panel.add(proxyPort, gbc_eolh); panel.add(proxyUserNameLabel, GBC.std()); panel.add(proxyUserName, gbc_eolh); panel.add(proxyPasswordLabel, GBC.std()); panel.add(proxyPassword, gbc_eolh); backGround.add(panel, GBC.eol().fillH()); ignoreDlErrors = new JCheckBox(I18nUtils.localizedStringForKey("set_net_default_ignore_error"), settings.ignoreDlErrors); JPanel jPanel = new JPanel(new GridBagLayout()); jPanel.setBorder(createSectionBorder(I18nUtils.localizedStringForKey("set_net_default"))); jPanel.add(ignoreDlErrors, GBC.std()); jPanel.add(Box.createHorizontalGlue(), GBC.eol().fillH()); backGround.add(jPanel, GBC.eol().fillH()); backGround.add(Box.createVerticalGlue(), GBC.eol().fill(GBC.VERTICAL)); } public void createJButtons() { JPanel buttonPanel = new JPanel(new GridBagLayout()); okButton = new JButton(I18nUtils.localizedStringForKey("OK")); cancelButton = new JButton(I18nUtils.localizedStringForKey("Cancel")); GBC gbc = GBC.std().insets(5, 5, 5, 5); buttonPanel.add(okButton, gbc); buttonPanel.add(cancelButton, gbc); add(buttonPanel, BorderLayout.SOUTH); } private void loadSettings() { Settings s = settings; unitSystem.setSelectedItem(s.unitSystem); tileStoreTab.tileStoreEnabled.setSelected(s.tileStoreEnabled); // language languageCombo.setSelectedItem(SupportLocale.localeOf(s.localeLanguage, s.localeCountry)); mapSize.setValue(s.maxMapSize); mapOverlapTiles.setValue(s.mapOverlapTiles); atlasOutputDirectory.setText(s.getAtlasOutputDirectoryString()); long limit = s.getBandwidthLimit(); for (Bandwidth b : Bandwidth.values()) { if (limit <= b.limit) { bandwidth.setSelectedItem(b); break; } } int index = Arrays.binarySearch(THREADCOUNT_LIST, s.downloadThreadCount); if (index < 0) { if (s.downloadThreadCount > THREADCOUNT_LIST[THREADCOUNT_LIST.length - 1]) index = THREADCOUNT_LIST.length - 1; else index = 0; } threadCount.setSelectedIndex(index); defaultExpirationTime.setTimeMilliValue(s.tileDefaultExpirationTime); maxExpirationTime.setTimeMilliValue(s.tileMaxExpirationTime); minExpirationTime.setTimeMilliValue(s.tileMinExpirationTime); osmHikingTicket.setText(s.osmHikingTicket); ignoreDlErrors.setSelected(s.ignoreDlErrors); paperAtlas.loadSettings(s); display.loadSettings(s); } /** * Reads the user defined settings from the gui and updates the {@link Settings} values according to the read gui * settings. */ private void applySettings() { Settings s = settings; s.unitSystem = (UnitSystem) unitSystem.getSelectedItem(); s.tileStoreEnabled = tileStoreTab.tileStoreEnabled.isSelected(); s.tileDefaultExpirationTime = defaultExpirationTime.getTimeMilliValue(); s.tileMinExpirationTime = minExpirationTime.getTimeMilliValue(); s.tileMaxExpirationTime = maxExpirationTime.getTimeMilliValue(); s.maxMapSize = mapSize.getValue(); s.mapOverlapTiles = (Integer) mapOverlapTiles.getValue(); Locale locale = ((SupportLocale) languageCombo.getSelectedItem()).locale; s.localeLanguage = locale.getLanguage(); s.localeCountry = locale.getCountry(); s.setAtlasOutputDirectory(atlasOutputDirectory.getText()); int threads = ((Integer) threadCount.getSelectedItem()).intValue(); s.downloadThreadCount = threads; s.setBandwidthLimit(((Bandwidth) bandwidth.getSelectedItem()).limit); s.setProxyType((ProxyType) proxyType.getSelectedItem()); s.setCustomProxyHost(proxyHost.getText()); s.setCustomProxyPort(proxyPort.getText()); s.setCustomProxyUserName(proxyUserName.getText()); s.setCustomProxyPassword(proxyPassword.getText()); s.applyProxySettings(); Vector disabledMaps = new Vector(); for (MapSource ms : disabledMapSourcesModel.getVector()) { disabledMaps.add(ms.getName()); } s.mapSourcesDisabled = disabledMaps; Vector enabledMaps = new Vector(); for (MapSource ms : enabledMapSourcesModel.getVector()) { enabledMaps.add(ms.getName()); } s.mapSourcesEnabled = enabledMaps; s.ignoreDlErrors = ignoreDlErrors.isSelected(); paperAtlas.applySettings(s); display.applySettings(s); if (MainGUI.getMainGUI() == null) return; MainGUI.getMainGUI().updateMapSourcesList(); s.osmHikingTicket = osmHikingTicket.getText().trim(); try { MainGUI.getMainGUI().checkAndSaveSettings(); } catch (Exception e) { log.error("Error saving settings to file", e); JOptionPane.showMessageDialog(null, String.format(I18nUtils.localizedStringForKey("set_error_saving_msg"), e.getClass().getSimpleName()), I18nUtils.localizedStringForKey("set_error_saving_title"), JOptionPane.ERROR_MESSAGE); } MainGUI.getMainGUI().previewMap.repaint(); } private void addListeners() { addWindowListener(new WindowCloseListener()); okButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { applySettings(); // Close the dialog window SettingsGUI.this.dispose(); } }); cancelButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { SettingsGUI.this.dispose(); } }); tabbedPane.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { if (tabbedPane.getSelectedComponent() == null) return; // First time the tile store tab is selected start updating the tile store information if (tabbedPane.getSelectedComponent() == tileStoreTab) { // if ("Tile store".equals(tabbedPane.getSelectedComponent().getName())) { tabbedPane.removeChangeListener(this); tileStoreTab.updateTileStoreInfoPanelAsync(null); } } }); KeyStroke escapeKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, false); Action escapeAction = new AbstractAction() { private static final long serialVersionUID = 1L; public void actionPerformed(ActionEvent e) { SettingsGUI.this.dispose(); } }; getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(escapeKeyStroke, "ESCAPE"); getRootPane().getActionMap().put("ESCAPE", escapeAction); } public static final TitledBorder createSectionBorder(String title) { TitledBorder tb = BorderFactory.createTitledBorder(title); Border border = BorderFactory.createEtchedBorder(EtchedBorder.LOWERED); Border margin = new EmptyBorder(3, 3, 3, 3); tb.setBorder(new CompoundBorder(border, margin)); return tb; } private class WindowCloseListener extends WindowAdapter { @Override public void windowClosed(WindowEvent event) { // On close we check if the tile store information retrieval thread // is still running and if yes we interrupt it tileStoreTab.stopThread(); } } private class MapPacksOnlineUpdateAction implements ActionListener { public void actionPerformed(ActionEvent event) { // try { // boolean result = MapSourcesUpdater.mapsourcesOnlineUpdate(); // String msg = (result) ? "Online update successfull" : "No new update avilable"; // DateFormat df = DateFormat.getDateTimeInstance(); // Date date = MapSourcesUpdater.getMapSourcesDate(System.getProperties()); // msg += "\nCurrent map source date: " + df.format(date); // JOptionPane.showMessageDialog(SettingsGUI.this, msg); // if (result) // MainGUI.getMainGUI().refreshPreviewMap(); // } catch (MapSourcesUpdateException e) { // JOptionPane.showMessageDialog(SettingsGUI.this, e.getMessage(), "Mapsources online update failed", // JOptionPane.ERROR_MESSAGE); // } MapPackManager mpm; try { mpm = new MapPackManager(Settings.getInstance().getMapSourcesDirectory()); int result = mpm.updateMapPacks(); switch (result) { case -1: JOptionPane.showMessageDialog(SettingsGUI.this, I18nUtils.localizedStringForKey("set_mapsrc_config_online_update_msg_outdate"), I18nUtils.localizedStringForKey("set_mapsrc_config_online_update_no_update"), JOptionPane.ERROR_MESSAGE); break; case 0: JOptionPane.showMessageDialog(SettingsGUI.this, I18nUtils.localizedStringForKey("set_mapsrc_config_online_update_msg_noneed"), I18nUtils.localizedStringForKey("set_mapsrc_config_online_update_no_update"), JOptionPane.INFORMATION_MESSAGE); break; default: JOptionPane.showMessageDialog(SettingsGUI.this, String.format( I18nUtils.localizedStringForKey("set_mapsrc_config_online_update_msg_done"), result), I18nUtils.localizedStringForKey("set_mapsrc_config_online_update_done"), JOptionPane.INFORMATION_MESSAGE); } } catch (UpdateFailedException e) { JOptionPane.showMessageDialog(SettingsGUI.this, e.getMessage(), I18nUtils.localizedStringForKey("set_mapsrc_config_online_update_failed"), JOptionPane.ERROR_MESSAGE); } catch (Exception e) { Settings.getInstance().mapSourcesUpdate.etag = null; GUIExceptionHandler.processException(e); } } } public static void main(String[] args) { Logging.configureConsoleLogging(Level.TRACE); ProgramInfo.initialize(); DefaultMapSourcesManager.initialize(); TileStore.initialize(); StartMOBAC.setLookAndFeel(); try { Settings.load(); } catch (JAXBException e1) { e1.printStackTrace(); } new SettingsGUI(null); Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { try { Settings.save(); } catch (JAXBException e) { e.printStackTrace(); } } }); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/SplashFrame.java0000644000175000017500000000415312127544350026103 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui; import java.awt.Dimension; import java.awt.HeadlessException; import java.awt.Toolkit; import javax.swing.BorderFactory; import javax.swing.JFrame; import javax.swing.JLabel; import mobac.utilities.Utilities; public class SplashFrame extends JFrame { private static SplashFrame startupFrame; public static void showFrame() { startupFrame = new SplashFrame(); } public SplashFrame() throws HeadlessException { //super(MainGUI.localizedStringForKey("splash_title")); super("MOBAC"); setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); setUndecorated(true); setIconImages(MainGUI.MOBAC_ICONS); JLabel image = new JLabel(Utilities.loadResourceImageIcon("Splash.jpg")); image.setBorder(BorderFactory.createEtchedBorder()); add(image); pack(); setFocusable(false); Dimension dScreen = Toolkit.getDefaultToolkit().getScreenSize(); setLocation((dScreen.width - getWidth()) / 2, (dScreen.height - getHeight()) / 2); setSize(getMinimumSize()); setVisible(true); } public static void hideFrame() { if (startupFrame == null) return; startupFrame.setVisible(false); startupFrame.dispose(); startupFrame = null; } public static void main(String[] arg) { new SplashFrame(); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/MainGUI.java0000644000175000017500000012225612150552674025140 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Font; import java.awt.Frame; import java.awt.GraphicsEnvironment; import java.awt.GridBagLayout; import java.awt.GridLayout; import java.awt.Image; import java.awt.Insets; import java.awt.Point; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.ArrayList; import java.util.Enumeration; import java.util.LinkedList; import java.util.List; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.DefaultComboBoxModel; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JCheckBoxMenuItem; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JLayeredPane; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JRadioButtonMenuItem; import javax.swing.JScrollPane; import javax.swing.JSlider; import javax.swing.KeyStroke; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.event.MenuEvent; import javax.swing.event.MenuListener; import javax.xml.bind.JAXBException; import mobac.externaltools.ExternalToolDef; import mobac.externaltools.ExternalToolsLoader; import mobac.gui.actions.AddGpxTrackPolygonMap; import mobac.gui.actions.AddMapLayer; import mobac.gui.actions.AtlasConvert; import mobac.gui.actions.AtlasCreate; import mobac.gui.actions.AtlasNew; import mobac.gui.actions.BookmarkAdd; import mobac.gui.actions.BookmarkManage; import mobac.gui.actions.DebugSetLogLevel; import mobac.gui.actions.DebugShowLogFile; import mobac.gui.actions.DebugShowMapSourceNames; import mobac.gui.actions.DebugShowMapTileGrid; import mobac.gui.actions.DebugShowReport; import mobac.gui.actions.HelpLicenses; import mobac.gui.actions.PanelShowHide; import mobac.gui.actions.RefreshCustomMapsources; import mobac.gui.actions.SelectionModeCircle; import mobac.gui.actions.SelectionModePolygon; import mobac.gui.actions.SelectionModeRectangle; import mobac.gui.actions.ShowAboutDialog; import mobac.gui.actions.ShowHelpAction; import mobac.gui.actions.ShowReadme; import mobac.gui.atlastree.JAtlasTree; import mobac.gui.components.FilledLayeredPane; import mobac.gui.components.JAtlasNameField; import mobac.gui.components.JBookmarkMenuItem; import mobac.gui.components.JCollapsiblePanel; import mobac.gui.components.JMenuItem2; import mobac.gui.components.JZoomCheckBox; import mobac.gui.listeners.AtlasModelListener; import mobac.gui.mapview.GridZoom; import mobac.gui.mapview.JMapViewer; import mobac.gui.mapview.PreviewMap; import mobac.gui.mapview.WgsGrid.WgsDensity; import mobac.gui.mapview.controller.JMapController; import mobac.gui.mapview.controller.PolygonCircleSelectionMapController; import mobac.gui.mapview.controller.PolygonSelectionMapController; import mobac.gui.mapview.controller.RectangleSelectionMapController; import mobac.gui.mapview.interfaces.MapEventListener; import mobac.gui.panels.JCoordinatesPanel; import mobac.gui.panels.JGpxPanel; import mobac.gui.panels.JProfilesPanel; import mobac.gui.panels.JTileImageParametersPanel; import mobac.gui.panels.JTileStoreCoveragePanel; import mobac.gui.settings.SettingsGUI; import mobac.mapsources.MapSourcesManager; import mobac.program.ProgramInfo; import mobac.program.interfaces.AtlasInterface; import mobac.program.interfaces.FileBasedMapSource; import mobac.program.interfaces.MapSource; import mobac.program.model.Bookmark; import mobac.program.model.MapSelection; import mobac.program.model.MercatorPixelCoordinate; import mobac.program.model.Profile; import mobac.program.model.SelectedZoomLevels; import mobac.program.model.Settings; import mobac.program.model.SettingsWgsGrid; import mobac.program.model.TileImageParameters; import mobac.utilities.GBC; import mobac.utilities.GUIExceptionHandler; import mobac.utilities.I18nUtils; import mobac.utilities.Utilities; import org.apache.log4j.Level; import org.apache.log4j.Logger; public class MainGUI extends JFrame implements MapEventListener { private static final long serialVersionUID = 1L; private static Logger log = Logger.getLogger(MainGUI.class); private static Color labelBackgroundColor = new Color(0, 0, 0, 127); private static Color checkboxBackgroundColor = new Color(0, 0, 0, 40); private static Color labelForegroundColor = Color.WHITE; private static MainGUI mainGUI = null; public static final ArrayList MOBAC_ICONS = new ArrayList(3); static { MOBAC_ICONS.add(Utilities.loadResourceImageIcon("mobac48.png").getImage()); MOBAC_ICONS.add(Utilities.loadResourceImageIcon("mobac32.png").getImage()); MOBAC_ICONS.add(Utilities.loadResourceImageIcon("mobac16.png").getImage()); } protected JMenuBar menuBar; protected JMenu toolsMenu = null; private JMenu bookmarkMenu = null; public final PreviewMap previewMap = new PreviewMap(); public final JAtlasTree jAtlasTree = new JAtlasTree(previewMap); private JCheckBox wgsGridCheckBox; private JComboBox wgsGridCombo; private JLabel zoomLevelText; private JComboBox gridZoomCombo; private JSlider zoomSlider; private JComboBox mapSourceCombo; private JButton settingsButton; private JAtlasNameField atlasNameTextField; private JButton createAtlasButton; private JPanel zoomLevelPanel; private JZoomCheckBox[] cbZoom = new JZoomCheckBox[0]; private JLabel amountOfTilesLabel; private AtlasCreate atlasCreateAction = new AtlasCreate(jAtlasTree); private JCoordinatesPanel coordinatesPanel; private JProfilesPanel profilesPanel; public JTileImageParametersPanel tileImageParametersPanel; private JTileStoreCoveragePanel tileStoreCoveragePanel; public JGpxPanel gpxPanel; private JPanel mapControlPanel = new JPanel(new BorderLayout()); private JPanel leftPanel = new JPanel(new GridBagLayout()); private JPanel leftPanelContent = null; private JPanel rightPanel = new JPanel(new GridBagLayout()); public JMenu logLevelMenu; private JMenuItem smRectangle; private JMenuItem smPolygon; private JMenuItem smCircle; private MercatorPixelCoordinate mapSelectionMax = null; private MercatorPixelCoordinate mapSelectionMin = null; public static void createMainGui() { if (mainGUI != null) return; mainGUI = new MainGUI(); mainGUI.setVisible(true); log.trace("MainGUI now visible"); } public static MainGUI getMainGUI() { return mainGUI; } // MP: get custom font static Font sCustomFont = null; public static Font customFont() { if (sCustomFont == null) { // force to use Chinese font sCustomFont = new Font("宋体", 9, 13); } return sCustomFont; } // MP: update all UI components' default font to custom font public static void setDefaultFontOfAllUIComponents(Font defaultFont) { if (defaultFont != null) { // register custom font to application,system font will return false GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); ge.registerFont(defaultFont); // update all UI's font settings javax.swing.plaf.FontUIResource fontRes = new javax.swing.plaf.FontUIResource(defaultFont); Enumeration keys = UIManager.getDefaults().keys(); while (keys.hasMoreElements()) { Object key = keys.nextElement(); Object value = UIManager.get(key); if (value instanceof javax.swing.plaf.FontUIResource) { UIManager.put(key, fontRes); } } } } private MainGUI() { super(); mainGUI = this; setIconImages(MOBAC_ICONS); GUIExceptionHandler.registerForCurrentThread(); setTitle(ProgramInfo.getCompleteTitle()); log.trace("Creating main dialog - " + getTitle()); setResizable(true); Dimension dScreen = Toolkit.getDefaultToolkit().getScreenSize(); setMinimumSize(new Dimension(Math.min(800, dScreen.width), Math.min(590, dScreen.height))); setSize(getMinimumSize()); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); addWindowListener(new WindowDestroyer()); addComponentListener(new MainWindowListener()); previewMap.addMapEventListener(this); createControls(); calculateNrOfTilesToDownload(); setLayout(new BorderLayout()); add(leftPanel, BorderLayout.WEST); add(rightPanel, BorderLayout.EAST); JLayeredPane layeredPane = new FilledLayeredPane(); layeredPane.add(previewMap, Integer.valueOf(0)); layeredPane.add(mapControlPanel, Integer.valueOf(1)); add(layeredPane, BorderLayout.CENTER); updateMapControlsPanel(); updateLeftPanel(); updateRightPanel(); updateZoomLevelCheckBoxes(); calculateNrOfTilesToDownload(); menuBar = new JMenuBar(); prepareMenuBar(); setJMenuBar(menuBar); loadSettings(); profilesPanel.initialize(); mapSourceChanged(previewMap.getMapSource()); updateZoomLevelCheckBoxes(); updateGridSizeCombo(); tileImageParametersPanel.updateControlsState(); zoomChanged(previewMap.getZoom()); gridZoomChanged(previewMap.getGridZoom()); previewMap.updateMapSelection(); previewMap.grabFocus(); } private void createControls() { // zoom slider zoomSlider = new JSlider(JMapViewer.MIN_ZOOM, previewMap.getMapSource().getMaxZoom()); zoomSlider.setOrientation(JSlider.HORIZONTAL); zoomSlider.setMinimumSize(new Dimension(50, 10)); zoomSlider.setSize(50, zoomSlider.getPreferredSize().height); zoomSlider.addChangeListener(new ZoomSliderListener()); zoomSlider.setOpaque(false); // zoom level text zoomLevelText = new JLabel(" 00 "); zoomLevelText.setOpaque(true); zoomLevelText.setBackground(labelBackgroundColor); zoomLevelText.setForeground(labelForegroundColor); zoomLevelText.setToolTipText(I18nUtils.localizedStringForKey("map_ctrl_zoom_level_title_tips")); // grid zoom combo gridZoomCombo = new JComboBox(); gridZoomCombo.setEditable(false); gridZoomCombo.addActionListener(new GridZoomComboListener()); gridZoomCombo.setToolTipText(I18nUtils.localizedStringForKey("map_ctrl_zoom_grid_tips")); SettingsWgsGrid s = Settings.getInstance().wgsGrid; // WGS Grid label wgsGridCheckBox = new JCheckBox(I18nUtils.localizedStringForKey("map_ctrl_wgs_grid_title"), s.enabled); // wgsGridCheckBox.setOpaque(true); wgsGridCheckBox.setOpaque(true); wgsGridCheckBox.setBackground(checkboxBackgroundColor); wgsGridCheckBox.setForeground(labelForegroundColor); wgsGridCheckBox.setToolTipText(I18nUtils.localizedStringForKey("map_ctrl_wgs_grid_tips")); wgsGridCheckBox.setMargin(new Insets(0, 0, 0, 0)); wgsGridCheckBox.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { boolean enabled = wgsGridCheckBox.isSelected(); Settings.getInstance().wgsGrid.enabled = enabled; wgsGridCombo.setVisible(enabled); previewMap.repaint(); } }); // WGS Grid combo wgsGridCombo = new JComboBox(WgsDensity.values()); wgsGridCombo.setMaximumRowCount(WgsDensity.values().length); wgsGridCombo.setVisible(s.enabled); wgsGridCombo.setSelectedItem(s.density); wgsGridCombo.setToolTipText(I18nUtils.localizedStringForKey("map_ctrl_wgs_grid_density_tips")); wgsGridCombo.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { WgsDensity d = (WgsDensity) wgsGridCombo.getSelectedItem(); Settings.getInstance().wgsGrid.density = d; previewMap.repaint(); } }); // map source combo mapSourceCombo = new JComboBox(MapSourcesManager.getInstance().getEnabledOrderedMapSources()); mapSourceCombo.setMaximumRowCount(20); mapSourceCombo.addActionListener(new MapSourceComboListener()); mapSourceCombo.setToolTipText(I18nUtils.localizedStringForKey("lp_map_source_combo_tips")); // settings button settingsButton = new JButton(I18nUtils.localizedStringForKey("lp_main_setting_button_title")); settingsButton.addActionListener(new SettingsButtonListener()); settingsButton.setToolTipText(I18nUtils.localizedStringForKey("lp_main_setting_button_tips")); // atlas name text field atlasNameTextField = new JAtlasNameField(); atlasNameTextField.setColumns(12); atlasNameTextField.setActionCommand("atlasNameTextField"); atlasNameTextField.setToolTipText(I18nUtils.localizedStringForKey("lp_atlas_name_field_tips")); // main button createAtlasButton = new JButton(I18nUtils.localizedStringForKey("lp_mian_create_btn_title")); createAtlasButton.addActionListener(atlasCreateAction); createAtlasButton.setToolTipText(I18nUtils.localizedStringForKey("lp_main_create_btn_tips")); // zoom level check boxes zoomLevelPanel = new JPanel(); zoomLevelPanel.setBorder(BorderFactory.createEmptyBorder()); zoomLevelPanel.setOpaque(false); // amount of tiles to download amountOfTilesLabel = new JLabel(); amountOfTilesLabel.setToolTipText(I18nUtils.localizedStringForKey("lp_zoom_total_tile_count_tips")); amountOfTilesLabel.setOpaque(true); amountOfTilesLabel.setBackground(labelBackgroundColor); amountOfTilesLabel.setForeground(labelForegroundColor); coordinatesPanel = new JCoordinatesPanel(); tileImageParametersPanel = new JTileImageParametersPanel(); profilesPanel = new JProfilesPanel(jAtlasTree); profilesPanel.getLoadButton().addActionListener(new LoadProfileListener()); tileStoreCoveragePanel = new JTileStoreCoveragePanel(previewMap); } private void prepareMenuBar() { // Atlas menu JMenu atlasMenu = new JMenu(I18nUtils.localizedStringForKey("menu_atlas")); atlasMenu.setMnemonic(KeyEvent.VK_A); JMenuItem newAtlas = new JMenuItem(I18nUtils.localizedStringForKey("menu_atlas_new")); newAtlas.setMnemonic(KeyEvent.VK_N); newAtlas.addActionListener(new AtlasNew()); atlasMenu.add(newAtlas); JMenuItem convertAtlas = new JMenuItem(I18nUtils.localizedStringForKey("menu_atlas_convert_format")); convertAtlas.setMnemonic(KeyEvent.VK_V); convertAtlas.addActionListener(new AtlasConvert()); atlasMenu.add(convertAtlas); atlasMenu.addSeparator(); JMenuItem createAtlas = new JMenuItem(I18nUtils.localizedStringForKey("menu_atlas_create")); createAtlas.setMnemonic(KeyEvent.VK_C); createAtlas.addActionListener(atlasCreateAction); atlasMenu.add(createAtlas); // Maps menu JMenu mapsMenu = new JMenu(I18nUtils.localizedStringForKey("menu_maps")); mapsMenu.setMnemonic(KeyEvent.VK_M); JMenu selectionModeMenu = new JMenu(I18nUtils.localizedStringForKey("menu_maps_selection")); selectionModeMenu.setMnemonic(KeyEvent.VK_M); mapsMenu.add(selectionModeMenu); smRectangle = new JRadioButtonMenuItem(I18nUtils.localizedStringForKey("menu_maps_selection_rect")); smRectangle.addActionListener(new SelectionModeRectangle()); smRectangle.setSelected(true); selectionModeMenu.add(smRectangle); smPolygon = new JRadioButtonMenuItem(I18nUtils.localizedStringForKey("menu_maps_selection_polygon")); smPolygon.addActionListener(new SelectionModePolygon()); selectionModeMenu.add(smPolygon); smCircle = new JRadioButtonMenuItem(I18nUtils.localizedStringForKey("menu_maps_selection_circle")); smCircle.addActionListener(new SelectionModeCircle()); selectionModeMenu.add(smCircle); JMenuItem addSelection = new JMenuItem(I18nUtils.localizedStringForKey("menu_maps_selection_add")); addSelection.addActionListener(AddMapLayer.INSTANCE); addSelection.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, ActionEvent.CTRL_MASK)); addSelection.setMnemonic(KeyEvent.VK_A); mapsMenu.add(addSelection); JMenuItem addGpxTrackSelection = new JMenuItem2( I18nUtils.localizedStringForKey("menu_maps_selection_add_by_gpx"), AddGpxTrackPolygonMap.class); mapsMenu.add(addGpxTrackSelection); // Bookmarks menu bookmarkMenu = new JMenu(I18nUtils.localizedStringForKey("menu_bookmark")); bookmarkMenu.setMnemonic(KeyEvent.VK_B); JMenuItem addBookmark = new JMenuItem(I18nUtils.localizedStringForKey("menu_bookmark_save")); addBookmark.setMnemonic(KeyEvent.VK_S); addBookmark.addActionListener(new BookmarkAdd(previewMap)); bookmarkMenu.add(addBookmark); JMenuItem manageBookmarks = new JMenuItem2(I18nUtils.localizedStringForKey("menu_bookmark_manage"), BookmarkManage.class); manageBookmarks.setMnemonic(KeyEvent.VK_S); bookmarkMenu.add(addBookmark); bookmarkMenu.add(manageBookmarks); bookmarkMenu.addSeparator(); // Panels menu JMenu panelsMenu = new JMenu(I18nUtils.localizedStringForKey("menu_panels")); panelsMenu.setMnemonic(KeyEvent.VK_P); JMenuItem showLeftPanel = new JMenuItem(I18nUtils.localizedStringForKey("menu_show_hide_left_panel")); showLeftPanel.addActionListener(new PanelShowHide(leftPanel)); JMenuItem showRightPanel = new JMenuItem(I18nUtils.localizedStringForKey("menu_show_hide_gpx_panel")); showRightPanel.addActionListener(new PanelShowHide(rightPanel)); panelsMenu.add(showLeftPanel); panelsMenu.add(showRightPanel); menuBar.add(atlasMenu); menuBar.add(mapsMenu); menuBar.add(bookmarkMenu); menuBar.add(panelsMenu); loadToolsMenu(); menuBar.add(Box.createHorizontalGlue()); // Debug menu JMenu debugMenu = new JMenu(I18nUtils.localizedStringForKey("menu_debug")); JMenuItem mapGrid = new JCheckBoxMenuItem(I18nUtils.localizedStringForKey("menu_debug_show_hide_tile_border"), false); mapGrid.addActionListener(new DebugShowMapTileGrid()); debugMenu.add(mapGrid); debugMenu.addSeparator(); debugMenu.setMnemonic(KeyEvent.VK_D); JMenuItem mapSourceNames = new JMenuItem2(I18nUtils.localizedStringForKey("menu_debug_show_all_map_source"), DebugShowMapSourceNames.class); mapSourceNames.setMnemonic(KeyEvent.VK_N); debugMenu.add(mapSourceNames); debugMenu.addSeparator(); JMenuItem refreshCustomMapSources = new JMenuItem2( I18nUtils.localizedStringForKey("menu_debug_refresh_map_source"), RefreshCustomMapsources.class); debugMenu.add(refreshCustomMapSources); debugMenu.addSeparator(); JMenuItem showLog = new JMenuItem2(I18nUtils.localizedStringForKey("menu_debug_show_log_file"), DebugShowLogFile.class); showLog.setMnemonic(KeyEvent.VK_S); debugMenu.add(showLog); logLevelMenu = new JMenu(I18nUtils.localizedStringForKey("menu_debug_log_level")); logLevelMenu.setMnemonic(KeyEvent.VK_L); Level[] list = new Level[] { Level.TRACE, Level.DEBUG, Level.INFO, Level.ERROR, Level.FATAL, Level.OFF }; ActionListener al = new DebugSetLogLevel(); Level rootLogLevel = Logger.getRootLogger().getLevel(); for (Level level : list) { String name = level.toString(); JRadioButtonMenuItem item = new JRadioButtonMenuItem(name, (rootLogLevel.toString().equals(name))); item.setName(name); item.addActionListener(al); logLevelMenu.add(item); } debugMenu.add(logLevelMenu); debugMenu.addSeparator(); JMenuItem report = new JMenuItem2(I18nUtils.localizedStringForKey("menu_debug_system_report"), DebugShowReport.class); report.setMnemonic(KeyEvent.VK_R); debugMenu.add(report); menuBar.add(debugMenu); // Help menu JMenu help = new JMenu(I18nUtils.localizedStringForKey("menu_help")); JMenuItem readme = new JMenuItem(I18nUtils.localizedStringForKey("menu_help_readme")); JMenuItem howToMap = new JMenuItem(I18nUtils.localizedStringForKey("menu_help_how_to_preview")); JMenuItem licenses = new JMenuItem(I18nUtils.localizedStringForKey("menu_help_licenses")); JMenuItem about = new JMenuItem(I18nUtils.localizedStringForKey("menu_help_about")); readme.addActionListener(new ShowReadme()); about.addActionListener(new ShowAboutDialog()); howToMap.addActionListener(new ShowHelpAction()); licenses.addActionListener(new HelpLicenses()); help.add(readme); help.add(howToMap); help.addSeparator(); help.add(licenses); help.addSeparator(); help.add(about); menuBar.add(help); } public void loadToolsMenu() { if (ExternalToolsLoader.load()) { if (toolsMenu == null) { toolsMenu = new JMenu(I18nUtils.localizedStringForKey("menu_tool")); toolsMenu.addMenuListener(new MenuListener() { public void menuSelected(MenuEvent e) { loadToolsMenu(); log.debug("Tools menu Loaded"); } public void menuDeselected(MenuEvent e) { } public void menuCanceled(MenuEvent e) { } }); menuBar.add(toolsMenu); } toolsMenu.removeAll(); for (ExternalToolDef t : ExternalToolsLoader.tools) { JMenuItem m = new JMenuItem(t.name); m.addActionListener(t); toolsMenu.add(m); } } } private void updateLeftPanel() { leftPanel.removeAll(); coordinatesPanel.addButtonActionListener(new ApplySelectionButtonListener()); JCollapsiblePanel mapSourcePanel = new JCollapsiblePanel( I18nUtils.localizedStringForKey("lp_map_source_title"), new GridBagLayout()); mapSourcePanel.addContent(mapSourceCombo, GBC.std().insets(2, 2, 2, 2).fill()); JCollapsiblePanel zoomLevelsPanel = new JCollapsiblePanel(I18nUtils.localizedStringForKey("lp_zoom_title"), new GridBagLayout()); zoomLevelsPanel.addContent(zoomLevelPanel, GBC.eol().insets(2, 4, 2, 0)); zoomLevelsPanel.addContent(amountOfTilesLabel, GBC.std().anchor(GBC.WEST).insets(0, 5, 0, 2)); GBC gbc_std = GBC.std().insets(5, 2, 5, 3); GBC gbc_eol = GBC.eol().insets(5, 2, 5, 3); JCollapsiblePanel atlasContentPanel = new JCollapsiblePanel(I18nUtils.localizedStringForKey("lp_atlas_title"), new GridBagLayout()); JScrollPane treeScrollPane = new JScrollPane(jAtlasTree, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); jAtlasTree.getTreeModel().addTreeModelListener(new AtlasModelListener(jAtlasTree, profilesPanel)); treeScrollPane.setMinimumSize(new Dimension(100, 150)); treeScrollPane.setPreferredSize(new Dimension(100, 200)); treeScrollPane.setAutoscrolls(true); atlasContentPanel.addContent(treeScrollPane, GBC.eol().fill().insets(0, 1, 0, 0)); JButton clearAtlas = new JButton(I18nUtils.localizedStringForKey("lp_atlas_new_btn_title")); atlasContentPanel.addContent(clearAtlas, GBC.std()); clearAtlas.addActionListener(new AtlasNew()); JButton addLayers = new JButton(I18nUtils.localizedStringForKey("lp_atlas_add_selection_btn_title")); atlasContentPanel.addContent(addLayers, GBC.eol()); addLayers.addActionListener(AddMapLayer.INSTANCE); atlasContentPanel.addContent(new JLabel(I18nUtils.localizedStringForKey("lp_atlas_name_label_title")), gbc_std); atlasContentPanel.addContent(atlasNameTextField, gbc_eol.fill(GBC.HORIZONTAL)); gbc_eol = GBC.eol().insets(5, 2, 5, 2).fill(GBC.HORIZONTAL); leftPanelContent = new JPanel(new GridBagLayout()); leftPanelContent.add(coordinatesPanel, gbc_eol); leftPanelContent.add(mapSourcePanel, gbc_eol); leftPanelContent.add(zoomLevelsPanel, gbc_eol); leftPanelContent.add(tileImageParametersPanel, gbc_eol); leftPanelContent.add(atlasContentPanel, gbc_eol); leftPanelContent.add(profilesPanel, gbc_eol); leftPanelContent.add(createAtlasButton, gbc_eol); leftPanelContent.add(settingsButton, gbc_eol); leftPanelContent.add(tileStoreCoveragePanel, gbc_eol); leftPanelContent.add(Box.createVerticalGlue(), GBC.eol().fill(GBC.VERTICAL)); JScrollPane scrollPane = new JScrollPane(leftPanelContent); scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); scrollPane.setBorder(BorderFactory.createEmptyBorder()); // Set the scroll pane width large enough so that the // scroll bar has enough space to appear right to it Dimension d = scrollPane.getPreferredSize(); d.width += 5 + scrollPane.getVerticalScrollBar().getWidth(); // scrollPane.setPreferredSize(d); scrollPane.setMinimumSize(d); leftPanel.add(scrollPane, GBC.std().fill()); // leftPanel.add(leftPanelContent, GBC.std().fill()); } private void updateRightPanel() { GBC gbc_eol = GBC.eol().insets(5, 2, 5, 2).fill(); gpxPanel = new JGpxPanel(previewMap); rightPanel.add(gpxPanel, gbc_eol); } private JPanel updateMapControlsPanel() { mapControlPanel.removeAll(); mapControlPanel.setOpaque(false); // zoom label JLabel zoomLabel = new JLabel(I18nUtils.localizedStringForKey("map_ctrl_zoom_level_title")); zoomLabel.setOpaque(true); zoomLabel.setBackground(labelBackgroundColor); zoomLabel.setForeground(labelForegroundColor); // top panel JPanel topControls = new JPanel(new GridBagLayout()); topControls.setOpaque(false); topControls.add(zoomLabel, GBC.std().insets(5, 5, 0, 0)); topControls.add(zoomSlider, GBC.std().insets(0, 5, 0, 0)); topControls.add(zoomLevelText, GBC.std().insets(0, 5, 0, 0)); topControls.add(gridZoomCombo, GBC.std().insets(10, 5, 0, 0)); topControls.add(wgsGridCheckBox, GBC.std().insets(10, 5, 0, 0)); topControls.add(wgsGridCombo, GBC.std().insets(5, 5, 0, 0)); topControls.add(Box.createHorizontalGlue(), GBC.std().fillH()); mapControlPanel.add(topControls, BorderLayout.NORTH); // bottom panel // JPanel bottomControls = new JPanel(new GridBagLayout()); // bottomControls.setOpaque(false); // bottomControls.add(Box.createHorizontalGlue(), // GBC.std().fill(GBC.HORIZONTAL)); // mapControlPanel.add(bottomControls, BorderLayout.SOUTH); return mapControlPanel; } public void updateMapSourcesList() { MapSource ms = (MapSource) mapSourceCombo.getSelectedItem(); mapSourceCombo .setModel(new DefaultComboBoxModel(MapSourcesManager.getInstance().getEnabledOrderedMapSources())); mapSourceCombo.setSelectedItem(ms); MapSource ms2 = (MapSource) mapSourceCombo.getSelectedItem(); if (!ms.equals(ms2)) previewMap.setMapSource(ms2); } public void updateBookmarksMenu() { LinkedList items = new LinkedList(); for (int i = 0; i < bookmarkMenu.getMenuComponentCount(); i++) { JMenuItem item = bookmarkMenu.getItem(i); if (!(item instanceof JBookmarkMenuItem)) items.add(item); } bookmarkMenu.removeAll(); for (JMenuItem item : items) { if (item != null) bookmarkMenu.add(item); else bookmarkMenu.addSeparator(); } for (Bookmark b : Settings.getInstance().placeBookmarks) { bookmarkMenu.add(new JBookmarkMenuItem(b)); } } private void loadSettings() { if (Profile.DEFAULT.exists()) { try { jAtlasTree.load(Profile.DEFAULT); } catch (Exception e) { log.error("Failed to load atlas", e); GUIExceptionHandler.processException(e); new AtlasNew().actionPerformed(null); } } else new AtlasNew().actionPerformed(null); Settings settings = Settings.getInstance(); atlasNameTextField.setText(settings.elementName); previewMap.settingsLoad(); int nextZoom = 0; List zoomList = settings.selectedZoomLevels; if (zoomList != null) { for (JZoomCheckBox currentZoomCb : cbZoom) { for (int i = nextZoom; i < zoomList.size(); i++) { int currentListZoom = zoomList.get(i); if (currentZoomCb.getZoomLevel() == currentListZoom) { currentZoomCb.setSelected(true); nextZoom = 1; break; } } } } coordinatesPanel.setNumberFormat(settings.coordinateNumberFormat); tileImageParametersPanel.loadSettings(); tileImageParametersPanel.atlasFormatChanged(jAtlasTree.getAtlas().getOutputFormat()); // mapSourceCombo // .setSelectedItem(MapSourcesManager.getSourceByName(settings. // mapviewMapSource)); setSize(settings.mainWindow.size); Point windowLocation = settings.mainWindow.position; if (windowLocation.x == -1 && windowLocation.y == -1) { setLocationRelativeTo(null); } else { setLocation(windowLocation); } if (settings.mainWindow.maximized) setExtendedState(Frame.MAXIMIZED_BOTH); leftPanel.setVisible(settings.mainWindow.leftPanelVisible); rightPanel.setVisible(settings.mainWindow.rightPanelVisible); if (leftPanelContent != null) { for (Component c : leftPanelContent.getComponents()) { if (c instanceof JCollapsiblePanel) { JCollapsiblePanel cp = (JCollapsiblePanel) c; String name = cp.getName(); if (name != null && settings.mainWindow.collapsedPanels.contains(name)) cp.setCollapsed(true); } } } updateBookmarksMenu(); } private void saveSettings() { try { jAtlasTree.save(Profile.DEFAULT); Settings s = Settings.getInstance(); previewMap.settingsSave(); s.mapviewMapSource = previewMap.getMapSource().getName(); s.selectedZoomLevels = new SelectedZoomLevels(cbZoom).getZoomLevelList(); s.elementName = atlasNameTextField.getText(); s.coordinateNumberFormat = coordinatesPanel.getNumberFormat(); tileImageParametersPanel.saveSettings(); boolean maximized = (getExtendedState() & Frame.MAXIMIZED_BOTH) != 0; s.mainWindow.maximized = maximized; if (!maximized) { s.mainWindow.size = getSize(); s.mainWindow.position = getLocation(); } s.mainWindow.collapsedPanels.clear(); if (leftPanelContent != null) { for (Component c : leftPanelContent.getComponents()) { if (c instanceof JCollapsiblePanel) { JCollapsiblePanel cp = (JCollapsiblePanel) c; if (cp.isCollapsed()) s.mainWindow.collapsedPanels.add(cp.getName()); } } } s.mainWindow.leftPanelVisible = leftPanel.isVisible(); s.mainWindow.rightPanelVisible = rightPanel.isVisible(); checkAndSaveSettings(); } catch (Exception e) { GUIExceptionHandler.showExceptionDialog(e); JOptionPane.showMessageDialog(null, I18nUtils.localizedStringForKey("msg_settings_write_error"), I18nUtils.localizedStringForKey("Error"), JOptionPane.ERROR_MESSAGE); } } public void checkAndSaveSettings() throws JAXBException { if (Settings.checkSettingsFileModified()) { int x = JOptionPane.showConfirmDialog(this, I18nUtils.localizedStringForKey("msg_setting_file_is_changed_by_other"), I18nUtils.localizedStringForKey("msg_setting_file_is_changed_by_other_title"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); if (x != JOptionPane.YES_OPTION) return; } Settings.save(); } public JTileImageParametersPanel getParametersPanel() { return tileImageParametersPanel; } public String getUserText() { return atlasNameTextField.getText(); } public void refreshPreviewMap() { previewMap.refreshMap(); } private class ZoomSliderListener implements ChangeListener { public void stateChanged(ChangeEvent e) { previewMap.setZoom(zoomSlider.getValue()); } } private class GridZoomComboListener implements ActionListener { public void actionPerformed(ActionEvent e) { if (!gridZoomCombo.isEnabled()) return; GridZoom g = (GridZoom) gridZoomCombo.getSelectedItem(); if (g == null) return; log.debug("Selected grid zoom combo box item has changed: " + g.getZoom()); previewMap.setGridZoom(g.getZoom()); repaint(); previewMap.updateMapSelection(); } } private void updateGridSizeCombo() { int maxZoom = previewMap.getMapSource().getMaxZoom(); int minZoom = previewMap.getMapSource().getMinZoom(); GridZoom lastGridZoom = (GridZoom) gridZoomCombo.getSelectedItem(); gridZoomCombo.setEnabled(false); gridZoomCombo.removeAllItems(); gridZoomCombo.setMaximumRowCount(maxZoom - minZoom + 2); gridZoomCombo.addItem(new GridZoom(-1) { @Override public String toString() { return I18nUtils.localizedStringForKey("map_ctrl_zoom_grid_disable"); } }); for (int i = maxZoom; i >= minZoom; i--) { gridZoomCombo.addItem(new GridZoom(i)); } if (lastGridZoom != null) gridZoomCombo.setSelectedItem(lastGridZoom); gridZoomCombo.setEnabled(true); } private class ApplySelectionButtonListener implements ActionListener { public void actionPerformed(ActionEvent e) { setSelectionByEnteredCoordinates(); } } private class MapSourceComboListener implements ActionListener { public void actionPerformed(ActionEvent e) { MapSource mapSource = (MapSource) mapSourceCombo.getSelectedItem(); if (mapSource == null) { mapSourceCombo.setSelectedIndex(0); mapSource = (MapSource) mapSourceCombo.getSelectedItem(); } if (mapSource instanceof FileBasedMapSource) // initialize the map source e.g. detect available zoom levels ((FileBasedMapSource) mapSource).initialize(); previewMap.setMapSource(mapSource); zoomSlider.setMinimum(previewMap.getMapSource().getMinZoom()); zoomSlider.setMaximum(previewMap.getMapSource().getMaxZoom()); updateGridSizeCombo(); updateZoomLevelCheckBoxes(); calculateNrOfTilesToDownload(); } } private class LoadProfileListener implements ActionListener { public void actionPerformed(ActionEvent e) { Profile profile = profilesPanel.getSelectedProfile(); profilesPanel.getDeleteButton().setEnabled(profile != null); if (profile == null) return; jAtlasTree.load(profile); previewMap.repaint(); tileImageParametersPanel.atlasFormatChanged(jAtlasTree.getAtlas().getOutputFormat()); } } private class SettingsButtonListener implements ActionListener { public void actionPerformed(ActionEvent e) { SettingsGUI.showSettingsDialog(MainGUI.this); } } private void updateZoomLevelCheckBoxes() { MapSource tileSource = previewMap.getMapSource(); int zoomLevels = tileSource.getMaxZoom() - tileSource.getMinZoom() + 1; zoomLevels = Math.max(zoomLevels, 0); JCheckBox oldZoomLevelCheckBoxes[] = cbZoom; int oldMinZoom = 0; if (cbZoom.length > 0) oldMinZoom = cbZoom[0].getZoomLevel(); cbZoom = new JZoomCheckBox[zoomLevels]; zoomLevelPanel.removeAll(); zoomLevelPanel.setLayout(new GridLayout(0, 10, 1, 2)); ZoomLevelCheckBoxListener cbl = new ZoomLevelCheckBoxListener(); for (int i = cbZoom.length - 1; i >= 0; i--) { int cbz = i + tileSource.getMinZoom(); JZoomCheckBox cb = new JZoomCheckBox(cbz); cb.setPreferredSize(new Dimension(22, 11)); cb.setMinimumSize(cb.getPreferredSize()); cb.setOpaque(false); cb.setFocusable(false); cb.setName(Integer.toString(cbz)); int oldCbIndex = cbz - oldMinZoom; if (oldCbIndex >= 0 && oldCbIndex < (oldZoomLevelCheckBoxes.length)) cb.setSelected(oldZoomLevelCheckBoxes[oldCbIndex].isSelected()); cb.addActionListener(cbl); // cb.setToolTipText("Select zoom level " + cbz + " for atlas"); zoomLevelPanel.add(cb); cbZoom[i] = cb; JLabel l = new JLabel(Integer.toString(cbz)); zoomLevelPanel.add(l); } amountOfTilesLabel.setOpaque(false); amountOfTilesLabel.setForeground(Color.black); } private class ZoomLevelCheckBoxListener implements ActionListener { public void actionPerformed(ActionEvent e) { calculateNrOfTilesToDownload(); } } public void selectionChanged(MercatorPixelCoordinate max, MercatorPixelCoordinate min) { mapSelectionMax = max; mapSelectionMin = min; coordinatesPanel.setSelection(max, min); calculateNrOfTilesToDownload(); } public void zoomChanged(int zoomLevel) { zoomLevelText.setText(" " + zoomLevel + " "); zoomSlider.setValue(zoomLevel); } public void gridZoomChanged(int newGridZoomLevel) { gridZoomCombo.setSelectedItem(new GridZoom(newGridZoomLevel)); } public MapSource getSelectedMapSource() { return (MapSource) mapSourceCombo.getSelectedItem(); } public SelectedZoomLevels getSelectedZoomLevels() { return new SelectedZoomLevels(cbZoom); } public void selectNextMapSource() { if (mapSourceCombo.getSelectedIndex() == mapSourceCombo.getItemCount() - 1) { Toolkit.getDefaultToolkit().beep(); } else { mapSourceCombo.setSelectedIndex(mapSourceCombo.getSelectedIndex() + 1); } } public void selectPreviousMapSource() { if (mapSourceCombo.getSelectedIndex() == 0) { Toolkit.getDefaultToolkit().beep(); } else { mapSourceCombo.setSelectedIndex(mapSourceCombo.getSelectedIndex() - 1); } } public void mapSourceChanged(MapSource newMapSource) { // TODO update selected area if new map source has different projectionCategory calculateNrOfTilesToDownload(); // if (newMapSource != null && newMapSource.equals(mapSourceCombo.getSelectedItem())) // return; mapSourceCombo.setSelectedItem(newMapSource); } public void mapSelectionControllerChanged(JMapController newMapController) { smPolygon.setSelected(false); smCircle.setSelected(false); smRectangle.setSelected(false); if (newMapController instanceof PolygonSelectionMapController) smPolygon.setSelected(true); else if (newMapController instanceof PolygonCircleSelectionMapController) smCircle.setSelected(true); else if (newMapController instanceof RectangleSelectionMapController) smRectangle.setSelected(true); } private void setSelectionByEnteredCoordinates() { coordinatesPanel.correctMinMax(); MapSelection ms = coordinatesPanel.getMapSelection(previewMap.getMapSource()); mapSelectionMax = ms.getBottomRightPixelCoordinate(); mapSelectionMin = ms.getTopLeftPixelCoordinate(); previewMap.setSelectionAndZoomTo(ms, false); } public MapSelection getMapSelectionCoordinates() { if (mapSelectionMax == null || mapSelectionMin == null) return null; return new MapSelection(previewMap.getMapSource(), mapSelectionMax, mapSelectionMin); } public TileImageParameters getSelectedTileImageParameters() { return tileImageParametersPanel.getSelectedTileImageParameters(); } private void calculateNrOfTilesToDownload() { MapSelection ms = getMapSelectionCoordinates(); String baseText; baseText = I18nUtils.localizedStringForKey("lp_zoom_total_tile_title"); if (ms == null || !ms.isAreaSelected()) { amountOfTilesLabel.setText(String.format(baseText, "0")); amountOfTilesLabel.setToolTipText(""); } else { try { SelectedZoomLevels sZL = new SelectedZoomLevels(cbZoom); int[] zoomLevels = sZL.getZoomLevels(); long totalNrOfTiles = 0; StringBuilder hint = new StringBuilder(1024); hint.append(I18nUtils.localizedStringForKey("lp_zoom_total_tile_hint_head")); for (int i = 0; i < zoomLevels.length; i++) { int zoom = zoomLevels[i]; long[] info = ms.calculateNrOfTilesEx(zoom); totalNrOfTiles += info[0]; hint.append(String.format(I18nUtils.localizedStringForKey("lp_zoom_total_tile_hint_row"), zoomLevels[i], info[0], info[1], info[2])); // hint.append("
Level " + zoomLevels[i] + ": " + info[0] + " (" + info[1] + "*" + info[2] + // ")"); } String hintText = "" + hint.toString() + ""; amountOfTilesLabel.setText(String.format(baseText, Long.toString(totalNrOfTiles))); amountOfTilesLabel.setToolTipText(hintText); } catch (Exception e) { amountOfTilesLabel.setText(String.format(baseText, "?")); log.error("", e); } } } public AtlasInterface getAtlas() { return jAtlasTree.getAtlas(); } private class WindowDestroyer extends WindowAdapter { @Override public void windowOpened(WindowEvent e) { SwingUtilities.invokeLater(new Runnable() { public void run() { previewMap.setEnabled(true); } }); } public void windowClosing(WindowEvent event) { saveSettings(); } } /** * Saves the window position and size when window is moved or resized. This is necessary because of the maximized * state. If a window is maximized it is impossible to retrieve the window size & position of the non-maximized * window - therefore we have to collect the information every time they change. */ private class MainWindowListener extends ComponentAdapter { public void componentResized(ComponentEvent event) { // log.debug(event.paramString()); updateValues(); } public void componentMoved(ComponentEvent event) { // log.debug(event.paramString()); updateValues(); } private void updateValues() { // only update old values while window is in NORMAL state // Note(Java bug): Sometimes getExtendedState() says the window is // not maximized but maximizing is already in progress and therefore // the window bounds are already changed. if ((getExtendedState() & MAXIMIZED_BOTH) != 0) return; Settings s = Settings.getInstance(); s.mainWindow.size = getSize(); s.mainWindow.position = getLocation(); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/components/0000755000175000017500000000000012127544350025215 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/components/JCoordinateField.java0000644000175000017500000001304012127544350031223 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.components; import java.awt.Color; import java.awt.Point; import java.awt.event.MouseEvent; import java.text.DecimalFormatSymbols; import java.text.NumberFormat; import java.text.ParseException; import java.text.ParsePosition; import javax.swing.JTextField; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import mobac.utilities.I18nUtils; import mobac.utilities.Utilities; import mobac.utilities.geo.CoordinateDms2Format; public class JCoordinateField extends JTextField { private static final long serialVersionUID = 1L; private static final Color ERROR_COLOR = new Color(255, 100, 100); private static final String INVALID_TEXT = I18nUtils.localizedStringForKey("lp_coords_invalid_text"); private JCoordinateListener coordinateListener; private boolean inputIsValid = true; private NumberFormat numberFormat; private final double min; private final double max; public JCoordinateField(double min, double max) { super(10); this.min = min; this.max = max; numberFormat = new CoordinateDms2Format(new DecimalFormatSymbols()); coordinateListener = new JCoordinateListener(); coordinateListener.checkCoordinate(null); } @Override public Point getToolTipLocation(MouseEvent event) { if (getToolTipText().length() > 0) return super.getToolTipLocation(event); else // We don't want a tool tip but Java does not allow to disable it? // -> show it at a point where no user will ever see it return new Point(Integer.MAX_VALUE, Integer.MAX_VALUE); } public void setCoordinate(double value) { try { // We know that the number is valid, therefore we can skip the check // -> saves CPU power while selecting via preview map boolean newValid = true; coordinateListener.setEnabled(false); if (Double.isNaN(value)) { super.setText(""); newValid = false; } else { super.setText(numberFormat.format(value)); } if (newValid != inputIsValid) coordinateListener.changeValidMode(true); } finally { coordinateListener.setEnabled(true); } } public double getCoordinate() throws ParseException { ParsePosition pos = new ParsePosition(0); String text = JCoordinateField.this.getText(); Number num = numberFormat.parse(text, pos); if (num == null || pos.getErrorIndex() >= 0 || Double.isNaN(num.doubleValue())) throw new ParseException(text, pos.getErrorIndex()); return num.doubleValue(); } public double getCoordinateOrNaN() { ParsePosition pos = new ParsePosition(0); String text = JCoordinateField.this.getText(); Number num = numberFormat.parse(text, pos); if (num == null || pos.getErrorIndex() >= 0) return Double.NaN; return num.doubleValue(); } public boolean isInputValid() { return inputIsValid; } public NumberFormat getNumberFormat() { return numberFormat; } public void setNumberFormat(NumberFormat numberFormat) { double coord = getCoordinateOrNaN(); this.numberFormat = numberFormat; setCoordinate(coord); } protected class JCoordinateListener implements DocumentListener { private Color defaultColor; private boolean enabled; private JCoordinateListener() { enabled = true; defaultColor = JCoordinateField.this.getBackground(); JCoordinateField.this.getDocument().addDocumentListener(this); } private void checkCoordinate(DocumentEvent de) { if (!enabled) return; boolean valid = false; try { ParsePosition pos = new ParsePosition(0); String text = JCoordinateField.this.getText(); Number num = numberFormat.parse(text, pos); if (num == null) { valid = false; return; } double d = num.doubleValue(); valid = (!Double.isNaN(d)) && (d >= min) && (d <= max); } catch (Exception e) { valid = false; } if (valid != inputIsValid) changeValidMode(valid); } private void changeValidMode(boolean valid) { Color newC = valid ? defaultColor : ERROR_COLOR; JCoordinateField.this.setBackground(newC); String toolTip = valid ? "" : String.format(INVALID_TEXT, numberFormat.format(min), numberFormat.format(max)); JCoordinateField.this.setToolTipText(toolTip); if (toolTip.length() > 0) Utilities.showTooltipNow(JCoordinateField.this); inputIsValid = valid; } public void changedUpdate(DocumentEvent e) { checkCoordinate(e); } public void insertUpdate(DocumentEvent e) { checkCoordinate(e); } public void removeUpdate(DocumentEvent e) { checkCoordinate(e); } public boolean isEnabled() { return enabled; } public void setEnabled(boolean enabled) { this.enabled = enabled; } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/components/JCollapsiblePanel.java0000644000175000017500000002174112122526604031405 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.components; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Cursor; import java.awt.Dimension; import java.awt.Font; import java.awt.GridBagLayout; import java.awt.LayoutManager; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.ImageIcon; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.border.Border; import mobac.utilities.GBC; import mobac.utilities.Utilities; /** * Bases upon "TitleContainer" from project "swivel" * http://code.google.com/p/swivel/ (LGPL license) * * A {@code TitleContainer} is a simple container that provides an easily * visible title. * */ public class JCollapsiblePanel extends JPanel { private static final long serialVersionUID = 1L; protected static final int DEFAULT_TITLE_PADDING = 3; protected static final Color DEFAULT_TITLE_BACKGROUND_COLOR = Color.LIGHT_GRAY; protected static final Color DEFAULT_TITLE_COLOR = Color.BLACK; private static ImageIcon arrowClosed; private static ImageIcon arrowOpen; static { try { arrowClosed = Utilities.loadResourceImageIcon("arrow_closed.png"); arrowOpen = Utilities.loadResourceImageIcon("arrow_open.png"); } catch (Exception e) { arrowClosed = new ImageIcon(); arrowOpen = new ImageIcon(); } } // title protected final JLabel titleIcon; protected final JLabel titleLabel; protected final JPanel titlePanel; // main component protected Container contentContainer; // collapsing protected final CollapsingMouseListener collapsingMouseListener; private boolean isCollapsed; /** * Constructs a {@code TitleContainer} that wraps the specified container. * * @param container * the main container */ public JCollapsiblePanel(Container container) { this(container, ""); } public JCollapsiblePanel(String title) { this(new JPanel(), title); } public JCollapsiblePanel(String title, LayoutManager layout) { this(new JPanel(layout), title); setName(title); } /** * Constructs a {@code TitleContainer} that wraps the specified component * and has the specified title. * * @param container * the main container * @param title * the title */ public JCollapsiblePanel(Container container, String title) { super(); setName(title); titleIcon = new JLabel(arrowOpen); titleLabel = new JLabel(title); titlePanel = new JPanel(new GridBagLayout()); // mainComponentPanel = new JPanel(new GridBagLayout()); collapsingMouseListener = new CollapsingMouseListener(); titleIcon.setMinimumSize(new Dimension(40, 40)); titleIcon.setPreferredSize(titleIcon.getPreferredSize()); // set collapse behavior titlePanel.addMouseListener(collapsingMouseListener); // look and feel setTitleBackgroundColor(DEFAULT_TITLE_BACKGROUND_COLOR); setTitleColor(DEFAULT_TITLE_COLOR); setTitleBarPadding(DEFAULT_TITLE_PADDING); // layout titlePanel.add(titleIcon, GBC.std()); titlePanel.add(titleLabel, GBC.std().insets(5, 0, 1, 0)); titlePanel.add(Box.createHorizontalGlue(), GBC.eol().fill()); setLayout(new BorderLayout()); add(titlePanel, BorderLayout.NORTH); add(container, BorderLayout.CENTER); setContentContainer(container); setBorder(BorderFactory.createEtchedBorder()); } /** * This method provides a programmatic way to collapse the container. * * @param collapsed * whether the container should be collapsed or shown */ public void setCollapsed(boolean collapsed) { if (isCollapsed == collapsed) { return; } if (collapsed) { titleIcon.setIcon(arrowClosed); // We have to make sure that the panel width does not shrink because // of the hidden content of contentContainer Dimension dcont = contentContainer.getLayout().preferredLayoutSize(contentContainer); Dimension pref = titlePanel.getPreferredSize(); titlePanel.setPreferredSize(new Dimension(dcont.width, pref.height)); } else { titleIcon.setIcon(arrowOpen); } contentContainer.setVisible(!collapsed); isCollapsed = collapsed; revalidate(); } /** * Gets whether the container is collapsed or not. * * @return whether the container is collapsed or not */ public boolean isCollapsed() { return isCollapsed; } /** * Sets the title of this container. * * @param title * the title */ public void setTitle(String title) { if (title != null) { titleLabel.setText(title); } else { titleLabel.setText(""); } } /** * Gets the this container's title. * * @return the title */ public String getTitle() { return titleLabel.getText(); } /** * Sets the main content container for this container. * * @param container * the main content container */ public void setContentContainer(Container container) { // don't need to do anything if the main component hasn't changed if (container == this.contentContainer) { return; } // remove the main component if (this.contentContainer != null) { remove(this.contentContainer); } // replace the main component this.contentContainer = container; add(container, BorderLayout.CENTER); // repaint main component revalidate(); } /** * Gets the main content container for this container. * * @return the main container */ public Container getContentContainer() { return contentContainer; } public void addContent(Component comp, Object constraints) { contentContainer.add(comp, constraints); } /** * Sets the title font. * * @param font * the title font */ public void setTitleFont(Font font) { super.setFont(font); if (titleLabel != null) { titleLabel.setFont(font); } } /** * Sets the background color of the title bar. * * @param color * the color */ public void setTitleBackgroundColor(Color color) { this.titlePanel.setBackground(color); } /** * Sets the title text color. * * @param color * the color */ public void setTitleColor(Color color) { this.titleLabel.setForeground(color); } /** * Sets the title bar padding in pixels. * * @param padding * the title bar padding in pixels */ public void setTitleBarPadding(int padding) { Border border = BorderFactory.createEmptyBorder(padding, padding, padding, padding); this.titlePanel.setBorder(border); } /** * Sets the visibility of the title bar. If the title bar is invisible, the * user will not be able to collapse or decollapse the container. * * @param visible * visibility of the title bar */ public void setTitleBarVisible(boolean visible) { this.titlePanel.setVisible(visible); } /** * Gets the visibility of the title bar. * * @return true if the title bar is visible, false otherwise */ public boolean isTitleBarVisible() { return this.titlePanel.isVisible(); } //-------------------------------------------------------------------------- /** * A {@code MouseListener} that changes the cursor when moved over the title * bar to indicate that it is clickable. Clicking the title bar collapses * the container. */ private class CollapsingMouseListener extends MouseAdapter { private final Cursor CLICK_ME_CURSOR = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR); /** * Collapses or shows the titled component. * * {@inheritDoc} */ public void mousePressed(MouseEvent e) { setCollapsed(!JCollapsiblePanel.this.isCollapsed); } /** * Changes the cursor to indicate clickability. * * {@inheritDoc} */ public void mouseEntered(MouseEvent e) { titlePanel.setCursor(CLICK_ME_CURSOR); } /** * Changes the cursor back to the default. * * {@inheritDoc} */ public void mouseExited(MouseEvent e) { titlePanel.setCursor(Cursor.getDefaultCursor()); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/components/JRegexTextField.java0000644000175000017500000000425212122526604031055 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.components; import java.awt.Toolkit; import java.util.regex.Pattern; import javax.swing.JTextField; import javax.swing.text.AttributeSet; import javax.swing.text.BadLocationException; import javax.swing.text.PlainDocument; public class JRegexTextField extends JTextField { private static final long serialVersionUID = 1L; public JRegexTextField(String regex, int maxLength) { super(); setDocument(new AtlasNameDocument(regex, maxLength)); } public class AtlasNameDocument extends PlainDocument { private static final long serialVersionUID = 1L; public Pattern pattern; public int maxLength; public AtlasNameDocument(String regex, int maxLength) { super(); pattern = Pattern.compile(regex); this.maxLength = maxLength; } public void insertString(int offset, String str, AttributeSet attr) throws BadLocationException { if (str == null) return; if (!pattern.matcher(str).matches()) { Toolkit.getDefaultToolkit().beep(); return; } String oldText = JRegexTextField.this.getText(); super.insertString(offset, str, attr); // Maximum length exceeded? if (JRegexTextField.this.getText().length() > maxLength) { JRegexTextField.this.setText(oldText); Toolkit.getDefaultToolkit().beep(); } } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/components/JZoomCheckBox.java0000644000175000017500000000251412127544350030527 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.components; import javax.swing.JCheckBox; import mobac.utilities.I18nUtils; public class JZoomCheckBox extends JCheckBox { private static final long serialVersionUID = 1L; private final int zoomLevel; public JZoomCheckBox(int zoomLevel) { super(); this.zoomLevel = zoomLevel; setToolTipText(String.format(I18nUtils.localizedStringForKey("lp_zoom_number_tips"),zoomLevel)); } public int getZoomLevel() { return zoomLevel; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/components/JIntCombo.java0000644000175000017500000000532212122526604027703 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.components; import java.awt.Component; import java.awt.event.ActionListener; import java.util.Vector; import javax.swing.ComboBoxEditor; import javax.swing.JComboBox; import org.apache.log4j.Logger; public class JIntCombo extends JComboBox { private static final long serialVersionUID = 1L; static Logger log = Logger.getLogger(JIntCombo.class); protected JIntField editorComponent; protected Integer defaultValue; public JIntCombo(Vector values, Integer defaultValue) { super(values); this.defaultValue = defaultValue; createEditorComponent(); setEditable(true); setEditor(new Editor()); setMaximumRowCount(values.size()); setSelectedItem(defaultValue); } protected void createEditorComponent() { } public int getValue() { try { return editorComponent.getValue(); } catch (NumberFormatException e) { return defaultValue; } } public void setValue(int newValue) { setSelectedIndex(-1); editorComponent.setValue(newValue, true); } public boolean isValueValid() { return editorComponent.isInputValid(); } protected class Editor implements ComboBoxEditor { public Editor() { super(); } public void addActionListener(ActionListener l) { editorComponent.addActionListener(l); } public Component getEditorComponent() { return editorComponent; } public Object getItem() { try { return editorComponent.getValue(); } catch (NumberFormatException e) { return getValue(); } } public void removeActionListener(ActionListener l) { editorComponent.removeActionListener(l); } public void selectAll() { editorComponent.selectAll(); } public void setItem(Object entry) { if (entry == null) return; editorComponent.setValue(((Integer) entry).intValue(), true); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/components/JMenuItem2.java0000644000175000017500000000341412122526604027776 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.components; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JMenuItem; public class JMenuItem2 extends JMenuItem implements ActionListener { private Class actionClass; public JMenuItem2(String text, int mnemonic, Class actionClass) { super(text, mnemonic); this.actionClass = actionClass; addActionListener(this); } public JMenuItem2(String text, Class actionClass) { super(text); this.actionClass = actionClass; addActionListener(this); } public void actionPerformed(ActionEvent event) { ActionListener al; try { al = actionClass.newInstance(); al.actionPerformed(event); } catch (InstantiationException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/components/JDistanceSlider.java0000644000175000017500000000412312122526604031064 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.components; import java.util.Hashtable; import javax.swing.JLabel; import javax.swing.JSlider; import mobac.program.interfaces.MapSpace; import mobac.program.model.UnitSystem; public class JDistanceSlider extends JSlider { private static final long serialVersionUID = 1L; private final Hashtable labelTable; public JDistanceSlider(MapSpace mapSpace, int zoom, int y, UnitSystem unit, int pixelMin, int pixelMax) { super(pixelMin, pixelMax); labelTable = new Hashtable(); int diff4 = (pixelMax - pixelMin) / 4; int[] labelvalues = new int[] { pixelMin, pixelMin + diff4, pixelMin + 2 * diff4, pixelMin + 3 * diff4, pixelMax }; for (int i : labelvalues) { double distance = mapSpace.horizontalDistance(zoom, y, i) * unit.earthRadius * unit.unitFactor; String label; if (distance > unit.unitFactor) { distance /= unit.unitFactor; label = String.format("%2.0f %s", distance, unit.unitLarge); } else label = String.format("%2.0f %s", distance, unit.unitSmall); labelTable.put(new Integer(i), new JLabel(label)); } setPaintTicks(true); setMajorTickSpacing(diff4); setLabelTable(labelTable); setPaintLabels(true); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/components/JProfilesComboBox.java0000644000175000017500000000453312122526604031410 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.components; import javax.swing.DefaultComboBoxModel; import javax.swing.JComboBox; import javax.swing.JTextField; import javax.swing.border.EmptyBorder; import javax.swing.plaf.basic.BasicComboBoxEditor; import mobac.program.model.Profile; /** * An editable {@link JComboBox} for displaying the saved atlases profiles. */ public class JProfilesComboBox extends JComboBox { private static final long serialVersionUID = 1L; public JProfilesComboBox() { super(); setEditable(true); setEditor(new ProfilesComboBoxEditor()); } public void loadProfilesList() { setModel(new DefaultComboBoxModel(Profile.getProfiles())); setSelectedIndex(-1); } public boolean deleteSelectedProfile() { Profile profile = (Profile) getSelectedItem(); if (profile == null) return false; profile.delete(); setSelectedIndex(-1); removeItem(profile); return true; } /** * * @return the selected profile or null if no profile is * selected or a new unsaved profile is selected */ public Profile getSelectedProfile() { Object selItem = getSelectedItem(); if (selItem instanceof Profile) return (Profile) selItem; else return null; } protected static class ProfilesComboBoxEditor extends BasicComboBoxEditor { @Override protected JTextField createEditorComponent() { JAtlasNameField field = new JAtlasNameField(); field.setBorder(new EmptyBorder(2, 2, 2, 0)); return field; } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/components/JAtlasNameField.java0000644000175000017500000000235312122526604031003 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.components; import javax.swing.JTextField; import mobac.program.model.Profile; /** * A {@link JTextField} that only accepts ASCII characters, numbers and spaces. * */ public class JAtlasNameField extends JRegexTextField { private static final long serialVersionUID = 1L; public JAtlasNameField() { super(Profile.PROFILE_NAME_REGEX, 40); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/components/JMapSizeCombo.java0000644000175000017500000000444312122526604030524 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.components; import java.awt.Color; import java.util.Vector; import org.apache.log4j.Logger; public class JMapSizeCombo extends JIntCombo { private static final long serialVersionUID = 1L; public static final int MIN = 10; public static final int MAX = Integer.MAX_VALUE; static Vector MAP_SIZE_VALUES; static Integer DEFAULT; static Logger log = Logger.getLogger(JMapSizeCombo.class); static { // Sizes from 1024 to 32768 MAP_SIZE_VALUES = new Vector(11); MAP_SIZE_VALUES.addElement(new Integer(128000)); MAP_SIZE_VALUES.addElement(new Integer(1048575)); MAP_SIZE_VALUES.addElement(new Integer(65536)); MAP_SIZE_VALUES.addElement(DEFAULT = new Integer(32767)); MAP_SIZE_VALUES.addElement(new Integer(30000)); MAP_SIZE_VALUES.addElement(new Integer(25000)); MAP_SIZE_VALUES.addElement(new Integer(20000)); MAP_SIZE_VALUES.addElement(new Integer(15000)); MAP_SIZE_VALUES.addElement(new Integer(10000)); MAP_SIZE_VALUES.addElement(new Integer(2048)); MAP_SIZE_VALUES.addElement(new Integer(1024)); } public JMapSizeCombo() { super(MAP_SIZE_VALUES, DEFAULT); setEditable(true); setEditor(new Editor()); setMaximumRowCount(MAP_SIZE_VALUES.size()); setSelectedItem(DEFAULT); } @Override protected void createEditorComponent() { editorComponent = new JIntField(MIN, MAX, 4, ""); editorComponent.setErrorColor(Color.ORANGE); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/components/JDropDownButton.java0000644000175000017500000000473512122526604031130 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.components; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.Action; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import javax.swing.SwingConstants; import javax.swing.plaf.basic.BasicArrowButton; public class JDropDownButton extends JButton { private static final long serialVersionUID = 1L; private BasicArrowButton arrowButton; private JPopupMenu buttonPopupMenu; public JDropDownButton(String text) { super(text); buttonPopupMenu = new JPopupMenu(); arrowButton = new BasicArrowButton(SwingConstants.SOUTH, null, null, Color.BLACK, null); arrowButton.setBorder(BorderFactory.createEmptyBorder()); arrowButton.setFocusable(false); setHorizontalAlignment(SwingConstants.LEFT); setLayout(new BorderLayout()); add(arrowButton, BorderLayout.EAST); arrowButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Rectangle r = getBounds(); buttonPopupMenu.show(JDropDownButton.this, r.x, r.y + r.height); } }); } public void addDropDownItem(String text, ActionListener l) { JMenuItem item = new JMenuItem(text); item.addActionListener(l); buttonPopupMenu.add(item); } public void addDropDownItem(String text, Action a) { JMenuItem item = new JMenuItem(text); item.setAction(a); buttonPopupMenu.add(item); } public void addDropDownItem(JMenuItem item) { buttonPopupMenu.add(item); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/components/JTimeSlider.java0000644000175000017500000000537712122526604030244 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.components; import java.util.Hashtable; import java.util.concurrent.TimeUnit; import javax.swing.JLabel; import javax.swing.JSlider; public class JTimeSlider extends JSlider { private static final long serialVersionUID = 1L; private static final Hashtable LABEL_TABLE; private static final double LOG2 = Math.log(2d); private static final double C1 = -1000.4d / LOG2; private static final double C2 = 3d * LOG2; private static final int MIN = 10000; private static final int MAX = 31000; static { LABEL_TABLE = new Hashtable(); int hour = timeToSliderValue(TimeUnit.HOURS.toMillis(1)); int day = timeToSliderValue(TimeUnit.DAYS.toMillis(1)); int month = timeToSliderValue(TimeUnit.DAYS.toMillis(31)); int year = timeToSliderValue(TimeUnit.DAYS.toMillis(365)); LABEL_TABLE.put(new Integer(MIN), new JLabel("0 sec")); LABEL_TABLE.put(new Integer(hour), new JLabel("1 hour")); LABEL_TABLE.put(new Integer(day), new JLabel("1 day")); LABEL_TABLE.put(new Integer(month), new JLabel("1 month")); LABEL_TABLE.put(new Integer(year), new JLabel("1 year")); LABEL_TABLE.put(new Integer(MAX), new JLabel("never")); } public JTimeSlider() { super(MIN, MAX); setMinorTickSpacing(1000); setPaintTicks(true); setLabelTable(LABEL_TABLE); setPaintLabels(true); } public long getTimeSecondsValue() { return sliderToTimeValue(super.getValue()) / 1000; } public long getTimeMilliValue() { return sliderToTimeValue(super.getValue()); } public void setTimeMilliValue(long time) { super.setValue(timeToSliderValue(time)); } private static long sliderToTimeValue(int sliderValue) { return -1024000 + (long) (1000 * Math.pow(2d, sliderValue / 1000d)); } private static int timeToSliderValue(long timeValue) { return (int) (C1 * (C2 - Math.log((timeValue + 1024000) / 125d))); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/components/FilledLayeredPane.java0000644000175000017500000000310012122526604031360 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.components; import java.awt.Component; import javax.swing.JLayeredPane; public class FilledLayeredPane extends JLayeredPane { private static final long serialVersionUID = 1L; /** * Layout each of the components in this JLayeredPane so that they all fill * the entire extents of the layered pane -- from (0,0) to (getWidth(), * getHeight()) */ @Override public void doLayout() { // Synchronizing on getTreeLock, because I see other layouts doing // that. // see BorderLayout::layoutContainer(Container) synchronized (getTreeLock()) { int w = getWidth(); int h = getHeight(); for (Component c : getComponents()) { c.setBounds(0, 0, w, h); } } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/components/JIntField.java0000644000175000017500000000706112122526604027671 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.components; import java.awt.Color; import javax.swing.JTextField; import javax.swing.border.EmptyBorder; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import mobac.program.model.NumericDocument; import mobac.utilities.Utilities; public class JIntField extends JTextField { private static final long serialVersionUID = 1L; protected Color errorColor = new Color(255, 100, 100); public int min = 0; public int max = 0; private String errorText; private InputListener listener; private boolean inputIsValid = true; public JIntField(int min, int max, int columns, String errorText) { super(columns); this.min = min; this.max = max; this.errorText = errorText; setDocument(new NumericDocument()); listener = new InputListener(); listener.checkInput(null); setBorder(new EmptyBorder(2, 2, 2, 0)); } public void setErrorColor(Color c) { errorColor = c; } public int getValue() throws NumberFormatException { return Integer.parseInt(getText()); } public void setValue(int newValue, boolean check) { if (newValue <= 0) super.setText(""); else super.setText(Integer.toString(newValue)); if (check) listener.checkInput(null); } public void setText(String t) { throw new RuntimeException("Calling setText() is not allowed!"); } public boolean isInputValid() { return testInputValid(); } private boolean testInputValid() { try { int i = Integer.parseInt(getText()); return (i >= min) && (i <= max); } catch (NumberFormatException e) { return false; } } protected class InputListener implements DocumentListener { private Color defaultColor; private InputListener() { defaultColor = JIntField.this.getBackground(); JIntField.this.getDocument().addDocumentListener(this); } private void checkInput(DocumentEvent de) { boolean valid = false; try { valid = testInputValid(); } catch (Exception e) { valid = false; } if (valid != inputIsValid) setDisplayedValidMode(valid); inputIsValid = valid; } private void setDisplayedValidMode(boolean valid) { Color newC = valid ? defaultColor : errorColor; JIntField.this.setBackground(newC); String toolTip = valid ? "" : String.format(errorText, new Object[] { min, max }); JIntField.this.setToolTipText(toolTip); if (toolTip.length() > 0) Utilities.showTooltipNow(JIntField.this); } public void changedUpdate(DocumentEvent e) { checkInput(e); } public void insertUpdate(DocumentEvent e) { checkInput(e); } public void removeUpdate(DocumentEvent e) { checkInput(e); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/components/JTileSizeCombo.java0000644000175000017500000000425312127544350030706 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.components; import java.util.Vector; import mobac.utilities.I18nUtils; import org.apache.log4j.Logger; public class JTileSizeCombo extends JIntCombo { private static final long serialVersionUID = 1L; public static final int MIN = 50; public static final int MAX = 8192; static Vector TILE_SIZE_VALUES; static Integer DEFAULT; static Logger log = Logger.getLogger(JTileSizeCombo.class); static { DEFAULT = new Integer(256); TILE_SIZE_VALUES = new Vector(); TILE_SIZE_VALUES.addElement(new Integer(64)); TILE_SIZE_VALUES.addElement(new Integer(128)); TILE_SIZE_VALUES.addElement(DEFAULT); TILE_SIZE_VALUES.addElement(new Integer(512)); TILE_SIZE_VALUES.addElement(new Integer(768)); TILE_SIZE_VALUES.addElement(new Integer(1024)); TILE_SIZE_VALUES.addElement(new Integer(1536)); for (int i = 2048; i <= MAX; i += 1024) { TILE_SIZE_VALUES.addElement(new Integer(i)); } } public JTileSizeCombo() { super(TILE_SIZE_VALUES, DEFAULT); setEditable(true); setEditor(new Editor()); setMaximumRowCount(TILE_SIZE_VALUES.size()); setSelectedItem(DEFAULT); } @Override protected void createEditorComponent() { editorComponent = new JIntField(MIN, MAX, 4, I18nUtils.localizedStringForKey("msg_invalid_tile_size")); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/components/JDirectoryChooser.java0000644000175000017500000000355112127544350031465 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.components; import java.io.File; import javax.swing.JFileChooser; import javax.swing.filechooser.FileFilter; import mobac.utilities.I18nUtils; public class JDirectoryChooser extends JFileChooser { private static final long serialVersionUID = -1954689476383812988L; public JDirectoryChooser() { super(); setDialogType(CUSTOM_DIALOG); setDialogTitle(I18nUtils.localizedStringForKey("dlg_select_dir_title")); //setApproveButtonText("Select Directory"); setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); setAcceptAllFileFilterUsed(false); addChoosableFileFilter(new FileFilter() { @Override public boolean accept(File f) { return f.isDirectory(); } @Override public String getDescription() { return I18nUtils.localizedStringForKey("dlg_select_dir_description"); } }); } @Override public void approveSelection() { if (!this.getFileFilter().accept(this.getSelectedFile())) return; super.approveSelection(); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/components/JBookmarkMenuItem.java0000644000175000017500000000270112122526604031400 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.components; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JMenuItem; import mobac.gui.MainGUI; import mobac.program.model.Bookmark; public class JBookmarkMenuItem extends JMenuItem implements ActionListener { private final Bookmark bookmark; public JBookmarkMenuItem(Bookmark bookmark) { super(bookmark.toString()); this.bookmark = bookmark; addActionListener(this); } public void actionPerformed(ActionEvent paramActionEvent) { MainGUI.getMainGUI().previewMap.gotoPositionBookmark(bookmark); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/components/JObjectCheckBox.java0000644000175000017500000000367712122526604031021 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.components; import javax.swing.Action; import javax.swing.Icon; import javax.swing.JCheckBox; /** * An extended {@link JCheckBox} implementation that allows to link one user * object to the checkbox. * * @param * type of the user object linked/stored with the checkbox */ public class JObjectCheckBox extends JCheckBox { private static final long serialVersionUID = 1L; private E object; public JObjectCheckBox(Icon icon) { super(icon); } public JObjectCheckBox(String text) { super(text); } public JObjectCheckBox(Action a) { super(a); } public JObjectCheckBox(Icon icon, boolean selected) { super(icon, selected); } public JObjectCheckBox(String text, boolean selected) { super(text, selected); } public JObjectCheckBox(String text, Icon icon) { super(text, icon); } public JObjectCheckBox(String text, Icon icon, boolean selected) { super(text, icon, selected); } public E getObject() { return object; } public void setObject(E object) { this.object = object; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/gpxtree/0000755000175000017500000000000012127544350024506 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/gpxtree/GpxRootEntry.java0000644000175000017500000000407212127544350030000 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.gpxtree; import mobac.data.gpx.gpx11.Gpx; import mobac.data.gpx.gpx11.MetadataType; import mobac.gui.mapview.layer.GpxLayer; import mobac.utilities.I18nUtils; public class GpxRootEntry extends GpxEntry { public GpxRootEntry(GpxLayer layer) { this.setLayer(layer); this.setWaypointParent(true); } public String toString() { String name = getMetaDataName(); if (name != null && !name.equals("")) { return name; } else { if (getLayer().getFile() == null) { return I18nUtils.localizedStringForKey("rp_gpx_root_default_name_nofile"); } else { return String.format(I18nUtils.localizedStringForKey("rp_gpx_root_default_name_hasfile"), getLayer() .getFile().getName()); } } } public String getMetaDataName() { try { return getLayer().getGpx().getMetadata().getName(); } catch (NullPointerException e) { return null; } } public void setMetaDataName(String name) { Gpx gpx = getLayer().getGpx(); if (gpx.getMetadata() == null) gpx.setMetadata(new MetadataType()); gpx.getMetadata().setName(name); // Notify the model about the changed node text getLayer().getPanel().getTreeModel().nodeChanged(getNode()); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/gpxtree/GpxEntry.java0000644000175000017500000000376212122526604027136 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.gpxtree; import javax.swing.tree.DefaultMutableTreeNode; import mobac.gui.mapview.layer.GpxLayer; /** * Generalized entry in the gpx tree. All actual entries derive from this class. The class encapsulates everything * gui-related as well as the actual gpx data for the editor. Subclasses: {@link GpxRootEntry}, {@link TrkEntry}, * {@link RteEntry}, {@link WptEntry} * * @author lhoeppner * */ public class GpxEntry { private DefaultMutableTreeNode node; private GpxLayer layer; /** determines whether an entry can be a parent for waypoints */ private boolean isWaypointParent = false; public void setLayer(GpxLayer layer) { this.layer = layer; } public GpxLayer getLayer() { return layer; } /** * Remembers the associated tree node. * * @param node */ public void setNode(DefaultMutableTreeNode node) { this.node = node; } public DefaultMutableTreeNode getNode() { return node; } public void setWaypointParent(boolean isWaypointParent) { this.isWaypointParent = isWaypointParent; } public boolean isWaypointParent() { return isWaypointParent; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/gpxtree/RteEntry.java0000644000175000017500000000313712127544350027131 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.gpxtree; import mobac.data.gpx.gpx11.RteType; import mobac.gui.mapview.layer.GpxLayer; import mobac.utilities.I18nUtils; public class RteEntry extends GpxEntry { private RteType rte; public RteEntry(RteType rte, GpxLayer layer) { this.setRte(rte); this.setLayer(layer); this.setWaypointParent(true); } public String toString() { String name = ""; try { name = getRte().getName(); } catch (NullPointerException e) { // no name set } if (name != null && !name.equals("")) { return name; } else { return I18nUtils.localizedStringForKey("rp_gpx_unname_route_name"); } } private void setRte(RteType rte) { this.rte = rte; } public RteType getRte() { return rte; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/gpxtree/WptEntry.java0000644000175000017500000000276712127544350027161 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.gpxtree; import mobac.data.gpx.gpx11.WptType; import mobac.gui.mapview.layer.GpxLayer; import mobac.utilities.I18nUtils; public class WptEntry extends GpxEntry { private WptType wpt; public WptEntry(WptType wpt, GpxLayer layer) { this.wpt = wpt; this.setLayer(layer); } public String toString() { String name = ""; try { name = wpt.getName(); } catch (NullPointerException e) { // no name set } if (name != null && !name.equals("")) { return name; } else { return I18nUtils.localizedStringForKey("rp_gpx_unname_wpt_name"); } } public WptType getWpt() { return wpt; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/gpxtree/TrkEntry.java0000644000175000017500000000303312127544350027132 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.gpxtree; import mobac.data.gpx.gpx11.TrkType; import mobac.gui.mapview.layer.GpxLayer; import mobac.utilities.I18nUtils; public class TrkEntry extends GpxEntry { private TrkType trk; public TrkEntry(TrkType trk, GpxLayer layer) { this.trk = trk; this.setLayer(layer); this.setWaypointParent(false); } public String toString() { String name = ""; try { name = trk.getName(); } catch (NullPointerException e) { // no name set } if (name != null && !name.equals("")) { return name; } else { return I18nUtils.localizedStringForKey("rp_gpx_unname_track_name"); } } public TrkType getTrk() { return trk; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/gpxtree/TrksegEntry.java0000644000175000017500000000272712127544350027642 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.gpxtree; import mobac.data.gpx.gpx11.TrksegType; import mobac.gui.mapview.layer.GpxLayer; import mobac.utilities.I18nUtils; public class TrksegEntry extends GpxEntry { private TrksegType trkseg; private String name; public TrksegEntry(TrksegType trkseg, int segnum, GpxLayer layer) { this.trkseg = trkseg; this.name = String.format(I18nUtils.localizedStringForKey("rp_gpx_node_seg_name"), Integer.toString(segnum)); this.setLayer(layer); this.setWaypointParent(true); } public String toString() { return name; } public TrksegType getTrkSeg() { return trkseg; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/gpxtree/GpxTreeListener.java0000644000175000017500000000577612127544350030454 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.gpxtree; import java.awt.Component; import java.awt.event.ActionEvent; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import javax.swing.JTree; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreePath; import mobac.gui.actions.GpxElementListener; import mobac.utilities.I18nUtils; /** * Listener for the gpx editor tree. * * @author lhoeppner * */ public class GpxTreeListener implements MouseListener { private JPopupMenu popup; public void actionPerformed(ActionEvent e) { } public void mouseClicked(MouseEvent e) { } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void mousePressed(MouseEvent e) { if (e.isPopupTrigger()) { showPopup(e); } } public void mouseReleased(MouseEvent e) { if (e.isPopupTrigger()) { showPopup(e); } } /** * Popup for all elements in the gpx tree. TODO separate for waypoints, files, tracks and routes * * @param e */ private void showPopup(MouseEvent e) { JTree tree = (JTree) e.getSource(); TreePath selPath = tree.getPathForLocation(e.getX(), e.getY()); tree.setSelectionPath(selPath); if (selPath == null) return; DefaultMutableTreeNode node = (DefaultMutableTreeNode) selPath.getLastPathComponent(); GpxEntry gpxEntry = null; try { gpxEntry = (GpxEntry) node.getUserObject(); gpxEntry.setNode(node); } catch (ClassCastException exc) { } popup = new JPopupMenu(); JMenuItem delete = new JMenuItem(I18nUtils.localizedStringForKey("rp_gpx_pop_menu_delete_element")); delete.setName(GpxElementListener.MENU_NAME_DELETE); GpxElementListener listener = new GpxElementListener(gpxEntry); delete.addMouseListener(listener); popup.add(delete); JMenuItem rename = new JMenuItem(I18nUtils.localizedStringForKey("rp_gpx_pop_menu_rename_element")); rename.setName(GpxElementListener.MENU_NAME_RENAME); rename.addMouseListener(listener); popup.add(rename); popup.show((Component) e.getSource(), e.getX(), e.getY()); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/actions/0000755000175000017500000000000012127544346024475 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/actions/DebugShowMapSourceNames.java0000644000175000017500000000772412127544346032044 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.actions; import java.awt.Dimension; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.table.AbstractTableModel; import mobac.gui.MainGUI; import mobac.mapsources.MapSourcesManager; import mobac.program.interfaces.MapSource; import mobac.program.model.MapSourceLoaderInfo; import mobac.utilities.I18nUtils; public class DebugShowMapSourceNames implements ActionListener { public void actionPerformed(ActionEvent e) { ArrayList mapSources = new ArrayList(MapSourcesManager.getInstance() .getAllAvailableMapSources()); Collections.sort(mapSources, new Comparator() { public int compare(MapSource o1, MapSource o2) { return o1.getName().compareTo(o2.getName()); } }); JFrame dialog = new JFrame(I18nUtils.localizedStringForKey("dlg_show_source_title")); dialog.setLocationRelativeTo(MainGUI.getMainGUI()); dialog.setLocation(100, 40); Dimension dScreen = Toolkit.getDefaultToolkit().getScreenSize(); dScreen.height -= 200; dScreen.width = Math.min(dScreen.width - 100, 700); dialog.setSize(dScreen); dialog.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); JTable mapSourcesTable = new JTable(new MapSourcesTableModel(mapSources)); JScrollPane scroller = new JScrollPane(mapSourcesTable); mapSourcesTable.getColumnModel().getColumn(2).setMaxWidth(100); dialog.add(scroller); dialog.setVisible(true); } static class MapSourcesTableModel extends AbstractTableModel { List mapSources; public MapSourcesTableModel(List mapSources) { super(); this.mapSources = mapSources; } public int getRowCount() { return mapSources.size(); } public int getColumnCount() { return 4; } @Override public String getColumnName(int column) { switch (column) { case 0: return I18nUtils.localizedStringForKey("dlg_show_source_column_name"); case 1: return I18nUtils.localizedStringForKey("dlg_show_source_column_display_text"); case 2: return I18nUtils.localizedStringForKey("dlg_show_source_column_rev"); case 3: return I18nUtils.localizedStringForKey("dlg_show_source_column_type"); default: return null; } } public Object getValueAt(int rowIndex, int columnIndex) { MapSource ms = mapSources.get(rowIndex); MapSourceLoaderInfo li; switch (columnIndex) { case 0: return ms.getName(); case 1: return ms.toString(); case 2: li = ms.getLoaderInfo(); if (li == null) return null; return li.getRevision(); case 3: li = ms.getLoaderInfo(); if (li == null) return null; String s = ""; File f = li.getSourceFile(); if (f != null) s += f.getName() + " / "; return s + li.getLoaderType(); default: return null; } } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/actions/DebugShowMapTileGrid.java0000644000175000017500000000273112122526604031304 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.actions; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JCheckBoxMenuItem; import mobac.gui.MainGUI; import mobac.gui.mapview.PreviewMap; public class DebugShowMapTileGrid implements ActionListener { public void actionPerformed(ActionEvent e) { PreviewMap previewMap = MainGUI.getMainGUI().previewMap; previewMap.setTileGridVisible(!previewMap.isTileGridVisible()); if (e.getSource() instanceof JCheckBoxMenuItem) { JCheckBoxMenuItem m = (JCheckBoxMenuItem) e.getSource(); m.setSelected(previewMap.isTileGridVisible()); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/actions/AtlasCreate.java0000644000175000017500000000404312127544346027531 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.actions; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JOptionPane; import mobac.exceptions.AtlasTestException; import mobac.gui.atlastree.JAtlasTree; import mobac.program.AtlasThread; import mobac.program.interfaces.AtlasInterface; import mobac.utilities.I18nUtils; public class AtlasCreate implements ActionListener { private JAtlasTree jAtlasTree; public AtlasCreate(JAtlasTree jAtlasTree) { this.jAtlasTree = jAtlasTree; } public void actionPerformed(ActionEvent event) { if (!jAtlasTree.testAtlasContentValid()) return; try { // We have to work on a deep clone otherwise the user would be // able to modify settings of maps, layers and the atlas itself // while the AtlasThread works on that atlas reference AtlasInterface atlasToCreate = jAtlasTree.getAtlas().deepClone(); Thread atlasThread = new AtlasThread(atlasToCreate); atlasThread.start(); } catch (AtlasTestException e) { JOptionPane.showMessageDialog(null, "" + e.getMessage() + "", I18nUtils.localizedStringForKey("msg_convert_incompatible_format"), JOptionPane.ERROR_MESSAGE); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/actions/ShowAboutDialog.java0000644000175000017500000000221712122526604030365 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.actions; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import mobac.gui.dialogs.AboutDialog; public class ShowAboutDialog implements ActionListener { public void actionPerformed(ActionEvent e) { new AboutDialog().setVisible(true); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/actions/ShowReadme.java0000644000175000017500000000341512127544346027401 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.actions; import java.awt.Desktop; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.IOException; import javax.swing.JOptionPane; import mobac.gui.MainGUI; import mobac.program.DirectoryManager; import mobac.utilities.GUIExceptionHandler; import mobac.utilities.I18nUtils; public class ShowReadme implements ActionListener { public void actionPerformed(ActionEvent event) { File readme = new File(DirectoryManager.programDir, "README.HTM"); if (!readme.isFile()) { JOptionPane.showMessageDialog(MainGUI.getMainGUI(), I18nUtils.localizedStringForKey("msg_no_found_readme_file"), I18nUtils.localizedStringForKey("Error"), JOptionPane.ERROR_MESSAGE); return; } try { Desktop.getDesktop().browse(readme.toURI()); } catch (IOException e) { GUIExceptionHandler.processException(e); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/actions/GpxElementListener.java0000644000175000017500000001316112127544346031120 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.actions; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import mobac.data.gpx.gpx11.WptType; import mobac.gui.MainGUI; import mobac.gui.gpxtree.GpxEntry; import mobac.gui.gpxtree.GpxRootEntry; import mobac.gui.gpxtree.RteEntry; import mobac.gui.gpxtree.TrkEntry; import mobac.gui.gpxtree.TrksegEntry; import mobac.gui.gpxtree.WptEntry; import mobac.gui.mapview.PreviewMap; import mobac.gui.mapview.controller.GpxMapController; import mobac.utilities.I18nUtils; /** * Listener for the gpx editor tree elements. * * @author lhoeppner * @author r_x * */ public class GpxElementListener implements MouseListener { public static final String MENU_NAME_RENAME = I18nUtils.localizedStringForKey("rp_gpx_menu_rename"); public static final String MENU_NAME_DELETE = I18nUtils.localizedStringForKey("rp_gpx_menu_delete"); private final GpxEntry gpxEntry; private GpxMapController mapController = null; private GpxEditor editor = GpxEditor.getInstance(); public GpxElementListener(GpxEntry gpxEntry) { this.gpxEntry = gpxEntry; } public void mouseClicked(MouseEvent e) { } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void mousePressed(MouseEvent e) { handleClick(e); } public void mouseReleased(MouseEvent e) { handleClick(e); } private void handleClick(MouseEvent e) { JMenuItem item = (JMenuItem) e.getSource(); if (item == null) return; if (MENU_NAME_RENAME.equals(item.getName())) { renameEntry(); } else if (MENU_NAME_DELETE.equals(item.getName())) { removeEntry(); } } /** * Removes an entry (wpt, trk, trkseg, rte) from a gpx file (and the displayed layer) Currently only works for * waypoints. * */ private void removeEntry() { int answer = JOptionPane.showConfirmDialog(null, I18nUtils.localizedStringForKey("rp_gpx_msg_confim_delete"), I18nUtils.localizedStringForKey("rp_gpx_msg_confim_delete_title"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); if (answer == JOptionPane.YES_OPTION) { PreviewMap map = MainGUI.getMainGUI().previewMap; map.getMapSelectionController().disable(); if (mapController == null) mapController = new GpxMapController(map, gpxEntry.getLayer().getPanel(), false); mapController.enable(); if (gpxEntry.getClass().equals(RteEntry.class)) { // RteEntry rte = (RteEntry) gpxEntry; } else if (gpxEntry.getClass().equals(TrkEntry.class)) { // TrkEntry trk = (TrkEntry) gpxEntry; } else if (gpxEntry.getClass().equals(WptEntry.class)) { WptEntry wptEntry = (WptEntry) gpxEntry; WptType wpt = wptEntry.getWpt(); editor.findWptAndDelete(wpt, gpxEntry); wptEntry.getLayer().getPanel().removeWpt(wptEntry); mapController.repaint(); } else if (gpxEntry.getClass().equals(GpxRootEntry.class)) { // GpxRootEntry root = (GpxRootEntry) gpxEntry; } } else { return; } } /** * Renames (if possible) the entry according to user input. * */ private void renameEntry() { if (gpxEntry.getClass().equals(TrksegEntry.class)) { JOptionPane.showMessageDialog(null, I18nUtils.localizedStringForKey("rp_gpx_msg_can_not_rename_track"), I18nUtils.localizedStringForKey("Error"), JOptionPane.INFORMATION_MESSAGE); return; } else { if (gpxEntry.getClass().equals(RteEntry.class)) { RteEntry rte = (RteEntry) gpxEntry; String name = JOptionPane.showInputDialog(null, I18nUtils.localizedStringForKey("rp_gpx_rename_element_title"), rte.getRte().getName()); if (name == null) { return; } rte.getRte().setName(name); } else if (gpxEntry.getClass().equals(TrkEntry.class)) { TrkEntry trk = (TrkEntry) gpxEntry; String name = JOptionPane.showInputDialog(null, I18nUtils.localizedStringForKey("rp_gpx_rename_element_title"), trk.getTrk().getName()); if (name == null) { return; } trk.getTrk().setName(name); } else if (gpxEntry.getClass().equals(WptEntry.class)) { WptEntry wpt = (WptEntry) gpxEntry; String name = JOptionPane.showInputDialog(null, I18nUtils.localizedStringForKey("rp_gpx_rename_element_title"), wpt.getWpt().getName()); if (name == null) { return; } wpt.getWpt().setName(name); } else if (gpxEntry.getClass().equals(GpxRootEntry.class)) { GpxRootEntry root = (GpxRootEntry) gpxEntry; String initialValue = root.getMetaDataName(); String name = JOptionPane.showInputDialog(null, I18nUtils.localizedStringForKey("rp_gpx_rename_element_title"), initialValue); if (name == null) { return; } root.setMetaDataName(name); } } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/actions/RefreshCustomMapsources.java0000644000175000017500000000424112127544346032174 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.actions; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JOptionPane; import mobac.gui.MainGUI; import mobac.mapsources.MapSourcesManager; import mobac.program.interfaces.FileBasedMapSource; import mobac.program.interfaces.MapSource; import mobac.utilities.I18nUtils; public class RefreshCustomMapsources implements ActionListener { public void actionPerformed(ActionEvent e) { MapSourcesManager manager = MapSourcesManager.getInstance(); MainGUI gui = MainGUI.getMainGUI(); MapSource selectedMapSource = gui.getSelectedMapSource(); boolean updateGui = false; int count = 0; for (MapSource mapSource : manager.getAllAvailableMapSources()) { if (mapSource instanceof FileBasedMapSource) { FileBasedMapSource fbms = (FileBasedMapSource) mapSource; fbms.reinitialize(); count++; if (mapSource.equals(selectedMapSource)) updateGui = true; } } if (updateGui) { /* * The currently selected map source was updated - we have to force an GUI update in case the available zoom * levels has been changed */ gui.mapSourceChanged(selectedMapSource); } JOptionPane.showMessageDialog(gui, String.format(I18nUtils.localizedStringForKey("msg_refresh_all_map_source_done"), count)); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/actions/HelpLicenses.java0000644000175000017500000000222212122526604027704 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.actions; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import mobac.gui.dialogs.LicensesDialog; public class HelpLicenses implements ActionListener { public void actionPerformed(ActionEvent e) { new LicensesDialog().setVisible(true); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/actions/SelectionModeRectangle.java0000644000175000017500000000254512122526604031715 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.actions; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import mobac.gui.MainGUI; import mobac.gui.mapview.PreviewMap; import mobac.gui.mapview.controller.RectangleSelectionMapController; public class SelectionModeRectangle implements ActionListener { public void actionPerformed(ActionEvent e) { PreviewMap previewMap = MainGUI.getMainGUI().previewMap; previewMap.setMapSelectionController(new RectangleSelectionMapController(previewMap)); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/actions/GpxEditor.java0000644000175000017500000000735012122526604027242 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.actions; import java.util.List; import javax.swing.tree.DefaultMutableTreeNode; import mobac.data.gpx.gpx11.Gpx; import mobac.data.gpx.gpx11.RteType; import mobac.data.gpx.gpx11.TrkType; import mobac.data.gpx.gpx11.TrksegType; import mobac.data.gpx.gpx11.WptType; import mobac.gui.gpxtree.GpxEntry; import mobac.gui.gpxtree.RteEntry; import mobac.gui.gpxtree.TrkEntry; import mobac.gui.gpxtree.TrksegEntry; /** * Encapsulates all functionality regarding edits of loaded gpx files. * * @author lhoeppner * */ public class GpxEditor { private static GpxEditor editor = null; public static GpxEditor getInstance() { if (editor == null) { editor = new GpxEditor(); } return editor; } /** * Adds a wpt to the selected route. * * @param entry * @param wpt */ public void findRteAndAdd(RteEntry entry, WptType wpt) { List rtes = entry.getLayer().getGpx().getRte(); RteType rteParent = (entry).getRte(); for (RteType rte : rtes) { if (rte.equals(rteParent)) { rte.getRtept().add(wpt); } } } /** * Adds a wpt to the selected track segment. * * @param entry * @param wpt */ public void findTrksegAndAdd(TrksegEntry entry, WptType wpt) { // get the track the selected track segment belongs to DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode) entry.getNode().getParent(); TrkEntry trkParent = (TrkEntry) parentNode.getUserObject(); // get the selected track segment TrksegType trksegParent = entry.getTrkSeg(); List trksegs = trkParent.getTrk().getTrkseg(); for (TrksegType trkseg : trksegs) { if (trkseg.equals(trksegParent)) { trkseg.getTrkpt().add(wpt); } } } /** * Removes a waypoint from the Gpx assigned to the layer. * * @param wpt * - the node to be removed * @return - true if wpt found and deleted, false otherwise */ public boolean findWptAndDelete(WptType wpt, GpxEntry gpxEntry) { Gpx gpx = gpxEntry.getLayer().getGpx(); // wpts List wpts = gpx.getWpt(); for (WptType currentWpt : wpts) { if (currentWpt.equals(wpt)) { wpts.remove(currentWpt); return true; } } // trks List trks = gpx.getTrk(); for (TrkType currentTrk : trks) { List trksegs = currentTrk.getTrkseg(); for (TrksegType currentTrkseg : trksegs) { wpts = currentTrkseg.getTrkpt(); for (WptType currentWpt : wpts) { if (currentWpt.equals(wpt)) { wpts.remove(currentWpt); return true; } } } } // rtes List rtes = gpx.getRte(); for (RteType currentRte : rtes) { wpts = currentRte.getRtept(); for (WptType currentWpt : wpts) { if (currentWpt.equals(wpt)) { wpts.remove(currentWpt); return true; } } } return false; // if the node wasn't found } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/actions/DebugShowLogFile.java0000644000175000017500000000432112127544346030471 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.actions; import java.awt.Desktop; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.IOException; import javax.swing.JOptionPane; import mobac.gui.MainGUI; import mobac.program.Logging; import mobac.utilities.GUIExceptionHandler; import mobac.utilities.I18nUtils; import org.apache.log4j.Logger; public class DebugShowLogFile implements ActionListener { public void actionPerformed(ActionEvent event) { Logger log = Logger.getLogger(DebugShowLogFile.class); String logFile = Logging.getLogFile(); if (logFile == null) { log.error("No file logger configured"); JOptionPane.showMessageDialog(MainGUI.getMainGUI(), I18nUtils.localizedStringForKey("msg_no_log_file_config"), I18nUtils.localizedStringForKey("Error"), JOptionPane.ERROR_MESSAGE); return; } File f = new File(logFile); if (!f.isFile()) { log.error("Log file does not exists: " + f.getAbsolutePath()); JOptionPane.showMessageDialog(MainGUI.getMainGUI(), String.format(I18nUtils.localizedStringForKey("msg_no_log_file"), f.getAbsolutePath()), I18nUtils.localizedStringForKey("Error"), JOptionPane.ERROR_MESSAGE); return; } try { Desktop.getDesktop().open(f); } catch (IOException e) { GUIExceptionHandler.processException(e); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/actions/GpxSave.java0000644000175000017500000000641512127544346026723 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.actions; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import javax.swing.JFileChooser; import javax.swing.JOptionPane; import javax.xml.bind.JAXBException; import mobac.data.gpx.GPXUtils; import mobac.data.gpx.gpx11.Gpx; import mobac.gui.MainGUI; import mobac.gui.gpxtree.GpxEntry; import mobac.gui.panels.JGpxPanel; import mobac.program.model.Settings; import mobac.utilities.I18nUtils; import mobac.utilities.file.GpxFileFilter; public class GpxSave implements ActionListener { private JGpxPanel panel; private boolean saveAs; public GpxSave(JGpxPanel panel) { this(panel, false); } /** * * @param panel * @param saveAs * if true a file chooser dialog is displayed where the user can * change the filename */ public GpxSave(JGpxPanel panel, boolean saveAs) { super(); this.panel = panel; this.saveAs = saveAs; } public void actionPerformed(ActionEvent event) { GpxEntry entry = panel.getSelectedEntry(); if (entry == null) { JOptionPane.showMessageDialog(null, I18nUtils.localizedStringForKey("rp_gpx_msg_error_save_gpx_file"), I18nUtils.localizedStringForKey("rp_gpx_msg_no_select_file"), JOptionPane.ERROR_MESSAGE); return; } if (!GPXUtils.checkJAXBVersion()) return; Gpx gpx = entry.getLayer().getGpx(); try { File f = entry.getLayer().getFile(); if (saveAs || f == null) f = selectFile(f); if (f == null) return; if (!f.getName().toLowerCase().endsWith(".gpx")) f = new File(f.getAbsolutePath() + ".gpx"); entry.getLayer().setFile(f); GPXUtils.saveGpxFile(gpx, f); } catch (JAXBException e) { throw new RuntimeException(e); } MainGUI.getMainGUI().previewMap.repaint(); } private File selectFile(File f) { JFileChooser fc = new JFileChooser(); try { File dir = new File(Settings.getInstance().gpxFileChooserDir); if (f == null) fc.setCurrentDirectory(dir); // restore the saved directory else fc.setSelectedFile(f); } catch (Exception e) { } fc.addChoosableFileFilter(new GpxFileFilter(true)); int returnVal = fc.showSaveDialog(MainGUI.getMainGUI()); if (returnVal != JFileChooser.APPROVE_OPTION) return null; Settings.getInstance().gpxFileChooserDir = fc.getCurrentDirectory().getAbsolutePath(); return fc.getSelectedFile(); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/actions/AddPolygonMapLayer.java0000644000175000017500000000735012127544346031040 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.actions; import java.awt.Point; import java.awt.Polygon; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.List; import javax.swing.JOptionPane; import mobac.exceptions.InvalidNameException; import mobac.gui.MainGUI; import mobac.gui.atlastree.JAtlasTree; import mobac.gui.mapview.JMapViewer; import mobac.gui.mapview.controller.AbstractPolygonSelectionMapController; import mobac.program.interfaces.AtlasInterface; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSpace; import mobac.program.model.Layer; import mobac.program.model.MapPolygon; import mobac.program.model.SelectedZoomLevels; import mobac.program.model.TileImageParameters; import mobac.utilities.I18nUtils; public class AddPolygonMapLayer implements ActionListener { public void actionPerformed(ActionEvent event) { MainGUI mg = MainGUI.getMainGUI(); AbstractPolygonSelectionMapController msc = (AbstractPolygonSelectionMapController) mg.previewMap .getMapSelectionController(); JAtlasTree jAtlasTree = mg.jAtlasTree; final String mapNameFmt = "%s %02d"; AtlasInterface atlasInterface = jAtlasTree.getAtlas(); String name = mg.getUserText(); MapSource mapSource = mg.getSelectedMapSource(); MapSpace mapSpace = mapSource.getMapSpace(); SelectedZoomLevels sZL = mg.getSelectedZoomLevels(); int[] zoomLevels = sZL.getZoomLevels(); if (zoomLevels.length == 0) { JOptionPane.showMessageDialog(mg, I18nUtils.localizedStringForKey("msg_no_zoom_level_selected")); return; } String layerName = name; Layer layer = null; int c = 1; boolean success = false; do { try { layer = new Layer(atlasInterface, layerName); success = true; } catch (InvalidNameException e) { layerName = name + "_" + Integer.toString(c++); } } while (!success); List polygonPoints = msc.getPolygonPoints(); for (int zoom : zoomLevels) { int xpoints[] = new int[polygonPoints.size()]; int ypoints[] = new int[polygonPoints.size()]; for (int i = 0; i < xpoints.length; i++) { Point p = mapSpace.changeZoom(polygonPoints.get(i), JMapViewer.MAX_ZOOM, zoom); xpoints[i] = p.x; ypoints[i] = p.y; } TileImageParameters customTileParameters = mg.getSelectedTileImageParameters(); Polygon polygon = new Polygon(xpoints, ypoints, xpoints.length); // Rectangle bounds = polygon.getBounds(); // int maxMapSize = Settings.getInstance().maxMapSize; // System.out.println(bounds.height + " " + bounds.width); String mapName = String.format(mapNameFmt, new Object[] { layerName, zoom }); MapPolygon map = new MapPolygon(layer, mapName, mapSource, zoom, polygon, customTileParameters); layer.addMap(map); } atlasInterface.addLayer(layer); jAtlasTree.getTreeModel().notifyNodeInsert(layer); msc.finishPolygon(); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/actions/GpxClear.java0000644000175000017500000000326212122526604027040 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.actions; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Iterator; import mobac.gui.MainGUI; import mobac.gui.mapview.interfaces.MapLayer; import mobac.gui.mapview.layer.GpxLayer; import mobac.gui.panels.JGpxPanel; /** * Deletes all loaded {@link GpxLayer}s from the main map viewer. * */ public class GpxClear implements ActionListener { JGpxPanel panel; public GpxClear(JGpxPanel panel) { super(); this.panel = panel; } public void actionPerformed(ActionEvent e) { Iterator mapLayers = MainGUI.getMainGUI().previewMap.mapLayers.iterator(); while (mapLayers.hasNext()) { if (mapLayers.next() instanceof GpxLayer) mapLayers.remove(); } panel.resetModel(); MainGUI.getMainGUI().previewMap.repaint(); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/actions/SelectionModeCircle.java0000644000175000017500000000255412122526604031212 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.actions; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import mobac.gui.MainGUI; import mobac.gui.mapview.PreviewMap; import mobac.gui.mapview.controller.PolygonCircleSelectionMapController; public class SelectionModeCircle implements ActionListener { public void actionPerformed(ActionEvent e) { PreviewMap previewMap = MainGUI.getMainGUI().previewMap; previewMap.setMapSelectionController(new PolygonCircleSelectionMapController(previewMap)); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/actions/BookmarkManage.java0000644000175000017500000000245212122526604030211 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.actions; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import mobac.gui.MainGUI; import mobac.gui.dialogs.ManageBookmarks; public class BookmarkManage implements ActionListener { public void actionPerformed(ActionEvent event) { ManageBookmarks mb = new ManageBookmarks(MainGUI.getMainGUI()); mb.setModal(true); mb.setVisible(true); MainGUI.getMainGUI().updateBookmarksMenu(); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/actions/AddMapLayer.java0000644000175000017500000000335612122526604027462 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.actions; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import mobac.gui.MainGUI; import mobac.gui.mapview.controller.AbstractPolygonSelectionMapController; import mobac.gui.mapview.controller.JMapController; import mobac.gui.mapview.controller.RectangleSelectionMapController; public class AddMapLayer implements ActionListener { public static final AddMapLayer INSTANCE = new AddMapLayer(); public void actionPerformed(ActionEvent event) { JMapController msc = MainGUI.getMainGUI().previewMap.getMapSelectionController(); if (msc instanceof RectangleSelectionMapController) new AddRectangleMapAutocut().actionPerformed(event); else if (msc instanceof AbstractPolygonSelectionMapController) new AddPolygonMapLayer().actionPerformed(event); else throw new RuntimeException("Unknown mapSelectionController type"); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/actions/GpxNew.java0000644000175000017500000000325012122526604026540 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.actions; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import mobac.data.gpx.GPXUtils; import mobac.data.gpx.gpx11.Gpx; import mobac.gui.MainGUI; import mobac.gui.gpxtree.GpxRootEntry; import mobac.gui.mapview.layer.GpxLayer; import mobac.gui.panels.JGpxPanel; //import mobac.gui.panels.JGpxPanel.ListModelEntry; public class GpxNew implements ActionListener { JGpxPanel panel; public GpxNew(JGpxPanel panel) { super(); this.panel = panel; } public void actionPerformed(ActionEvent event) { if (!GPXUtils.checkJAXBVersion()) return; newGpx(); MainGUI.getMainGUI().previewMap.repaint(); } public GpxRootEntry newGpx() { Gpx gpx = Gpx.createGpx(); GpxLayer gpxLayer = new GpxLayer(gpx); return panel.addGpxLayer(gpxLayer); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/actions/DebugSetLogLevel.java0000644000175000017500000000312012122526604030460 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.actions; import java.awt.Component; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JMenu; import javax.swing.JMenuItem; import mobac.gui.MainGUI; import org.apache.log4j.Level; import org.apache.log4j.Logger; public class DebugSetLogLevel implements ActionListener { public void actionPerformed(ActionEvent event) { Logger log = Logger.getRootLogger(); JMenuItem menuItem = (JMenuItem) event.getSource(); log.setLevel(Level.toLevel(menuItem.getName())); JMenu menu = MainGUI.getMainGUI().logLevelMenu; Component[] c = menu.getMenuComponents(); for (int i = 0; i < c.length; i++) { ((JMenuItem) c[i]).setSelected(c[i] == menuItem); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/actions/PanelShowHide.java0000644000175000017500000000236112122526604030024 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.actions; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JPanel; public class PanelShowHide implements ActionListener { private JPanel panel; public PanelShowHide(JPanel panel) { super(); this.panel = panel; } public void actionPerformed(ActionEvent e) { panel.setVisible(!panel.isVisible()); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/actions/OpenInWebbrowser.java0000644000175000017500000000373512122526604030572 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.actions; import java.awt.Desktop; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import mobac.program.Logging; public class OpenInWebbrowser implements ActionListener, MouseListener { URI uri; public OpenInWebbrowser(URI uri) { super(); this.uri = uri; } public OpenInWebbrowser(String uri) throws URISyntaxException { super(); this.uri = new URI(uri); } public void actionPerformed(ActionEvent event) { if (Desktop.isDesktopSupported()) { Desktop desktop = Desktop.getDesktop(); try { desktop.browse(uri); } catch (IOException e) { Logging.LOG.error("Failed to open web browser",e); } } } public void mouseReleased(MouseEvent e) { actionPerformed(null); } public void mouseClicked(MouseEvent e) { } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void mousePressed(MouseEvent e) { } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/actions/GpxLoad.java0000644000175000017500000001301212127544346026673 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.actions; import java.awt.Component; import java.awt.Cursor; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import javax.swing.JDialog; import javax.swing.JFileChooser; import javax.swing.JOptionPane; import javax.swing.JProgressBar; import javax.swing.SwingUtilities; import javax.swing.WindowConstants; import javax.xml.bind.JAXBException; import mobac.data.gpx.GPXUtils; import mobac.data.gpx.gpx11.Gpx; import mobac.gui.MainGUI; import mobac.gui.mapview.layer.GpxLayer; import mobac.gui.panels.JGpxPanel; import mobac.program.model.Settings; import mobac.utilities.I18nUtils; import mobac.utilities.file.GpxFileFilter; import org.apache.log4j.Logger; public class GpxLoad implements ActionListener { private Logger log = Logger.getLogger(GpxLoad.class); JGpxPanel panel; public GpxLoad(JGpxPanel panel) { super(); this.panel = panel; } public void actionPerformed(ActionEvent event) { if (!GPXUtils.checkJAXBVersion()) return; JFileChooser fc = new JFileChooser(); try { File dir = new File(Settings.getInstance().gpxFileChooserDir); fc.setCurrentDirectory(dir); // restore the saved directory } catch (Exception e) { } fc.setMultiSelectionEnabled(true); fc.addChoosableFileFilter(new GpxFileFilter(false)); final MainGUI mainGUI = MainGUI.getMainGUI(); int returnVal = fc.showOpenDialog(mainGUI); if (returnVal != JFileChooser.APPROVE_OPTION) return; Settings.getInstance().gpxFileChooserDir = fc.getCurrentDirectory().getAbsolutePath(); File[] f = fc.getSelectedFiles(); // check already opened gpx files boolean dublicates = false; for (File selectedFile : f) { dublicates = panel.isFileOpen(selectedFile.getAbsolutePath()); if (dublicates) break; } if (dublicates) { int answer = JOptionPane.showConfirmDialog(mainGUI, I18nUtils.localizedStringForKey("rp_gpx_msg_confirm_reopen_file"), I18nUtils.localizedStringForKey("Warning"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); if (answer != JOptionPane.YES_OPTION) return; } // process if (f.length > 1) { doMultiLoad(f, mainGUI); } else if (f.length == 1) { doLoad(f[0], mainGUI); } } /** * @param f */ private void doLoad(File f, Component parent) { try { Gpx gpx = GPXUtils.loadGpxFile(f); GpxLayer gpxLayer = new GpxLayer(gpx); gpxLayer.setFile(f); panel.addGpxLayer(gpxLayer); } catch (JAXBException e) { JOptionPane.showMessageDialog(parent, "Unable to load the GPX file
" + f.getAbsolutePath() + "

Please make sure the file is a valid GPX v1.1 file.
" + "
Internal error message:
" + e.getMessage() + "", "GPX loading failed", JOptionPane.ERROR_MESSAGE); throw new RuntimeException(e); } } private void doMultiLoad(final File[] files, final MainGUI mainGUI) { final JDialog progressDialog = new JDialog(mainGUI); // prepare progress dialog progressDialog.setSize(400, 50); progressDialog.setResizable(false); progressDialog.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); progressDialog.setLocation( Math.max(0, (int) (mainGUI.getLocation().getX() + mainGUI.getSize().getWidth() / 2 - 200)), Math.max(0, (int) (mainGUI.getLocation().getY() + mainGUI.getSize().getHeight() / 2 - 25))); final JProgressBar progressBar = new JProgressBar(0, files.length); progressDialog.add(progressBar); mainGUI.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); mainGUI.setEnabled(false); progressDialog.setVisible(true); Thread job = new Thread() { private int counter = 0; public void run() { try { // iterate over files to load for (final File file : files) { counter++; SwingUtilities.invokeLater(new Runnable() { public void run() { progressBar.setValue(counter); progressDialog.setTitle("Processing " + counter + " of " + files.length + " <" + file.getName() + ">"); } }); doLoad(file, progressDialog); } } catch (RuntimeException e) { log.error(e.getMessage(), e); } finally { SwingUtilities.invokeLater(new Runnable() { public void run() { // close progress dialog mainGUI.previewMap.repaint(); mainGUI.setCursor(Cursor.getDefaultCursor()); if (progressDialog != null) { progressDialog.setVisible(false); progressDialog.dispose(); } mainGUI.setEnabled(true); mainGUI.toFront(); } }); } }; }; job.start(); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/actions/AddRectangleMapAutocut.java0000644000175000017500000000666712127544346031677 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.actions; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JOptionPane; import mobac.exceptions.InvalidNameException; import mobac.gui.MainGUI; import mobac.gui.atlastree.JAtlasTree; import mobac.program.Logging; import mobac.program.interfaces.AtlasInterface; import mobac.program.interfaces.MapSource; import mobac.program.model.Layer; import mobac.program.model.MapSelection; import mobac.program.model.SelectedZoomLevels; import mobac.program.model.Settings; import mobac.program.model.TileImageParameters; import mobac.utilities.I18nUtils; public class AddRectangleMapAutocut implements ActionListener { public void actionPerformed(ActionEvent event) { MainGUI mg = MainGUI.getMainGUI(); JAtlasTree jAtlasTree = mg.jAtlasTree; final String mapNameFmt = "%s %02d"; AtlasInterface atlasInterface = jAtlasTree.getAtlas(); String name = mg.getUserText(); MapSource mapSource = mg.getSelectedMapSource(); SelectedZoomLevels sZL = mg.getSelectedZoomLevels(); MapSelection ms = mg.getMapSelectionCoordinates(); if (ms == null) { JOptionPane.showMessageDialog(mg, I18nUtils.localizedStringForKey("msg_no_select_area")); return; } Settings settings = Settings.getInstance(); // String errorText = mg.validateInput(); // if (errorText.length() > 0) { // JOptionPane.showMessageDialog(mg, errorText, "Errors", JOptionPane.ERROR_MESSAGE); // return; // } int[] zoomLevels = sZL.getZoomLevels(); if (zoomLevels.length == 0) { JOptionPane.showMessageDialog(mg, I18nUtils.localizedStringForKey("msg_no_zoom_level_selected")); return; } String layerName = name; Layer layer = null; int c = 1; boolean success = false; do { try { layer = new Layer(atlasInterface, layerName); success = true; } catch (InvalidNameException e) { layerName = name + "_" + Integer.toString(c++); } } while (!success); for (int zoom : zoomLevels) { Point tl = ms.getTopLeftPixelCoordinate(zoom); Point br = ms.getBottomRightPixelCoordinate(zoom); TileImageParameters customTileParameters = mg.getSelectedTileImageParameters(); try { String mapName = String.format(mapNameFmt, new Object[] { layerName, zoom }); layer.addMapsAutocut(mapName, mapSource, tl, br, zoom, customTileParameters, settings.maxMapSize, settings.mapOverlapTiles); } catch (InvalidNameException e) { Logging.LOG.error("", e); } } atlasInterface.addLayer(layer); jAtlasTree.getTreeModel().notifyNodeInsert(layer); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/actions/DebugShowReport.java0000644000175000017500000000231512122526604030414 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.actions; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import mobac.utilities.GUIExceptionHandler; public class DebugShowReport implements ActionListener { public void actionPerformed(ActionEvent e) { GUIExceptionHandler.processException(null, null); // throw new RuntimeException("Test"); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/actions/BookmarkAdd.java0000644000175000017500000000332112127544346027515 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.actions; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JOptionPane; import mobac.gui.MainGUI; import mobac.gui.mapview.PreviewMap; import mobac.program.model.Bookmark; import mobac.program.model.Settings; import mobac.utilities.I18nUtils; public class BookmarkAdd implements ActionListener { private final PreviewMap previewMap; public BookmarkAdd(PreviewMap previewMap) { this.previewMap = previewMap; } public void actionPerformed(ActionEvent arg0) { Bookmark bm = previewMap.getPositionBookmark(); String name = JOptionPane.showInputDialog(I18nUtils.localizedStringForKey("dlg_add_bookmark_msg"), bm.toString()); if (name == null) return; bm.setName(name); Settings.getInstance().placeBookmarks.add(bm); MainGUI.getMainGUI().updateBookmarksMenu(); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/actions/AtlasConvert.java0000644000175000017500000000551512127544346027753 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.actions; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.ListSelectionModel; import mobac.gui.MainGUI; import mobac.program.model.AtlasOutputFormat; import mobac.utilities.I18nUtils; public class AtlasConvert implements ActionListener { public void actionPerformed(ActionEvent event) { MainGUI mg = MainGUI.getMainGUI(); JPanel panel = new JPanel(); BorderLayout layout = new BorderLayout(); layout.setVgap(4); panel.setLayout(layout); JPanel formatPanel = new JPanel(new BorderLayout()); formatPanel.setPreferredSize(new Dimension(250, 300)); formatPanel.add(new JLabel(I18nUtils.localizedStringForKey("dlg_new_atlas_select_format_title")), BorderLayout.NORTH); JList atlasFormatList = new JList(AtlasOutputFormat.getFormatsAsVector()); atlasFormatList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); JScrollPane scroller = new JScrollPane(atlasFormatList); scroller.setPreferredSize(new Dimension(100, 200)); formatPanel.add(scroller, BorderLayout.CENTER); panel.add(formatPanel, BorderLayout.CENTER); AtlasOutputFormat currentAOF = null; try { currentAOF = mg.getAtlas().getOutputFormat(); } catch (Exception e) { } if (currentAOF != null) atlasFormatList.setSelectedValue(currentAOF, true); else atlasFormatList.setSelectedIndex(1); int result = JOptionPane.showConfirmDialog(MainGUI.getMainGUI(), panel, I18nUtils.localizedStringForKey("msg_convert_atlas_format"), JOptionPane.OK_CANCEL_OPTION); if (result != JOptionPane.OK_OPTION) return; AtlasOutputFormat format = (AtlasOutputFormat) atlasFormatList.getSelectedValue(); mg.jAtlasTree.convertAtlas(format); mg.getParametersPanel().atlasFormatChanged(format); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/actions/AtlasNew.java0000644000175000017500000000634012127544346027061 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.actions; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextField; import javax.swing.ListSelectionModel; import mobac.gui.MainGUI; import mobac.program.model.AtlasOutputFormat; import mobac.utilities.I18nUtils; public class AtlasNew implements ActionListener { public void actionPerformed(ActionEvent event) { MainGUI mg = MainGUI.getMainGUI(); JPanel panel = new JPanel(); BorderLayout layout = new BorderLayout(); layout.setVgap(4); panel.setLayout(layout); JPanel formatPanel = new JPanel(new BorderLayout()); formatPanel.add(new JLabel(I18nUtils.localizedStringForKey("dlg_new_atlas_select_format_title")), BorderLayout.NORTH); JList atlasFormatList = new JList(AtlasOutputFormat.getFormatsAsVector()); atlasFormatList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); JScrollPane scroller = new JScrollPane(atlasFormatList); scroller.setPreferredSize(new Dimension(140, 200)); formatPanel.add(scroller, BorderLayout.CENTER); JPanel namePanel = new JPanel(new BorderLayout()); namePanel.add(new JLabel(I18nUtils.localizedStringForKey("dlg_new_atlas_name_title")), BorderLayout.NORTH); JTextField atlasName = new JTextField(I18nUtils.localizedStringForKey("dlg_new_atlas_default_atlas_name")); namePanel.add(atlasName, BorderLayout.SOUTH); panel.add(namePanel, BorderLayout.NORTH); panel.add(formatPanel, BorderLayout.CENTER); panel.setPreferredSize(new Dimension(300, 300)); AtlasOutputFormat currentAOF = null; try { currentAOF = mg.getAtlas().getOutputFormat(); } catch (Exception e) { } if (currentAOF != null) atlasFormatList.setSelectedValue(currentAOF, true); else atlasFormatList.setSelectedIndex(1); int result = JOptionPane.showConfirmDialog(MainGUI.getMainGUI(), panel, I18nUtils.localizedStringForKey("dlg_new_atlas_title"), JOptionPane.OK_CANCEL_OPTION); if (result != JOptionPane.OK_OPTION) return; AtlasOutputFormat format = (AtlasOutputFormat) atlasFormatList.getSelectedValue(); mg.jAtlasTree.newAtlas(atlasName.getText(), format); mg.getParametersPanel().atlasFormatChanged(format); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/actions/GpxAddPoint.java0000644000175000017500000000457612127544346027535 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.actions; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JOptionPane; import mobac.gui.MainGUI; import mobac.gui.gpxtree.GpxEntry; import mobac.gui.mapview.PreviewMap; import mobac.gui.mapview.controller.GpxMapController; import mobac.gui.panels.JGpxPanel; import mobac.utilities.I18nUtils; public class GpxAddPoint implements ActionListener { JGpxPanel panel; private GpxMapController mapController = null; public GpxAddPoint(JGpxPanel panel) { super(); this.panel = panel; } public synchronized void actionPerformed(ActionEvent event) { GpxEntry entry = panel.getSelectedEntry(); if (entry == null) { int answer = JOptionPane.showConfirmDialog(null, I18nUtils.localizedStringForKey("rp_gpx_msg_ask_create_new"), I18nUtils.localizedStringForKey("rp_gpx_msg_ask_create_new_title"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); if (answer != JOptionPane.YES_OPTION) return; entry = new GpxNew(panel).newGpx(); } if (!entry.isWaypointParent()) { JOptionPane.showMessageDialog(null, I18nUtils.localizedStringForKey("rp_gpx_msg_add_point_failed"), I18nUtils.localizedStringForKey("Error"), JOptionPane.INFORMATION_MESSAGE); return; } PreviewMap map = MainGUI.getMainGUI().previewMap; map.getMapSelectionController().disable(); if (mapController == null) mapController = new GpxMapController(map, panel, false); mapController.enable(); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/actions/AddGpxTrackPolygonMap.java0000644000175000017500000001740412127544346031510 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.actions; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.List; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import mobac.data.gpx.gpx11.TrkType; import mobac.data.gpx.gpx11.TrksegType; import mobac.data.gpx.interfaces.GpxPoint; import mobac.exceptions.InvalidNameException; import mobac.gui.MainGUI; import mobac.gui.atlastree.JAtlasTree; import mobac.gui.components.JDistanceSlider; import mobac.gui.gpxtree.GpxEntry; import mobac.gui.gpxtree.GpxRootEntry; import mobac.gui.gpxtree.TrkEntry; import mobac.gui.gpxtree.TrksegEntry; import mobac.program.interfaces.AtlasInterface; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSpace; import mobac.program.model.EastNorthCoordinate; import mobac.program.model.Layer; import mobac.program.model.MapPolygon; import mobac.program.model.SelectedZoomLevels; import mobac.program.model.Settings; import mobac.program.model.TileImageParameters; import mobac.program.model.UnitSystem; import mobac.utilities.I18nUtils; public class AddGpxTrackPolygonMap implements ActionListener { public static final AddGpxTrackPolygonMap INSTANCE = new AddGpxTrackPolygonMap(); public void actionPerformed(ActionEvent event) { MainGUI mg = MainGUI.getMainGUI(); GpxEntry entry = mg.gpxPanel.getSelectedEntry(); if (entry == null) return; TrksegType trk = null; TrkType t = null; if (entry instanceof TrksegEntry) { trk = ((TrksegEntry) entry).getTrkSeg(); } else if (entry instanceof GpxRootEntry) { GpxRootEntry re = (GpxRootEntry) entry; List tlist = re.getLayer().getGpx().getTrk(); if (tlist.size() > 1) { JOptionPane.showMessageDialog(mg, I18nUtils.localizedStringForKey("msg_add_gpx_polygon_too_many_track")); return; } else if (tlist.size() == 1) t = tlist.get(0); } if (entry instanceof TrkEntry) t = ((TrkEntry) entry).getTrk(); if (t != null) { if (t.getTrkseg().size() > 1) { JOptionPane.showMessageDialog(mg, I18nUtils.localizedStringForKey("msg_add_gpx_polygon_too_many_segment")); return; } else if (t.getTrkseg().size() == 1) trk = t.getTrkseg().get(0); } if (trk == null) { JOptionPane.showMessageDialog(mg, I18nUtils.localizedStringForKey("msg_add_gpx_polygon_no_select"), I18nUtils.localizedStringForKey("Error"), JOptionPane.ERROR_MESSAGE); return; } JAtlasTree jAtlasTree = mg.jAtlasTree; final String mapNameFmt = "%s %02d"; AtlasInterface atlasInterface = jAtlasTree.getAtlas(); String name = mg.getUserText(); MapSource mapSource = mg.getSelectedMapSource(); SelectedZoomLevels sZL = mg.getSelectedZoomLevels(); int[] zoomLevels = sZL.getZoomLevels(); if (zoomLevels.length == 0) { JOptionPane.showMessageDialog(mg, I18nUtils.localizedStringForKey("msg_no_zoom_level_selected")); return; } List points = trk.getTrkpt(); EastNorthCoordinate[] trackPoints = new EastNorthCoordinate[points.size()]; EastNorthCoordinate minCoordinate = new EastNorthCoordinate(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY); EastNorthCoordinate maxCoordinate = new EastNorthCoordinate(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY); for (int i = 0; i < trackPoints.length; i++) { GpxPoint gpxPoint = points.get(i); EastNorthCoordinate c = new EastNorthCoordinate(gpxPoint.getLat().doubleValue(), gpxPoint.getLon() .doubleValue()); minCoordinate.lat = Math.min(minCoordinate.lat, c.lat); minCoordinate.lon = Math.min(minCoordinate.lon, c.lon); maxCoordinate.lat = Math.max(maxCoordinate.lat, c.lat); maxCoordinate.lon = Math.max(maxCoordinate.lon, c.lon); trackPoints[i] = c; } final int maxZoom = zoomLevels[zoomLevels.length - 1]; final MapSpace mapSpace = mapSource.getMapSpace(); Point p1 = maxCoordinate.toTileCoordinate(mapSpace, maxZoom); Point p2 = minCoordinate.toTileCoordinate(mapSpace, maxZoom); final int centerY = p1.y + ((p1.y - p2.y) / 2); final UnitSystem unitSystem = Settings.getInstance().getUnitSystem(); JPanel panel = new JPanel(new BorderLayout()); panel.setPreferredSize(new Dimension(300, 100)); final JLabel label = new JLabel(""); final JDistanceSlider slider = new JDistanceSlider(mapSource.getMapSpace(), maxZoom, centerY, unitSystem, 5, 500); ChangeListener cl = new ChangeListener() { public void stateChanged(ChangeEvent e) { double d = mapSpace.horizontalDistance(maxZoom, centerY, slider.getValue()); d *= unitSystem.earthRadius * unitSystem.unitFactor; String unitName = unitSystem.unitSmall; if (d > unitSystem.unitFactor) { d /= unitSystem.unitFactor; unitName = unitSystem.unitLarge; } label.setText(String.format(I18nUtils.localizedStringForKey("dlg_gpx_track_select_distance"), ((int) d), unitName)); } }; cl.stateChanged(null); slider.addChangeListener(cl); panel.add(label, BorderLayout.NORTH); panel.add(slider, BorderLayout.CENTER); int result = JOptionPane.showConfirmDialog(mg, panel, I18nUtils.localizedStringForKey("dlg_gpx_track_select_title"), JOptionPane.OK_CANCEL_OPTION); if (result != JOptionPane.OK_OPTION) return; String layerName = name; int c = 1; Layer layer = null; boolean success = false; do { try { layer = new Layer(atlasInterface, layerName); success = true; } catch (InvalidNameException e) { layerName = name + "_" + Integer.toString(c++); } } while (!success); TileImageParameters customTileParameters = mg.getSelectedTileImageParameters(); int distance = slider.getValue(); MapPolygon maxZoomMap = MapPolygon.createFromTrack(null, "Dummy", mapSource, maxZoom, trackPoints, distance, customTileParameters); int width = maxZoomMap.getMaxTileCoordinate().x - maxZoomMap.getMinTileCoordinate().x; int height = maxZoomMap.getMaxTileCoordinate().y - maxZoomMap.getMinTileCoordinate().y; if (Math.max(width, height) > Settings.getInstance().maxMapSize) { String msg = I18nUtils.localizedStringForKey("msg_add_gpx_polygon_maxsize"); result = JOptionPane.showConfirmDialog(mg, msg, I18nUtils.localizedStringForKey("msg_add_gpx_polygon_maxsize_title"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); if (result != JOptionPane.YES_OPTION) return; } for (int zoom : zoomLevels) { String mapName = String.format(mapNameFmt, new Object[] { layerName, zoom }); MapInterface map = MapPolygon.createFromMapPolygon(layer, mapName, zoom, maxZoomMap); layer.addMap(map); } atlasInterface.addLayer(layer); mg.jAtlasTree.getTreeModel().notifyNodeInsert(layer); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/actions/ShowHelpAction.java0000644000175000017500000000216612122526604030224 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.actions; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import mobac.gui.dialogs.Help; public class ShowHelpAction implements ActionListener { public void actionPerformed(ActionEvent event) { Help.showHelp(); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/actions/SelectionModePolygon.java0000644000175000017500000000254112122526604031434 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.actions; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import mobac.gui.MainGUI; import mobac.gui.mapview.PreviewMap; import mobac.gui.mapview.controller.PolygonSelectionMapController; public class SelectionModePolygon implements ActionListener { public void actionPerformed(ActionEvent e) { PreviewMap previewMap = MainGUI.getMainGUI().previewMap; previewMap.setMapSelectionController(new PolygonSelectionMapController(previewMap)); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/panels/0000755000175000017500000000000012171650636024316 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/panels/JTileImageParametersPanel.java0000644000175000017500000002567512127544346032157 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.panels; import java.awt.Dimension; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Arrays; import java.util.TreeSet; import javax.swing.AbstractListModel; import javax.swing.ComboBoxModel; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import mobac.gui.components.JCollapsiblePanel; import mobac.gui.components.JTileSizeCombo; import mobac.program.annotations.SupportedParameters; import mobac.program.atlascreators.AtlasCreator; import mobac.program.model.AtlasOutputFormat; import mobac.program.model.Settings; import mobac.program.model.TileImageFormat; import mobac.program.model.TileImageParameters; import mobac.program.model.TileImageParameters.Name; import mobac.program.tiledatawriter.TileImageJpegDataWriter; import mobac.utilities.GBC; import mobac.utilities.I18nUtils; import mobac.utilities.Utilities; public class JTileImageParametersPanel extends JCollapsiblePanel { private static final long serialVersionUID = 1L; private static boolean JPEG_TESTED = false; private JCheckBox enableCustomTileProcessingCheckButton; private JLabel tileSizeWidthLabel; private JLabel tileSizeHeightLabel; private JLabel tileImageFormatLabel; private JTileSizeCombo tileSizeWidth; private JTileSizeCombo tileSizeHeight; private JComboBox tileImageFormat; private boolean widthEnabled = true; private boolean heightEnabled = true; private boolean formatPngEnabled = true; private boolean formatJpgEnabled = true; public JTileImageParametersPanel() { super(I18nUtils.localizedStringForKey("lp_tile_param_title"), new GridBagLayout()); setName("TileImageParameters"); enableCustomTileProcessingCheckButton = new JCheckBox( I18nUtils.localizedStringForKey("lp_tile_param_recreate_checkbox_title")); enableCustomTileProcessingCheckButton.addActionListener(new EnableCustomTileSizeCheckButtonListener()); enableCustomTileProcessingCheckButton.setToolTipText(I18nUtils .localizedStringForKey("lp_tile_param_recreate_checkbox_tips")); tileSizeWidthLabel = new JLabel(I18nUtils.localizedStringForKey("lp_tile_param_width_title")); tileSizeWidth = new JTileSizeCombo(); tileSizeWidth.setToolTipText(I18nUtils.localizedStringForKey("lp_tile_param_width_tips")); tileSizeHeightLabel = new JLabel(I18nUtils.localizedStringForKey("lp_tile_param_height_title")); tileSizeHeight = new JTileSizeCombo(); tileSizeHeight.setToolTipText(I18nUtils.localizedStringForKey("lp_tile_param_height_tips")); tileImageFormatLabel = new JLabel(I18nUtils.localizedStringForKey("lp_tile_param_image_fmt_title")); tileImageFormat = new JComboBox(new TileFormatComboModel(TileImageFormat.values())); tileImageFormat.setMaximumRowCount(tileImageFormat.getItemCount()); tileImageFormat.addActionListener(new TileImageFormatListener()); GBC gbc_std = GBC.std().insets(5, 2, 5, 3); GBC gbc_eol = GBC.eol().insets(5, 2, 5, 3); JPanel tileSizePanel = new JPanel(new GridBagLayout()); tileSizePanel.add(tileSizeWidthLabel, gbc_std); tileSizePanel.add(tileSizeWidth, gbc_std); tileSizePanel.add(tileSizeHeightLabel, gbc_std); tileSizePanel.add(tileSizeHeight, gbc_eol); JPanel tileColorDepthPanel = new JPanel(); tileColorDepthPanel.add(tileImageFormatLabel); tileColorDepthPanel.add(tileImageFormat); contentContainer.add(enableCustomTileProcessingCheckButton, gbc_eol); contentContainer.add(tileSizePanel, GBC.eol()); contentContainer.add(tileColorDepthPanel, GBC.eol()); } public void loadSettings() { Settings settings = Settings.getInstance(); enableCustomTileProcessingCheckButton.setSelected(settings.isCustomTileSize()); updateControlsState(); tileImageFormat.setSelectedItem(settings.getTileImageFormat()); tileSizeHeight.setValue(settings.getTileSize().height); tileSizeWidth.setValue(settings.getTileSize().width); } public void saveSettings() { Settings settings = Settings.getInstance(); settings.setCustomTileSize(enableCustomTileProcessingCheckButton.isSelected()); Dimension tileSize = new Dimension(tileSizeWidth.getValue(), tileSizeHeight.getValue()); settings.setTileSize(tileSize); settings.setTileImageFormat((TileImageFormat) tileImageFormat.getSelectedItem()); } public TileImageParameters getSelectedTileImageParameters() { TileImageParameters customTileParameters = null; boolean customTileSize = enableCustomTileProcessingCheckButton.isSelected(); if (customTileSize) { int width = tileSizeWidth.getValue(); int height = tileSizeHeight.getValue(); TileImageFormat format = (mobac.program.model.TileImageFormat) tileImageFormat.getSelectedItem(); customTileParameters = new TileImageParameters(width, height, format); } return customTileParameters; } public void atlasFormatChanged(AtlasOutputFormat newAtlasOutputFormat) { Class atlasCreatorClass = newAtlasOutputFormat.getMapCreatorClass(); SupportedParameters params = atlasCreatorClass.getAnnotation(SupportedParameters.class); if (params != null) { TreeSet paramNames = new TreeSet(Arrays.asList(params .names())); if (paramNames.contains(Name.format)) { formatPngEnabled = true; formatJpgEnabled = true; } else { formatPngEnabled = paramNames.contains(Name.format_png); formatJpgEnabled = paramNames.contains(Name.format_jpg); } widthEnabled = paramNames.contains(Name.width); heightEnabled = paramNames.contains(Name.height); enableCustomTileProcessingCheckButton.setEnabled(true); } else { formatPngEnabled = false; formatJpgEnabled = false; widthEnabled = false; heightEnabled = false; enableCustomTileProcessingCheckButton.setEnabled(false); } updateControlsState(); } public void updateControlsState() { boolean b = false; if (enableCustomTileProcessingCheckButton.isEnabled()) b = enableCustomTileProcessingCheckButton.isSelected(); tileSizeWidth.setEnabled(b && widthEnabled); tileSizeWidthLabel.setEnabled(b && widthEnabled); tileSizeHeightLabel.setEnabled(b && heightEnabled); tileSizeHeight.setEnabled(b && heightEnabled); boolean formatEnabled = formatJpgEnabled || formatPngEnabled; tileImageFormatLabel.setEnabled(b && formatEnabled); tileImageFormat.setEnabled(b && formatEnabled); if (formatPngEnabled && !formatJpgEnabled) updateFormatComboModel(TileImageFormat.getPngFormats()); else if (!formatPngEnabled && formatJpgEnabled) updateFormatComboModel(TileImageFormat.getJpgFormats()); else updateFormatComboModel(TileImageFormat.values()); } private void updateFormatComboModel(TileImageFormat[] values) { TileFormatComboModel model = (TileFormatComboModel) tileImageFormat.getModel(); model.changeValues(values); } public String getValidationErrorMessages() { String errorText = ""; if (!enableCustomTileProcessingCheckButton.isSelected()) return errorText; if (!tileSizeHeight.isValueValid()) errorText += String.format(I18nUtils.localizedStringForKey("lp_tile_param_msg_valid_height"), JTileSizeCombo.MIN, JTileSizeCombo.MAX); if (!tileSizeWidth.isValueValid()) errorText += String.format(I18nUtils.localizedStringForKey("lp_tile_param_msg_valid_width"), JTileSizeCombo.MIN, JTileSizeCombo.MAX); return errorText; } private class EnableCustomTileSizeCheckButtonListener implements ActionListener { public void actionPerformed(ActionEvent e) { updateControlsState(); } } private class TileImageFormatListener implements ActionListener { public void actionPerformed(ActionEvent event) { if (!tileImageFormat.isEnabled()) return; TileImageFormat tif = (TileImageFormat) tileImageFormat.getSelectedItem(); if (tif == null) return; if (!JPEG_TESTED && (tif.getDataWriter() instanceof TileImageJpegDataWriter)) { if (!TileImageJpegDataWriter.performOpenJDKJpegTest()) JOptionPane.showMessageDialog(null, "The JPEG image format is not supported by OpenJDK.
" + "Please select a different tile format.", "Image format not available on OpenJDK", JOptionPane.ERROR_MESSAGE); JPEG_TESTED = true; } else if (tif == TileImageFormat.PNG4Bit || tif == TileImageFormat.PNG8Bit) { if (Utilities.testJaiColorQuantizerAvailable()) return; JOptionPane.showMessageDialog(null, "This image format is requires additional libraries to be installed:
" + "Java Advanced Image library (jai_core.jar & jai_codec.jar)
" + "For more details please see the file README.HTM " + "in section Requirements.", "Image format not available - libraries missing", JOptionPane.ERROR_MESSAGE); tileImageFormat.setSelectedIndex(0); } } } private class TileFormatComboModel extends AbstractListModel implements ComboBoxModel { TileImageFormat[] values; Object selectedObject = null; public TileFormatComboModel(TileImageFormat[] values) { super(); this.values = values; if (values.length > 0) selectedObject = values[0]; } public void changeValues(TileImageFormat[] values) { this.values = values; boolean found = false; for (TileImageFormat format : values) { if (format.equals(selectedObject)) { found = true; break; } } if (!found) selectedObject = values[0]; fireContentsChanged(this, -1, -1); } public int getSize() { return values.length; } public TileImageFormat getElementAt(int index) { return values[index]; } @Override public void setSelectedItem(Object anItem) { if ((selectedObject != null && !selectedObject.equals(anItem)) || selectedObject == null && anItem != null) { selectedObject = anItem; fireContentsChanged(this, -1, -1); } } @Override public Object getSelectedItem() { return selectedObject; } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/panels/JCoordinatesPanel.java0000644000175000017500000002113412127544346030527 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.panels; import java.awt.BorderLayout; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.text.ParseException; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JLayeredPane; import javax.swing.JMenuItem; import javax.swing.JPanel; import mobac.gui.components.FilledLayeredPane; import mobac.gui.components.JCollapsiblePanel; import mobac.gui.components.JCoordinateField; import mobac.gui.components.JDropDownButton; import mobac.program.interfaces.MapSource; import mobac.program.model.CoordinateStringFormat; import mobac.program.model.EastNorthCoordinate; import mobac.program.model.MapSelection; import mobac.program.model.MercatorPixelCoordinate; import mobac.utilities.GBC; import mobac.utilities.I18nUtils; /** * Encapsulates all interface components and code for the panel that shows the coordinates of the current selection and * allows the user to enter own coordinates. */ public class JCoordinatesPanel extends JCollapsiblePanel { private static final long serialVersionUID = 1L; public static final String NAME = "Coordinates";//用于持久化 private JCoordinateField latMinTextField; private JCoordinateField latMaxTextField; private JCoordinateField lonMinTextField; private JCoordinateField lonMaxTextField; private JButton applySelectionButton; private CoordinateStringFormat csf = CoordinateStringFormat.DEG_ENG; public JCoordinatesPanel() { super(I18nUtils.localizedStringForKey("lp_coords_title"), new GridBagLayout()); setName(NAME); // coordinates panel latMaxTextField = new JCoordinateField(MapSelection.LAT_MIN, MapSelection.LAT_MAX); latMaxTextField.setActionCommand("latMaxTextField"); lonMinTextField = new JCoordinateField(MapSelection.LON_MIN, MapSelection.LON_MAX); lonMinTextField.setActionCommand("longMinTextField"); lonMaxTextField = new JCoordinateField(MapSelection.LON_MIN, MapSelection.LON_MAX); lonMaxTextField.setActionCommand("longMaxTextField"); latMinTextField = new JCoordinateField(MapSelection.LAT_MIN, MapSelection.LAT_MAX); latMinTextField.setActionCommand("latMinTextField"); applySelectionButton = new JButton(I18nUtils.localizedStringForKey("lp_coords_select_btn_title")); JLabel latMaxLabel = new JLabel(I18nUtils.localizedStringForKey("lp_coords_label_N"), JLabel.CENTER); JLabel lonMinLabel = new JLabel(I18nUtils.localizedStringForKey("lp_coords_label_W"), JLabel.CENTER); JLabel lonMaxLabel = new JLabel(I18nUtils.localizedStringForKey("lp_coords_label_E"), JLabel.CENTER); JLabel latMinLabel = new JLabel(I18nUtils.localizedStringForKey("lp_coords_label_S"), JLabel.CENTER); JPanel northPanel = new JPanel(new BorderLayout()); JLayeredPane layeredPane = new FilledLayeredPane(); JPanel northInnerPanel = new JPanel(); northInnerPanel.add(latMaxLabel); northInnerPanel.add(latMaxTextField); JPanel formatButtonPanel = new JPanel(null); formatButtonPanel.setOpaque(false); JDropDownButton formatButton = new JDropDownButton(I18nUtils.localizedStringForKey("lp_coords_fmt_list_title")); formatButton.setMargin(new Insets(0, 5, 0, 0)); formatButton.setBounds(2, 2, 55, 20); formatButtonPanel.add(formatButton); for (CoordinateStringFormat csf : CoordinateStringFormat.values()) formatButton.addDropDownItem(new JNumberFormatMenuItem(csf)); layeredPane.add(northInnerPanel, Integer.valueOf(0)); layeredPane.setMinimumSize(northInnerPanel.getMinimumSize()); layeredPane.setPreferredSize(northInnerPanel.getPreferredSize()); layeredPane.add(formatButtonPanel, Integer.valueOf(2)); northPanel.add(layeredPane, BorderLayout.CENTER); // northPanel.add(northInnerPanel, BorderLayout.CENTER); contentContainer.add(northPanel, GBC.eol().fillH().insets(0, 5, 0, 0)); JPanel eastWestPanel = new JPanel(new GridBagLayout()); eastWestPanel.add(lonMinLabel, GBC.std()); eastWestPanel.add(lonMinTextField, GBC.std()); eastWestPanel.add(lonMaxLabel, GBC.std().insets(10, 0, 0, 0)); eastWestPanel.add(lonMaxTextField, GBC.std()); contentContainer.add(eastWestPanel, GBC.eol().fill()); JPanel southPanel = new JPanel(); southPanel.add(latMinLabel); southPanel.add(latMinTextField); contentContainer.add(southPanel, GBC.eol().anchor(GBC.CENTER)); contentContainer.add(applySelectionButton, GBC.eol().anchor(GBC.CENTER).insets(0, 5, 0, 0)); } public void setNumberFormat(CoordinateStringFormat csf) { this.csf = csf; latMaxTextField.setNumberFormat(csf.getNumberFormatLatitude()); latMinTextField.setNumberFormat(csf.getNumberFormatLatitude()); lonMaxTextField.setNumberFormat(csf.getNumberFormatLongitude()); lonMinTextField.setNumberFormat(csf.getNumberFormatLongitude()); } public CoordinateStringFormat getNumberFormat() { return csf; } public void setCoordinates(EastNorthCoordinate max, EastNorthCoordinate min) { latMaxTextField.setCoordinate(max.lat); lonMaxTextField.setCoordinate(max.lon); latMinTextField.setCoordinate(min.lat); lonMinTextField.setCoordinate(min.lon); } public void setCoordinates(MapSelection ms) { MercatorPixelCoordinate max = ms.getBottomRightPixelCoordinate(); MercatorPixelCoordinate min = ms.getTopLeftPixelCoordinate(); setSelection(max, min); } public void setSelection(MercatorPixelCoordinate max, MercatorPixelCoordinate min) { EastNorthCoordinate c1 = min.getEastNorthCoordinate(); EastNorthCoordinate c2 = max.getEastNorthCoordinate(); latMaxTextField.setCoordinate(c1.lat); lonMaxTextField.setCoordinate(c2.lon); latMinTextField.setCoordinate(c2.lat); lonMinTextField.setCoordinate(c1.lon); } /** * Checks if the values for min/max langitude and min/max latitude are interchanged (smaller value in the max field * and larger value in the min field) and swaps them if necessary. */ public void correctMinMax() { try { double lat1 = latMaxTextField.getCoordinate(); double lat2 = latMinTextField.getCoordinate(); if (lat1 < lat2) { String tmp = latMaxTextField.getText(); latMaxTextField.setText(latMinTextField.getText()); latMinTextField.setText(tmp); } } catch (ParseException e) { // one of the lat fields contains an invalid coordinate } try { double lon1 = lonMaxTextField.getCoordinate(); double lon2 = lonMinTextField.getCoordinate(); if (lon1 < lon2) { String tmp = lonMaxTextField.getText(); lonMaxTextField.setText(lonMinTextField.getText()); lonMinTextField.setText(tmp); } } catch (ParseException e) { // one of the lon fields contains an invalid coordinate } } public MapSelection getMapSelection(MapSource mapSource) { EastNorthCoordinate max = getMaxCoordinate(); EastNorthCoordinate min = getMinCoordinate(); return new MapSelection(mapSource, max, min); } public EastNorthCoordinate getMaxCoordinate() { return new EastNorthCoordinate(latMaxTextField.getCoordinateOrNaN(), lonMaxTextField.getCoordinateOrNaN()); } public EastNorthCoordinate getMinCoordinate() { return new EastNorthCoordinate(latMinTextField.getCoordinateOrNaN(), lonMinTextField.getCoordinateOrNaN()); } public void addButtonActionListener(ActionListener l) { applySelectionButton.addActionListener(l); } protected class JNumberFormatMenuItem extends JMenuItem implements ActionListener { private static final long serialVersionUID = 1L; private final CoordinateStringFormat csf; public JNumberFormatMenuItem(CoordinateStringFormat csf) { super(csf.toString()); this.csf = csf; addActionListener(this); } public void actionPerformed(ActionEvent e) { System.out.println(e); JCoordinatesPanel.this.setNumberFormat(csf); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/panels/JGpxPanel.java0000644000175000017500000002143012127544346027012 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.panels; import java.awt.GridBagLayout; import java.util.ArrayList; import java.util.List; import javax.swing.JButton; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreePath; import javax.swing.tree.TreeSelectionModel; import mobac.data.gpx.gpx11.RteType; import mobac.data.gpx.gpx11.TrkType; import mobac.data.gpx.gpx11.TrksegType; import mobac.data.gpx.gpx11.WptType; import mobac.gui.actions.GpxAddPoint; import mobac.gui.actions.GpxClear; import mobac.gui.actions.GpxLoad; import mobac.gui.actions.GpxNew; import mobac.gui.actions.GpxSave; import mobac.gui.components.JCollapsiblePanel; import mobac.gui.gpxtree.GpxEntry; import mobac.gui.gpxtree.GpxRootEntry; import mobac.gui.gpxtree.GpxTreeListener; import mobac.gui.gpxtree.RteEntry; import mobac.gui.gpxtree.TrkEntry; import mobac.gui.gpxtree.TrksegEntry; import mobac.gui.gpxtree.WptEntry; import mobac.gui.mapview.PreviewMap; import mobac.gui.mapview.layer.GpxLayer; import mobac.utilities.GBC; import mobac.utilities.I18nUtils; /** * Allows to load, display, edit and save gpx files using a tree view. TODO warn unsaved changes on exit * */ public class JGpxPanel extends JCollapsiblePanel { private static final long serialVersionUID = 1L; private JTree tree; private DefaultMutableTreeNode rootNode; private DefaultTreeModel model; private ArrayList openedFiles; private PreviewMap previewMap; public JGpxPanel(PreviewMap previewMap) { super("Gpx", new GridBagLayout()); this.previewMap = previewMap; JButton newGpx = new JButton(I18nUtils.localizedStringForKey("rp_gpx_new_gpx")); newGpx.addActionListener(new GpxNew(this)); JButton loadGpx = new JButton(I18nUtils.localizedStringForKey("rp_gpx_load_gpx")); loadGpx.addActionListener(new GpxLoad(this)); JButton saveGpx = new JButton(I18nUtils.localizedStringForKey("rp_gpx_save_gpx")); saveGpx.addActionListener(new GpxSave(this)); JButton clearGpx = new JButton(I18nUtils.localizedStringForKey("rp_gpx_clear_gpx")); clearGpx.addActionListener(new GpxClear(this)); JButton addPointGpx = new JButton(I18nUtils.localizedStringForKey("rp_gpx_add_wpt")); addPointGpx.addActionListener(new GpxAddPoint(this)); rootNode = new DefaultMutableTreeNode(I18nUtils.localizedStringForKey("rp_gpx_default_node_name")); tree = new JTree(rootNode); tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); tree.setRootVisible(false); tree.setShowsRootHandles(true); JScrollPane treeView = new JScrollPane(tree); // treeView.setPreferredSize(new Dimension(100, 300)); model = (DefaultTreeModel) tree.getModel(); tree.addMouseListener(new GpxTreeListener()); openedFiles = new ArrayList(); GBC eol = GBC.eol().fill(GBC.HORIZONTAL); GBC std = GBC.std().fill(GBC.HORIZONTAL); addContent(treeView, GBC.eol().fill()); addContent(clearGpx, std); addContent(addPointGpx, eol); addContent(newGpx, std); addContent(loadGpx, std); addContent(saveGpx, eol); } /** * adds a layer for a new gpx file on the map and adds its structure to the treeview * */ public GpxRootEntry addGpxLayer(GpxLayer layer) { layer.setPanel(this); GpxRootEntry gpxEntry = new GpxRootEntry(layer); DefaultMutableTreeNode gpxNode = new DefaultMutableTreeNode(gpxEntry); model.insertNodeInto(gpxNode, rootNode, rootNode.getChildCount()); TreePath path = new TreePath(gpxNode.getPath()); tree.scrollPathToVisible(new TreePath(path)); tree.setSelectionPath(path); addRtes(layer, gpxNode); addTrks(layer, gpxNode); addWpts(layer, gpxNode); if (layer.getFile() != null) openedFiles.add(layer.getFile().getAbsolutePath()); previewMap.mapLayers.add(layer); return gpxEntry; } /** * @param layer * @param gpxNode * @param model */ private void addWpts(GpxLayer layer, DefaultMutableTreeNode gpxNode) { List wpts = layer.getGpx().getWpt(); for (WptType wpt : wpts) { WptEntry wptEntry = new WptEntry(wpt, layer); DefaultMutableTreeNode wptNode = new DefaultMutableTreeNode(wptEntry); model.insertNodeInto(wptNode, gpxNode, gpxNode.getChildCount()); } } /** * @param layer * @param gpxNode * @param model */ private void addTrks(GpxLayer layer, DefaultMutableTreeNode gpxNode) { // tracks List trks = layer.getGpx().getTrk(); for (TrkType trk : trks) { TrkEntry trkEntry = new TrkEntry(trk, layer); DefaultMutableTreeNode trkNode = new DefaultMutableTreeNode(trkEntry); model.insertNodeInto(trkNode, gpxNode, gpxNode.getChildCount()); // trkseg List trksegs = trk.getTrkseg(); int counter = 1; for (TrksegType trkseg : trksegs) { TrksegEntry trksegEntry = new TrksegEntry(trkseg, counter, layer); DefaultMutableTreeNode trksegNode = new DefaultMutableTreeNode(trksegEntry); model.insertNodeInto(trksegNode, trkNode, trkNode.getChildCount()); counter++; // add trkpts List trkpts = trkseg.getTrkpt(); for (WptType trkpt : trkpts) { WptEntry trkptEntry = new WptEntry(trkpt, layer); DefaultMutableTreeNode trkptNode = new DefaultMutableTreeNode(trkptEntry); model.insertNodeInto(trkptNode, trksegNode, trksegNode.getChildCount()); } } } } /** * adds routes and route points to the tree view * * @param layer * @param gpxNode */ private void addRtes(GpxLayer layer, DefaultMutableTreeNode gpxNode) { List rtes = layer.getGpx().getRte(); for (RteType rte : rtes) { RteEntry rteEntry = new RteEntry(rte, layer); DefaultMutableTreeNode rteNode = new DefaultMutableTreeNode(rteEntry); model.insertNodeInto(rteNode, gpxNode, gpxNode.getChildCount()); // add rtepts List rtepts = rte.getRtept(); for (WptType rtept : rtepts) { WptEntry rteptEntry = new WptEntry(rtept, layer); DefaultMutableTreeNode rteptNode = new DefaultMutableTreeNode(rteptEntry); model.insertNodeInto(rteptNode, rteNode, rteNode.getChildCount()); } } } /** * Updates the tree view to show the newly added waypoint. * * @param wpt * - new waypoint * @param gpxEntry * - parent entry in the tree */ public void addWpt(WptType wpt, GpxEntry gpxEntry) { WptEntry wptEntry = new WptEntry(wpt, gpxEntry.getLayer()); DefaultMutableTreeNode wptNode = new DefaultMutableTreeNode(wptEntry); model.insertNodeInto(wptNode, gpxEntry.getNode(), gpxEntry.getNode().getChildCount()); } /** * Updates the tree view after removing a waypoint. * * @param wpt * - deleted waypoint * @param gpxEntry * - parent entry of the deleted element in the tree */ public void removeWpt(WptEntry wptEntry) { DefaultMutableTreeNode wptNode = wptEntry.getNode(); model.removeNodeFromParent(wptNode); // update layer (is changing the gpx enough? prolly not // did remove it already...check wheter its enough } public GpxEntry getSelectedEntry() { TreePath selection = tree.getSelectionPath(); if (selection == null) { return null; } DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) selection.getLastPathComponent(); GpxEntry gpxEntry = null; try { gpxEntry = (GpxEntry) selectedNode.getUserObject(); gpxEntry.setNode(selectedNode); } catch (ClassCastException e) { } return gpxEntry; } public boolean isFileOpen(String path) { return openedFiles.contains(path); } /** * Resets the tree view. Used by GpxClear. * */ public void resetModel() { rootNode = new DefaultMutableTreeNode(I18nUtils.localizedStringForKey("rp_gpx_default_node_name")); model.setRoot(rootNode); openedFiles = new ArrayList(); } public DefaultTreeModel getTreeModel() { return model; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/panels/JTileStoreCoveragePanel.java0000644000175000017500000001266312150552674031651 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.panels; import java.awt.FlowLayout; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.DefaultComboBoxModel; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JPanel; import mobac.gui.components.JCollapsiblePanel; import mobac.gui.mapview.PreviewMap; import mobac.gui.mapview.controller.JMapController; import mobac.gui.mapview.interfaces.MapEventListener; import mobac.gui.mapview.layer.TileStoreCoverageLayer; import mobac.mapsources.AbstractMultiLayerMapSource; import mobac.program.interfaces.MapSource; import mobac.program.model.MercatorPixelCoordinate; import mobac.utilities.GBC; import mobac.utilities.I18nUtils; public class JTileStoreCoveragePanel extends JCollapsiblePanel implements MapEventListener, ActionListener { //MP-add private static final long serialVersionUID = 1L; private JButton showCoverage; private JButton hideCoverage; private JComboBox layerSelector; private JComboBox zoomCombo; private PreviewMap mapViewer; public JTileStoreCoveragePanel(PreviewMap mapViewer) { super(I18nUtils.localizedStringForKey("lp_tile_store_title")); contentContainer.setLayout(new GridBagLayout()); this.mapViewer = mapViewer; showCoverage = new JButton(I18nUtils.localizedStringForKey("lp_tile_store_show_coverage_btn_title")); showCoverage.addActionListener(this); showCoverage.setToolTipText(I18nUtils.localizedStringForKey("lp_tile_store_show_coverage_btn_tips")); hideCoverage = new JButton(I18nUtils.localizedStringForKey("lp_tile_store_hide_coverage_btn_title")); hideCoverage.addActionListener(this); hideCoverage.setEnabled(false); zoomCombo = new JComboBox(); zoomCombo.setToolTipText(I18nUtils.localizedStringForKey("lp_tile_store_zoom_combo_tips")); titlePanel.setToolTipText(I18nUtils.localizedStringForKey("lp_tile_store_title_tips")); layerSelector = new JComboBox(); GBC gbc_eol = GBC.eol().insets(2, 2, 2, 2); GBC gbc_std = GBC.std().insets(2, 2, 2, 2); contentContainer.add(new JLabel(I18nUtils.localizedStringForKey("lp_tile_store_zoom_title")), gbc_std); contentContainer.add(zoomCombo, gbc_eol); contentContainer.add(new JLabel(I18nUtils.localizedStringForKey("lp_tile_store_layer_title")), gbc_std); contentContainer.add(layerSelector, gbc_eol); contentContainer.add(showCoverage, gbc_eol.fillH()); contentContainer.add(hideCoverage, gbc_eol.fillH()); mapSourceChanged(mapViewer.getMapSource()); mapViewer.addMapEventListener(this); } public void actionPerformed(ActionEvent e) { if (hideCoverage.equals(e.getSource())) { TileStoreCoverageLayer.removeCacheCoverageLayers(); mapViewer.repaint(); hideCoverage.setEnabled(false); return; } Integer zoom = (Integer) zoomCombo.getSelectedItem(); if (zoom == null) return; TileStoreCoverageLayer.removeCacheCoverageLayers(); mapViewer.repaint(); TileStoreCoverageLayer tscl = new TileStoreCoverageLayer(mapViewer, (MapSource) layerSelector.getSelectedItem(), zoom); mapViewer.mapLayers.add(tscl); hideCoverage.setEnabled(true); } public void gridZoomChanged(int newGridZoomLevel) { } public void mapSourceChanged(MapSource newMapSource) { TileStoreCoverageLayer.removeCacheCoverageLayers(); hideCoverage.setEnabled(false); Integer selZoom = (Integer) zoomCombo.getSelectedItem(); if (selZoom == null) selZoom = new Integer(8); int zoomLevels = Math.max(0, newMapSource.getMaxZoom() - newMapSource.getMinZoom() + 1); Integer[] items = new Integer[zoomLevels]; int zoom = newMapSource.getMinZoom(); for (int i = 0; i < items.length; i++) { items[i] = new Integer(zoom++); } zoomCombo.setModel(new DefaultComboBoxModel(items)); zoomCombo.setMaximumRowCount(10); zoomCombo.setSelectedItem(selZoom); MapSource[] layers; if (newMapSource instanceof AbstractMultiLayerMapSource) { layers = ((AbstractMultiLayerMapSource) newMapSource).getLayerMapSources(); layerSelector.setEnabled(true); } else { layers = new MapSource[] { newMapSource }; layerSelector.setEnabled(false); } layerSelector.setModel(new DefaultComboBoxModel(layers)); layerSelector.setSelectedIndex(0); } public void selectNextMapSource() { } public void selectPreviousMapSource() { } public void selectionChanged(MercatorPixelCoordinate max, MercatorPixelCoordinate min) { } public void zoomChanged(int newZoomLevel) { } public void mapSelectionControllerChanged(JMapController newMapController) { } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/panels/JProfilesPanel.java0000644000175000017500000001433512171650636030044 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.panels; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JOptionPane; import javax.swing.JPanel; import mobac.gui.atlastree.JAtlasTree; import mobac.gui.components.JCollapsiblePanel; import mobac.gui.components.JProfilesComboBox; import mobac.program.model.Profile; import mobac.utilities.GBC; import mobac.utilities.I18nUtils; import mobac.utilities.Utilities; public class JProfilesPanel extends JCollapsiblePanel { private static final long serialVersionUID = 1L; private JProfilesComboBox profilesCombo; private JButton reloadButton; private JButton deleteButton; private JButton loadButton; private JButton saveAsButton; public JProfilesPanel(JAtlasTree atlasTree) { super(I18nUtils.localizedStringForKey("lp_atlas_profile_title"), new GridBagLayout()); if (atlasTree == null) throw new NullPointerException(); // profiles combo box profilesCombo = new JProfilesComboBox(); profilesCombo.setToolTipText(I18nUtils.localizedStringForKey("lp_atlas_profile_combo_tips")); profilesCombo.addActionListener(new ProfileListListener()); // delete profile button deleteButton = new JButton(I18nUtils.localizedStringForKey("lp_atlas_profile_delete_btn_title")); deleteButton.addActionListener(new DeleteProfileListener()); deleteButton.setToolTipText(I18nUtils.localizedStringForKey("lp_atlas_profile_delete_btn_tips")); // save as profile button saveAsButton = new JButton(I18nUtils.localizedStringForKey("lp_atlas_profile_save_btn_title")); saveAsButton.setToolTipText(I18nUtils.localizedStringForKey("lp_atlas_profile_save_btn_tips")); saveAsButton.addActionListener(new SaveAsProfileListener(atlasTree)); loadButton = new JButton(I18nUtils.localizedStringForKey("lp_atlas_profile_load_btn_title")); loadButton.setToolTipText(I18nUtils.localizedStringForKey("lp_atlas_profile_load_btn_tips")); GBC gbc = GBC.eol().fill().insets(5, 5, 5, 5); reloadButton = new JButton(Utilities.loadResourceImageIcon("refresh.png")); reloadButton.setToolTipText(I18nUtils.localizedStringForKey("lp_atlas_profile_refresh_btn_tips")); reloadButton.addActionListener(new ReloadListener()); reloadButton.setPreferredSize(new Dimension(24, 0)); JPanel p = new JPanel(new BorderLayout()); p.add(profilesCombo, BorderLayout.CENTER); p.add(reloadButton, BorderLayout.EAST); contentContainer.add(p, gbc); contentContainer.add(deleteButton, gbc.toggleEol()); contentContainer.add(saveAsButton, gbc); contentContainer.add(loadButton, gbc.toggleEol()); saveAsButton.setEnabled(false); deleteButton.setEnabled(false); loadButton.setEnabled(false); } public void initialize() { // Load all profiles from the profiles file from disk profilesCombo.loadProfilesList(); deleteButton.setEnabled(false); loadButton.setEnabled(false); } public void reloadProfileList() { initialize(); } public JProfilesComboBox getProfilesCombo() { return profilesCombo; } public JButton getLoadButton() { return loadButton; } public JButton getDeleteButton() { return deleteButton; } public JButton getSaveAsButton() { return saveAsButton; } public Profile getSelectedProfile() { return profilesCombo.getSelectedProfile(); } private class SaveAsProfileListener implements ActionListener { JAtlasTree jAtlasTree; public SaveAsProfileListener(JAtlasTree atlasTree) { super(); jAtlasTree = atlasTree; } public void actionPerformed(ActionEvent e) { if (!jAtlasTree.testAtlasContentValid()) return; Object selObject = profilesCombo.getEditor().getItem(); String profileName = null; Profile profile = null; if (selObject instanceof Profile) { profile = (Profile) selObject; profileName = profile.getName(); } else profileName = (String) selObject; if (profileName.length() == 0) { JOptionPane.showMessageDialog(null, I18nUtils.localizedStringForKey("lp_atlas_profile_msg_ask_name"), I18nUtils.localizedStringForKey("Error"), JOptionPane.ERROR_MESSAGE); return; } profile = new Profile(profileName); if (profile.exists()) { int response = JOptionPane.showConfirmDialog(null, String.format(I18nUtils.localizedStringForKey("lp_atlas_profile_msg_overwrite_confirm"), profileName), I18nUtils.localizedStringForKey("lp_atlas_profile_msg_overwrite_confirm_title"), JOptionPane.YES_NO_OPTION); if (response != JOptionPane.YES_OPTION) return; } if (jAtlasTree.save(profile)) { reloadProfileList(); profilesCombo.setSelectedItem(profile); } } } private class DeleteProfileListener implements ActionListener { public void actionPerformed(ActionEvent e) { profilesCombo.deleteSelectedProfile(); } } private class ReloadListener implements ActionListener { public void actionPerformed(ActionEvent e) { reloadProfileList(); } } private class ProfileListListener implements ActionListener { public void actionPerformed(ActionEvent e) { boolean existingProfileSelected = profilesCombo.getSelectedProfile() != null; loadButton.setEnabled(existingProfileSelected); deleteButton.setEnabled(existingProfileSelected); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/dialogs/0000755000175000017500000000000012134265562024455 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/dialogs/MessageDialogs.java0000644000175000017500000000337512127544346030221 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.dialogs; import java.awt.Component; import java.awt.Dimension; import javax.swing.JLabel; import javax.swing.JOptionPane; import mobac.utilities.I18nUtils; public class MessageDialogs { public static void showErrorMessage(Component parentComponent, String message, String title) { JLabel label = new JLabel("" + message + ""); int maxWidth = 400; Dimension size = label.getPreferredSize(); if (size.width > maxWidth) { // Estimate the number of lines int lineCount = (int) Math.ceil(((double) size.width) / maxWidth); lineCount += 1; // Add one extra line as reserve size.width = maxWidth; // Limit the maximum width // Increase the size so that the size.height *= lineCount; label.setPreferredSize(size); } JOptionPane.showMessageDialog(null, label, I18nUtils.localizedStringForKey("Error"), JOptionPane.ERROR_MESSAGE); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/dialogs/ManageBookmarks.java0000644000175000017500000001004712127544346030365 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.dialogs; import java.awt.Dimension; import java.awt.GridBagLayout; import java.awt.HeadlessException; import java.awt.Toolkit; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import javax.swing.DefaultListModel; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JList; import javax.swing.ListSelectionModel; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.xml.bind.JAXBException; import mobac.gui.MainGUI; import mobac.program.DirectoryManager; import mobac.program.Logging; import mobac.program.model.Bookmark; import mobac.program.model.Settings; import mobac.utilities.GBC; import mobac.utilities.GUIExceptionHandler; import mobac.utilities.I18nUtils; public class ManageBookmarks extends JDialog implements ListSelectionListener, ActionListener { private JButton deleteButton; private JButton applyButton; private JList bookmarks; private DefaultListModel bookmarksModel; public ManageBookmarks(Window owner) throws HeadlessException { super(owner, I18nUtils.localizedStringForKey("dlg_mgn_bookmark_title")); setIconImages(MainGUI.MOBAC_ICONS); setLayout(new GridBagLayout()); applyButton = new JButton(I18nUtils.localizedStringForKey("Close")); applyButton.addActionListener(this); applyButton.setDefaultCapable(true); deleteButton = new JButton(I18nUtils.localizedStringForKey("dlg_mgn_bookmark_delete")); deleteButton.addActionListener(this); bookmarksModel = new DefaultListModel(); for (Bookmark b : Settings.getInstance().placeBookmarks) bookmarksModel.addElement(b); bookmarks = new JList(bookmarksModel); bookmarks.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); bookmarks.addListSelectionListener(this); bookmarks.setVisibleRowCount(10); bookmarks.setPreferredSize(new Dimension(250, 300)); add(bookmarks, GBC.eol().insets(10, 10, 10, 10).fill()); add(deleteButton, GBC.eol().anchor(GBC.CENTER).insets(0, 0, 0, 10)); add(applyButton, GBC.eol().anchor(GBC.CENTER).insets(0, 0, 0, 10)); pack(); Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); setLocation((dim.width - getWidth()) / 2, (dim.height - getHeight()) / 2); valueChanged(null); } public void actionPerformed(ActionEvent e) { if (deleteButton.equals(e.getSource())) deleteSelectedEntries(); else if (applyButton.equals(e.getSource())) apply(); } protected void deleteSelectedEntries() { int[] selected = bookmarks.getSelectedIndices(); for (int i = selected.length - 1; i >= 0; i--) bookmarksModel.remove(selected[i]); } protected void apply() { ArrayList bookmarksList = new ArrayList(bookmarksModel.getSize()); for (int i = 0; i < bookmarksModel.getSize(); i++) bookmarksList.add((Bookmark) bookmarksModel.get(i)); Settings.getInstance().placeBookmarks = bookmarksList; setVisible(false); dispose(); } public void valueChanged(ListSelectionEvent e) { deleteButton.setEnabled(bookmarks.getSelectedIndices().length > 0); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/dialogs/AboutDialog.java0000644000175000017500000000706512136352614027517 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.dialogs; import java.awt.Color; import java.awt.Dimension; import java.awt.GridBagLayout; import java.awt.HeadlessException; import java.awt.Toolkit; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import javax.swing.ImageIcon; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.UIManager; import mobac.gui.MainGUI; import mobac.program.ProgramInfo; import mobac.utilities.GBC; import mobac.utilities.I18nUtils; import mobac.utilities.Utilities; public class AboutDialog extends JDialog implements MouseListener { public AboutDialog() throws HeadlessException { super(MainGUI.getMainGUI(), I18nUtils.localizedStringForKey("dlg_about_title")); setIconImages(MainGUI.MOBAC_ICONS); setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); setResizable(false); JPanel panel = new JPanel(null); panel.setBackground(Color.WHITE); GBC std = GBC.std(); GBC eol = GBC.eol(); std.insets(3, 3, 3, 3); eol.insets(3, 3, 3, 3); ImageIcon splash = Utilities.loadResourceImageIcon("Splash.jpg"); Dimension size = new Dimension(splash.getIconWidth(), splash.getIconHeight()); panel.setPreferredSize(size); panel.setMinimumSize(size); panel.setMaximumSize(size); panel.setSize(size); JLabel splashLabel = new JLabel(splash); JPanel infoPanel = new JPanel(new GridBagLayout()); infoPanel.setBackground(Color.WHITE); infoPanel.setOpaque(false); infoPanel.add(new JLabel(I18nUtils.localizedStringForKey("dlg_about_version")), std); infoPanel.add(new JLabel(ProgramInfo.getVersion()), eol); infoPanel.add(new JLabel(I18nUtils.localizedStringForKey("dlg_about_program_version")), std); infoPanel.add(new JLabel(ProgramInfo.getRevisionStr()), eol); panel.add(infoPanel); panel.add(splashLabel); infoPanel.setBounds(200, 155, 320, 200); splashLabel.setBounds(0, 0, splash.getIconWidth(), splash.getIconHeight()); add(panel); pack(); Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); setLocation((dim.width - getWidth()) / 2, (dim.height - getHeight()) / 2); addMouseListener(this); } public void mouseClicked(MouseEvent e) { setVisible(false); } public void mousePressed(MouseEvent e) { } public void mouseReleased(MouseEvent e) { } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public static void main(String[] args) { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); ProgramInfo.initialize(); // Load revision info JDialog dlg = new AboutDialog(); dlg.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/dialogs/Help.java0000644000175000017500000000656312134265562026222 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.dialogs; import java.awt.Dimension; import java.awt.GridBagLayout; import java.awt.HeadlessException; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import java.io.DataInputStream; import java.io.IOException; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import mobac.gui.MainGUI; import mobac.utilities.Charsets; import mobac.utilities.GBC; import mobac.utilities.I18nUtils; public class Help extends JFrame implements WindowListener { private static Help INSTANCE = null; public static synchronized void showHelp() { if (INSTANCE == null) INSTANCE = new Help(); INSTANCE.setVisible(true); } public Help() throws HeadlessException { super(I18nUtils.localizedStringForKey("dlg_help_title")); setIconImages(MainGUI.MOBAC_ICONS); setLayout(new GridBagLayout()); JLabel text = new JLabel(); JButton closeButton = new JButton(I18nUtils.localizedStringForKey("Close")); closeButton.setDefaultCapable(true); closeButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { setVisible(false); dispose(); } }); DataInputStream in = new DataInputStream( I18nUtils.getI18nResourceAsStream("resources/text/help_dialog", "html")); byte[] buf; try { buf = new byte[in.available()]; in.readFully(buf); in.close(); String helpMessage = new String(buf, Charsets.UTF_8); // Strip out all line breaks because JOptionPane shows // the raw HTML code otherwise // helpMessage = helpMessage.replaceAll("\n", ""); // text.setFont(mobac.gui.MainGUI.defaultFont()); text.setText(helpMessage); } catch (IOException e) { } add(text, GBC.eol().insets(10, 10, 10, 10)); add(closeButton, GBC.eol().anchor(GBC.CENTER).insets(0, 0, 0, 10)); pack(); Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); setLocation((dim.width - getWidth()) / 2, (dim.height - getHeight()) / 2); setAlwaysOnTop(true); setResizable(false); } public void windowActivated(WindowEvent e) { } public void windowClosed(WindowEvent e) { INSTANCE = null; } public void windowClosing(WindowEvent e) { } public void windowDeactivated(WindowEvent e) { } public void windowDeiconified(WindowEvent e) { } public void windowIconified(WindowEvent e) { } public void windowOpened(WindowEvent e) { } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/dialogs/FontChooser.java0000644000175000017500000001367012127544346027562 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.dialogs; import java.awt.Dialog.ModalityType; import java.awt.Font; import java.awt.GraphicsEnvironment; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.ListSelectionModel; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import mobac.utilities.GBCTable; import mobac.utilities.I18nUtils; public class FontChooser { private static final String FONT_NAMES[] = GraphicsEnvironment.getLocalGraphicsEnvironment() .getAvailableFontFamilyNames(); private static final String STYLES[] = new String[] { "Plain", "Bold", "Italic", "Bold + Italic" }; public static final Font DEFAULT = new Font(Font.SANS_SERIF, Font.PLAIN, 12); public static String encodeFont(Font font) { String style; switch (font.getStyle()) { case Font.PLAIN: style = "PLAIN"; break; case Font.BOLD: style = "BOLD"; break; case Font.ITALIC: style = "ITALIC"; break; case Font.BOLD | Font.ITALIC: style = "BOLDITALIC"; break; default: style = "PLAIN"; } return font.getName() + "-" + style + "-" + font.getSize(); } private static JScrollPane scroll(JList jList, String title) { JLabel jLabel = new JLabel(title); jLabel.setHorizontalAlignment(JLabel.CENTER); JScrollPane jScrollPane = new JScrollPane(jList); jScrollPane.setColumnHeaderView(jLabel); return jScrollPane; } private final JDialog jDialog = new JDialog(); private final JLabel jLabelPreview = new JLabel("DUMMY"); private final JList jListName = createJList(FONT_NAMES); private final JList jListStyle = createJList(STYLES); private final JList jListSize = createJList(new Integer[] { 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 }); private final JButton jButtonOK = new JButton(I18nUtils.localizedStringForKey("OK")), jButtonCancel = new JButton( I18nUtils.localizedStringForKey("Cancel")); private boolean wasCanceled; public FontChooser() { jDialog.setTitle(I18nUtils.localizedStringForKey("dlg_font_choose_title")); jDialog.setModalityType(ModalityType.APPLICATION_MODAL); jLabelPreview.setHorizontalAlignment(JLabel.CENTER); jLabelPreview.setVerticalAlignment(JLabel.CENTER); jLabelPreview.setBorder(BorderFactory.createTitledBorder(I18nUtils .localizedStringForKey("dlg_font_choose_preview"))); jButtonOK.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { wasCanceled = false; jDialog.setVisible(false); } }); jButtonCancel.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { jDialog.setVisible(false); } }); JPanel buttonPane = new JPanel(); buttonPane.add(jButtonOK); buttonPane.add(jButtonCancel); JPanel jPanel = new JPanel(new GridBagLayout()); jPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); GBCTable gbc = new GBCTable(); jPanel.add(scroll(jListName, I18nUtils.localizedStringForKey("dlg_font_choose_name")), gbc.begin().fill()); jPanel.add(scroll(jListStyle, I18nUtils.localizedStringForKey("dlg_font_choose_style")), gbc.incX().fill()); jPanel.add(scroll(jListSize, I18nUtils.localizedStringForKey("dlg_font_choose_size")), gbc.incX().fill()); jPanel.add(jLabelPreview, gbc.begin(1, 2).fillH().gridwidth(3)); jPanel.add(buttonPane, gbc.incY().fillH().gridwidth(3)); jDialog.setContentPane(jPanel); jDialog.setSize(384, 384); jDialog.setMinimumSize(jDialog.getSize()); setFont(DEFAULT); } private JList createJList(E[] objects) { JList jList = new JList(objects); jList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); jList.addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent e) { if (!e.getValueIsAdjusting()) { Font font = getFont(); jLabelPreview.setFont(font); jLabelPreview.setText(encodeFont(font)); } } }); return jList; } public void setFont(Font font) { if (font == null) { font = DEFAULT; } jListName.setSelectedValue(font.getName(), true); jListStyle.setSelectedIndex(font.getStyle()); jListSize.setSelectedValue(font.getSize(), true); } public Font getFont() { String name = (String) jListName.getSelectedValue(); if (name == null) { name = DEFAULT.getName(); } int style = jListStyle.getSelectedIndex(); if (style == -1) { style = DEFAULT.getStyle(); } Integer size = (Integer) jListSize.getSelectedValue(); if (size == null) { size = DEFAULT.getSize(); } return new Font(name, style, size); } public void show() { wasCanceled = true; jDialog.setLocationRelativeTo(jDialog.getParent()); jDialog.setVisible(true); } public boolean wasCanceled() { return wasCanceled; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/dialogs/WorkinprogressDialog.java0000644000175000017500000001162612127544346031506 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.dialogs; import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.Frame; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import mobac.program.tilestore.berkeleydb.DelayedInterruptThread; import mobac.utilities.I18nUtils; import mobac.utilities.Utilities; import org.apache.log4j.Logger; public class WorkinprogressDialog extends JDialog implements WindowListener { private static final Logger log = Logger.getLogger(WorkinprogressDialog.class); private final ThreadFactory threadFactory; private Thread workerThread; public WorkinprogressDialog(Frame owner, String title) { this(owner, title, Executors.defaultThreadFactory()); } public WorkinprogressDialog(Frame owner, String title, ThreadFactory threadFactory) { super(owner, title, true); this.threadFactory = threadFactory; setLayout(new FlowLayout()); add(new JLabel(new ImageIcon(Utilities.getResourceImageUrl("ajax-loader.gif")))); setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); setLocationRelativeTo(owner); addWindowListener(this); JButton abort = new JButton(I18nUtils.localizedStringForKey("dlg_progress_about_btn")); abort.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { log.debug("User interrupted process"); WorkinprogressDialog.this.close(); } }); add(abort); pack(); } public void startWork(final Runnable r) { workerThread = threadFactory.newThread(new Runnable() { public void run() { try { r.run(); } catch (Exception e) { log.error(e.getMessage(), e); } finally { WorkinprogressDialog.this.close(); log.debug("Worker thread finished"); } } }); Thread t1 = new Thread() { @Override public void run() { setVisible(true); } }; t1.start(); } protected synchronized void abortWorking() { try { if (workerThread != null && !workerThread.isInterrupted()) { log.debug("User aborted process - interrupting worker thread"); workerThread.interrupt(); workerThread = null; } } catch (Exception e) { log.error(e.getMessage()); } } public void close() { abortWorking(); setVisible(false); } public void windowActivated(WindowEvent event) { } public void windowOpened(WindowEvent event) { workerThread.start(); } public void windowClosed(WindowEvent event) { abortWorking(); } public void windowClosing(WindowEvent event) { } public void windowDeactivated(WindowEvent event) { } public void windowDeiconified(WindowEvent event) { } public void windowIconified(WindowEvent event) { } public static void main(String[] args) { JFrame parentFrame = new JFrame(); parentFrame.setSize(500, 150); final JLabel jl = new JLabel(); jl.setText(I18nUtils.localizedStringForKey("dlg_progress_count")); parentFrame.add(BorderLayout.CENTER, jl); parentFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); parentFrame.setVisible(true); final WorkinprogressDialog dlg = new WorkinprogressDialog(parentFrame, I18nUtils.localizedStringForKey("dlg_progress_title"), DelayedInterruptThread.createThreadFactory()); final Thread t = new Thread() { @Override public void run() { try { for (int i = 0; i <= 500; i++) { jl.setText(String.format(I18nUtils.localizedStringForKey("dlg_progress_count_i"),i)); if (Thread.currentThread().isInterrupted()) { System.out.println("Aborted"); return; } Thread.sleep(25); } } catch (InterruptedException e) { System.out.println("Aborted"); return; } finally { dlg.setVisible(false); } } }; dlg.startWork(t); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/dialogs/LicensesDialog.java0000644000175000017500000001130712127544346030211 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.dialogs; import java.awt.Dimension; import java.awt.GridBagLayout; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.image.BufferedImage; import java.io.IOException; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTabbedPane; import javax.swing.JTextArea; import javax.swing.UIManager; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import mobac.gui.MainGUI; import mobac.program.ProgramInfo; import mobac.utilities.GBC; import mobac.utilities.I18nUtils; import mobac.utilities.Utilities; public class LicensesDialog extends JFrame implements ChangeListener, ActionListener { private LicenseInfo[] licenses = new LicenseInfo[] { new LicenseInfo("

Mobile Atlas Creator

", "gpl.txt"), new LicenseInfo("

Library Apache Log4J

", "apache-2.0.txt"), new LicenseInfo("

Library Apache Commons Codec

", "apache-2.0.txt"), new LicenseInfo("

Library Apache Commons IO

", "apache-2.0.txt"), new LicenseInfo("

Library Berkely-DB JavaEdition

", "license-dbd-je.txt"), new LicenseInfo("

Library BeanShell

", "lgpl-3.0.txt"), new LicenseInfo("

Library JavaPNG

", "gpl.txt"), new LicenseInfo("

Library iTextPDF

", "agpl.txt") }; private final JTextArea textArea; private final JTabbedPane tab; private String currentLicense = null; public LicensesDialog() { super(I18nUtils.localizedStringForKey("dlg_license_title")); Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); setLayout(new GridBagLayout()); setIconImages(MainGUI.MOBAC_ICONS); setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); JButton ok = new JButton("OK"); textArea = new JTextArea(); textArea.setEditable(false); textArea.setBackground(this.getBackground()); JScrollPane textScroller = new JScrollPane(textArea); textScroller.setPreferredSize(new Dimension(700, (int) (dim.height * 0.8))); tab = new JTabbedPane(JTabbedPane.LEFT, JTabbedPane.WRAP_TAB_LAYOUT); Icon icon = new ImageIcon(new BufferedImage(1, 50, BufferedImage.TYPE_INT_ARGB)); boolean first = true; for (LicenseInfo li : licenses) { tab.addTab("" + li.name + "", icon, (first) ? textScroller : null); first = false; } tab.addChangeListener(this); stateChanged(null); add(tab, GBC.eol().anchor(GBC.NORTH).fill()); // add(textScroller, GBC.eol()); add(ok, GBC.eol().anchor(GBC.CENTER).insets(5, 10, 10, 10)); ok.addActionListener(this); pack(); setLocation((dim.width - getWidth()) / 2, (dim.height - getHeight()) / 2); } public void stateChanged(ChangeEvent event) { String license; try { String nextLicense = licenses[tab.getSelectedIndex()].licenseResource; if (nextLicense.equals(currentLicense)) return; license = Utilities.loadTextResource("text/" + nextLicense); currentLicense = nextLicense; } catch (IOException e) { license = "Failed to load license: " + e.getMessage(); } textArea.setText(license); textArea.setCaretPosition(0); } public void actionPerformed(ActionEvent e) { dispose(); } private static class LicenseInfo { public final String name; public final String licenseResource; public LicenseInfo(String name, String licenseResource) { super(); this.name = name; this.licenseResource = licenseResource; } } public static void main(String[] args) { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); ProgramInfo.initialize(); // Load revision info JFrame dlg = new LicensesDialog(); dlg.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/atlastree/0000755000175000017500000000000012127544350025014 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/atlastree/NodeRenderer.java0000644000175000017500000000527612122526604030242 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.atlastree; import java.awt.Component; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JTree; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.TreeCellRenderer; import mobac.program.interfaces.AtlasInterface; import mobac.program.interfaces.LayerInterface; import mobac.utilities.Utilities; public class NodeRenderer implements TreeCellRenderer { private static ImageIcon atlasIcon = new ImageIcon(); private static ImageIcon layerIcon = new ImageIcon(); private static ImageIcon mapIcon = new ImageIcon(); static { atlasIcon = Utilities.loadResourceImageIcon("atlas.png"); layerIcon = Utilities.loadResourceImageIcon("layer.png"); mapIcon = Utilities.loadResourceImageIcon("map.png"); } DefaultTreeCellRenderer atlasRenderer; DefaultTreeCellRenderer layerRenderer; DefaultTreeCellRenderer mapRenderer; public NodeRenderer() { atlasRenderer = new SimpleTreeCellRenderer(atlasIcon); layerRenderer = new SimpleTreeCellRenderer(layerIcon); mapRenderer = new SimpleTreeCellRenderer(mapIcon); } public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { TreeCellRenderer tcr; if (value instanceof AtlasInterface) { tcr = atlasRenderer; } else if (value instanceof LayerInterface) tcr = layerRenderer; else tcr = mapRenderer; return tcr.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); } protected static class SimpleTreeCellRenderer extends DefaultTreeCellRenderer { private static final long serialVersionUID = 1L; public SimpleTreeCellRenderer(Icon icon) { super(); setIcon(icon); setOpenIcon(icon); setClosedIcon(icon); setLeafIcon(icon); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/atlastree/JAtlasTree.java0000644000175000017500000003435512127544350027667 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.atlastree; import java.awt.Insets; import java.awt.Point; import java.awt.Rectangle; import java.awt.dnd.Autoscroll; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import javax.swing.AbstractAction; import javax.swing.ActionMap; import javax.swing.InputMap; import javax.swing.JCheckBoxMenuItem; import javax.swing.JComponent; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPopupMenu; import javax.swing.JTree; import javax.swing.KeyStroke; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; import javax.swing.tree.TreeSelectionModel; import mobac.gui.MainGUI; import mobac.gui.mapview.PreviewMap; import mobac.gui.mapview.layer.MapAreaHighlightingLayer; import mobac.program.interfaces.AtlasInterface; import mobac.program.interfaces.AtlasObject; import mobac.program.interfaces.CapabilityDeletable; import mobac.program.interfaces.LayerInterface; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.RequiresSQLite; import mobac.program.interfaces.ToolTipProvider; import mobac.program.model.Atlas; import mobac.program.model.AtlasOutputFormat; import mobac.program.model.AtlasTreeModel; import mobac.program.model.EastNorthCoordinate; import mobac.program.model.MapSelection; import mobac.program.model.Profile; import mobac.program.model.TileImageParameters; import mobac.utilities.GUIExceptionHandler; import mobac.utilities.I18nUtils; import mobac.utilities.jdbc.SQLiteLoader; import org.apache.log4j.Logger; public class JAtlasTree extends JTree implements Autoscroll { private static final long serialVersionUID = 1L; private static final int margin = 12; private static final String MSG_ATLAS_VERSION_MISMATCH = I18nUtils.localizedStringForKey("msg_atlas_version_mismatch"); private static final String MSG_ATLAS_DATA_CHECK_FAILED = I18nUtils.localizedStringForKey("msg_atlas_data_check_failed"); private static final String MSG_ATLAS_EMPTY = I18nUtils.localizedStringForKey("msg_atlas_is_empty"); private static final String ACTION_DELETE_NODE = "DELETE_NODE"; private static final Logger log = Logger.getLogger(JAtlasTree.class); private AtlasTreeModel treeModel; private PreviewMap mapView; protected NodeRenderer nodeRenderer; protected String defaultToolTiptext; protected KeyStroke deleteNodeKS; protected DragDropController ddc; protected boolean displaySelectedMapArea = false; public JAtlasTree(PreviewMap mapView) { super(new AtlasTreeModel()); if (mapView == null) throw new NullPointerException("MapView parameter is null"); this.mapView = mapView; getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); ddc = new DragDropController(this); treeModel = (AtlasTreeModel) getModel(); // setRootVisible(false); setShowsRootHandles(true); nodeRenderer = new NodeRenderer(); setCellRenderer(nodeRenderer); setCellEditor(new NodeEditor(this)); setToolTipText(""); defaultToolTiptext = I18nUtils.localizedStringForKey("lp_atlas_default_tip"); setAutoscrolls(true); addMouseListener(new MouseController(this)); InputMap inputMap = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); ActionMap actionMap = getActionMap(); // map moving inputMap.put(deleteNodeKS = KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), ACTION_DELETE_NODE); actionMap.put(ACTION_DELETE_NODE, new AbstractAction(I18nUtils.localizedStringForKey("lp_atlas_pop_menu_delete_node")) { private static final long serialVersionUID = 1L; public void actionPerformed(ActionEvent e) { deleteSelectedNode(); JAtlasTree.this.mapView.repaint(); } }); } public boolean testAtlasContentValid() { AtlasInterface atlas = getAtlas(); if (RequiresSQLite.class.isAssignableFrom(atlas.getOutputFormat().getMapCreatorClass())) { if (!SQLiteLoader.loadSQLiteOrShowError()) return false; } if (atlas.calculateTilesToDownload() == 0) { JOptionPane.showMessageDialog(null, "" + MSG_ATLAS_EMPTY + "", "Error - atlas has no content", JOptionPane.ERROR_MESSAGE); return false; } return true; } @Override public String getToolTipText(MouseEvent event) { if (getRowForLocation(event.getX(), event.getY()) == -1) return defaultToolTiptext; TreePath curPath = getPathForLocation(event.getX(), event.getY()); Object o = curPath.getLastPathComponent(); if (o == null || !(o instanceof ToolTipProvider)) return null; return ((ToolTipProvider) o).getToolTip(); } @Override public boolean isPathEditable(TreePath path) { return super.isPathEditable(path) && (path.getLastPathComponent() instanceof AtlasObject); } public AtlasTreeModel getTreeModel() { return treeModel; } public void newAtlas(String name, AtlasOutputFormat format) { log.debug("Creating new atlas"); Atlas newAtlas = Atlas.newInstance(); newAtlas.setOutputFormat(format); newAtlas.setName(name); treeModel.setAtlas(newAtlas); mapView.repaint(); } public void newAtlas() { log.debug("Resetting atlas tree model"); Atlas newAtlas = Atlas.newInstance(); newAtlas.setName(MainGUI.getMainGUI().getUserText()); treeModel.setAtlas(newAtlas); mapView.repaint(); } /** * Changes the atlas format */ public void convertAtlas(AtlasOutputFormat format) { log.debug("Converting the atlas format to " + format); treeModel.getAtlas().setOutputFormat(format); } public void deleteSelectedNode() { TreePath path = getSelectionPath(); if (path == null) return; TreeNode selected = (TreeNode) path.getLastPathComponent(); int[] selectedRows = getSelectionRows(); if (!(selected instanceof CapabilityDeletable)) return; treeModel.notifyNodeDelete(selected); ((CapabilityDeletable) selected).delete(); int selRow = Math.min(selectedRows[0], getRowCount() - 1); TreePath path1 = path.getParentPath(); TreePath path2 = getPathForRow(selRow).getParentPath(); if (path1 != path2) { // next row belongs to different parent node -> we select parent // node instead setSelectionPath(path1); } else { setSelectionRow(selRow); scrollRowToVisible(selRow); } } public AtlasInterface getAtlas() { return treeModel.getAtlas(); } public boolean load(Profile profile) { log.debug("Loading profile " + profile); try { treeModel.load(profile); if (treeModel.getAtlas() instanceof Atlas) { Atlas atlas = (Atlas) treeModel.getAtlas(); if (atlas.getVersion() < Atlas.CURRENT_ATLAS_VERSION) { JOptionPane.showMessageDialog(null, MSG_ATLAS_VERSION_MISMATCH, "Outdated atlas version", JOptionPane.WARNING_MESSAGE); return true; } } boolean problemsDetected = Profile.checkAtlas(treeModel.getAtlas()); if (problemsDetected) { JOptionPane.showMessageDialog(null, MSG_ATLAS_DATA_CHECK_FAILED, "Atlas loading problem", JOptionPane.WARNING_MESSAGE); } return true; } catch (Exception e) { GUIExceptionHandler.processException(e); return false; } } public boolean save(Profile profile) { try { treeModel.save(profile); return true; } catch (Exception e) { GUIExceptionHandler.processException(e); return false; } } protected void showNodePopupMenu(MouseEvent event) { JPopupMenu pm = new JPopupMenu(); final TreePath selPath = getPathForLocation(event.getX(), event.getY()); setSelectionPath(selPath); JMenuItem mi = null; if (selPath != null) { // not clicked on empty area final Object o = selPath.getLastPathComponent(); if (o == null) return; if (o instanceof ToolTipProvider) { mi = new JMenuItem(I18nUtils.localizedStringForKey("lp_atlas_pop_menu_show_detail")); mi.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ToolTipProvider ttp = (ToolTipProvider) o; JOptionPane.showMessageDialog(MainGUI.getMainGUI(), ttp.getToolTip()); } }); pm.add(mi); } if (o instanceof AtlasObject) { final JCheckBoxMenuItem cbmi = new JCheckBoxMenuItem(I18nUtils.localizedStringForKey("lp_atlas_pop_menu_display_select_area")); final MapAreaHighlightingLayer msl = new MapAreaHighlightingLayer(this); cbmi.setSelected(displaySelectedMapArea); cbmi.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (displaySelectedMapArea) { MapAreaHighlightingLayer.removeHighlightingLayers(); } else { mapView.setSelectionByTileCoordinate(null, null, false); MapAreaHighlightingLayer.removeHighlightingLayers(); mapView.mapLayers.add(msl); } displaySelectedMapArea = !displaySelectedMapArea; mapView.repaint(); } }); pm.add(cbmi); } if (o instanceof MapInterface) { mi = new JMenuItem(I18nUtils.localizedStringForKey("lp_atlas_pop_menu_select_map_box")); mi.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { MapInterface map = (MapInterface) o; mapView.setMapSource(map.getMapSource()); mapView.setSelectionByTileCoordinate(map.getZoom(), map.getMinTileCoordinate(), map .getMaxTileCoordinate(), true); } }); pm.add(mi); mi = new JMenuItem(I18nUtils.localizedStringForKey("lp_atlas_pop_menu_zoom_to_map_box")); mi.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { MapInterface map = (MapInterface) o; MapSelection ms = new MapSelection(map); mapView.setMapSource(map.getMapSource()); mapView.setSelectionAndZoomTo(ms, true); mapView.setSelectionByTileCoordinate(map.getZoom(), map.getMinTileCoordinate(), map .getMaxTileCoordinate(), true); } }); pm.add(mi); } if (o instanceof LayerInterface) { mi = new JMenuItem(I18nUtils.localizedStringForKey("lp_atlas_pop_menu_zoom_to")); mi.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { LayerInterface layer = (LayerInterface) o; EastNorthCoordinate max = new EastNorthCoordinate(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY); EastNorthCoordinate min = new EastNorthCoordinate(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY); for (MapInterface map : layer) { MapSelection ms = new MapSelection(map); EastNorthCoordinate mapMax = ms.getMax(); EastNorthCoordinate mapMin = ms.getMin(); max.lat = Math.max(max.lat, mapMax.lat); max.lon = Math.max(max.lon, mapMax.lon); min.lat = Math.min(min.lat, mapMin.lat); min.lon = Math.min(min.lon, mapMin.lon); } MapSelection ms = new MapSelection(mapView.getMapSource(), max, min); mapView.zoomTo(ms); } }); pm.add(mi); } if (o instanceof AtlasObject) { mi = new JMenuItem(I18nUtils.localizedStringForKey("lp_atlas_pop_menu_rename")); mi.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { JAtlasTree.this.startEditingAtPath(selPath); } }); pm.add(mi); mi = new JMenuItem(I18nUtils.localizedStringForKey("lp_atlas_pop_menu_apply_tile_process")); mi.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { AtlasObject atlasObject = (AtlasObject) o; TileImageParameters p = MainGUI.getMainGUI().getSelectedTileImageParameters(); applyTileImageParameters(atlasObject, p); } }); pm.add(mi); } if (o instanceof CapabilityDeletable) { pm.addSeparator(); mi = new JMenuItem(getActionMap().get(ACTION_DELETE_NODE)); mi.setAccelerator(deleteNodeKS); pm.add(mi); } } if (pm.getComponentCount() > 0) pm.addSeparator(); mi = new JMenuItem(I18nUtils.localizedStringForKey("lp_atlas_pop_menu_clear_atals")); mi.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { newAtlas(); } }); pm.add(mi); pm.show(this, event.getX(), event.getY()); } protected void applyTileImageParameters(Object o, TileImageParameters p) { if (o instanceof Iterable) { Iterable it = (Iterable) o; for (Object ao : it) { applyTileImageParameters(ao, p); } } else if (o instanceof MapInterface) { ((MapInterface) o).setParameters(p); } } protected void selectElementOnMap(Object o) { if (o instanceof MapInterface) { MapInterface map = (MapInterface) o; mapView.setMapSource(map.getMapSource()); mapView.setSelectionByTileCoordinate(map.getZoom(), map.getMinTileCoordinate(), map.getMaxTileCoordinate(), true); } } public void autoscroll(Point cursorLocn) { int realrow = getRowForLocation(cursorLocn.x, cursorLocn.y); Rectangle outer = getBounds(); realrow = (cursorLocn.y + outer.y <= margin ? realrow < 1 ? 0 : realrow - 1 : realrow < getRowCount() - 1 ? realrow + 1 : realrow); scrollRowToVisible(realrow); } public Insets getAutoscrollInsets() { Rectangle outer = getBounds(); Rectangle inner = getParent().getBounds(); return new Insets(inner.y - outer.y + margin, inner.x - outer.x + margin, outer.height - inner.height - inner.y + outer.y + margin, outer.width - inner.width - inner.x + outer.x + margin); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/atlastree/MouseController.java0000644000175000017500000000332512122526604031013 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.atlastree; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.tree.TreePath; public class MouseController extends MouseAdapter { JAtlasTree atlasTree; public MouseController(JAtlasTree atlasTree) { super(); this.atlasTree = atlasTree; } @Override public void mouseClicked(MouseEvent e) { if (e.getButton() != MouseEvent.BUTTON1 || e.getClickCount() != 2) return; TreePath selPath = atlasTree.getSelectionPath(); if (selPath == null) return; // clicked on empty area atlasTree.selectElementOnMap(selPath.getLastPathComponent()); } public void mousePressed(MouseEvent e) { if (e.isPopupTrigger()) { atlasTree.showNodePopupMenu(e); } } public void mouseReleased(MouseEvent e) { if (e.isPopupTrigger()) { atlasTree.showNodePopupMenu(e); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/atlastree/NodeEditor.java0000644000175000017500000000415512122526604027715 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.atlastree; import java.awt.Component; import javax.swing.DefaultCellEditor; import javax.swing.JTree; import javax.swing.tree.DefaultTreeCellEditor; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.TreeCellEditor; import javax.swing.tree.TreeCellRenderer; import mobac.gui.components.JAtlasNameField; public class NodeEditor extends DefaultTreeCellEditor { public NodeEditor(JAtlasTree atlasTree) { super(atlasTree, null); atlasTree.setEditable(true); } @Override public Component getTreeCellEditorComponent(JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row) { // Each node type has it's own TreeCellRenderer implementation // this not covered by DefaultTreeCellEditor - therefore we have to // correct the renderer each time an editorComponent is requested TreeCellRenderer tcr = tree.getCellRenderer(); renderer = (DefaultTreeCellRenderer) tcr.getTreeCellRendererComponent(tree, value, isSelected, expanded, leaf, row, true); return super.getTreeCellEditorComponent(tree, value, isSelected, expanded, leaf, row); } @Override protected TreeCellEditor createTreeCellEditor() { return new DefaultCellEditor(new JAtlasNameField()); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/atlastree/NodeTransferWrapper.java0000644000175000017500000000357712122526604031623 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.atlastree; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.io.IOException; import javax.swing.tree.TreeNode; import mobac.program.interfaces.AtlasObject; public class NodeTransferWrapper implements Transferable { public static final DataFlavor ATLAS_OBJECT_FLAVOR = new DataFlavor(AtlasObject.class, "AtlasObject"); public static final DataFlavor[] FLAVORS = new DataFlavor[] { ATLAS_OBJECT_FLAVOR }; private TreeNode node; public NodeTransferWrapper(TreeNode node) { this.node = node; } public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { if (!ATLAS_OBJECT_FLAVOR.equals(flavor)) throw new UnsupportedFlavorException(flavor); return node; } public DataFlavor[] getTransferDataFlavors() { return FLAVORS; } public boolean isDataFlavorSupported(DataFlavor flavor) { return ATLAS_OBJECT_FLAVOR.equals(flavor); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/atlastree/DragDropController.java0000644000175000017500000001644412127544350031436 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.atlastree; import java.awt.HeadlessException; import java.awt.Point; import java.awt.datatransfer.Transferable; import java.awt.dnd.DnDConstants; import java.awt.dnd.DragGestureEvent; import java.awt.dnd.DragGestureListener; import java.awt.dnd.DragGestureRecognizer; import java.awt.dnd.DragSource; import java.awt.dnd.DragSourceDragEvent; import java.awt.dnd.DragSourceDropEvent; import java.awt.dnd.DragSourceEvent; import java.awt.dnd.DragSourceListener; import java.awt.dnd.DropTarget; import java.awt.dnd.DropTargetContext; import java.awt.dnd.DropTargetDragEvent; import java.awt.dnd.DropTargetDropEvent; import java.awt.dnd.DropTargetEvent; import java.awt.dnd.DropTargetListener; import javax.swing.JOptionPane; import javax.swing.JTree; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; import mobac.exceptions.InvalidNameException; import mobac.program.interfaces.LayerInterface; import mobac.program.interfaces.MapInterface; import mobac.program.model.AtlasTreeModel; import mobac.utilities.I18nUtils; import org.apache.log4j.Logger; public class DragDropController { static Logger log = Logger.getLogger(DragDropController.class); public DragDropController(JAtlasTree atlasTree) { super(); this.atlasTree = atlasTree; new AtlasDragSource(); new AtlasDropTarget(); } JAtlasTree atlasTree; protected class AtlasDragSource implements DragSourceListener, DragGestureListener { final DragGestureRecognizer recognizer; final DragSource source; public AtlasDragSource() { source = new DragSource(); recognizer = source.createDefaultDragGestureRecognizer(atlasTree, DnDConstants.ACTION_MOVE, this); } public void dragGestureRecognized(DragGestureEvent dge) { TreePath path = atlasTree.getSelectionPath(); if ((path == null) || (path.getPathCount() <= 1)) // We can't move the root node or an empty selection return; TreeNode oldNode = (TreeNode) path.getLastPathComponent(); if (!(oldNode instanceof LayerInterface || oldNode instanceof MapInterface)) return; Transferable transferable = new NodeTransferWrapper(oldNode); source.startDrag(dge, DragSource.DefaultMoveNoDrop, transferable, this); } /** * Called whenever the drop target changes and it has bee accepted ( */ public void dragEnter(DragSourceDragEvent dsde) { dsde.getDragSourceContext().setCursor(DragSource.DefaultMoveDrop); } public void dragOver(DragSourceDragEvent dsde) { } public void dragDropEnd(DragSourceDropEvent dsde) { } public void dragExit(DragSourceEvent dse) { dse.getDragSourceContext().setCursor(DragSource.DefaultMoveNoDrop); } public void dropActionChanged(DragSourceDragEvent dsde) { } } protected class AtlasDropTarget implements DropTargetListener { final DropTarget target; public AtlasDropTarget() throws HeadlessException { super(); target = new DropTarget(atlasTree, this); } public synchronized void dragEnter(DropTargetDragEvent dtde) { } public synchronized void dragExit(DropTargetEvent dte) { } public synchronized void dragOver(DropTargetDragEvent dtde) { try { Transferable t = dtde.getTransferable(); Object o = t.getTransferData(NodeTransferWrapper.ATLAS_OBJECT_FLAVOR); TreeNode node = getNodeForEvent(dtde); if (o instanceof LayerInterface && node instanceof LayerInterface) { dtde.acceptDrag(dtde.getDropAction()); return; } if (o instanceof MapInterface && node instanceof LayerInterface || node instanceof MapInterface) { dtde.acceptDrag(dtde.getDropAction()); return; } dtde.rejectDrag(); } catch (Exception e) { log.error("", e); } } public void dropActionChanged(DropTargetDragEvent dtde) { } public synchronized void drop(DropTargetDropEvent dtde) { try { TreeNode sourceNode = (TreeNode) dtde.getTransferable().getTransferData( NodeTransferWrapper.ATLAS_OBJECT_FLAVOR); Point pt = dtde.getLocation(); DropTargetContext dtc = dtde.getDropTargetContext(); JTree tree = (JTree) dtc.getComponent(); TreePath parentpath = tree.getClosestPathForLocation(pt.x, pt.y); TreeNode targetNode = (TreeNode) parentpath.getLastPathComponent(); if (targetNode.equals(sourceNode) || targetNode.getParent().equals(sourceNode)) { dtde.rejectDrop(); return; } AtlasTreeModel atlasTreeModel = (AtlasTreeModel) atlasTree.getModel(); if (sourceNode instanceof LayerInterface && targetNode instanceof LayerInterface) mergeLayers(atlasTreeModel, (LayerInterface) sourceNode, (LayerInterface) targetNode); if (targetNode instanceof MapInterface) // We can not make a map child of another map // -> use it's layer instead targetNode = targetNode.getParent(); if (sourceNode instanceof MapInterface && targetNode instanceof LayerInterface) moveMap(atlasTreeModel, (MapInterface) sourceNode, (LayerInterface) targetNode); } catch (Exception e) { log.error("", e); atlasTree.getTreeModel().notifyStructureChanged(); dtde.rejectDrop(); } } protected void mergeLayers(AtlasTreeModel atlasTreeModel, LayerInterface sourceLayer, LayerInterface targetLayer) throws InvalidNameException { int answer = JOptionPane.showConfirmDialog(null, String.format(I18nUtils.localizedStringForKey("msg_confirm_merge_layer"), sourceLayer.getName(), targetLayer.getName()), I18nUtils.localizedStringForKey("msg_confirm_merge_layer_title"), JOptionPane.YES_NO_OPTION); if (answer != JOptionPane.YES_OPTION) return; try { atlasTreeModel.mergeLayers(sourceLayer, targetLayer); } catch (InvalidNameException e) { JOptionPane.showMessageDialog(null, e.getMessage(), I18nUtils.localizedStringForKey("msg_merge_layer_failed"), JOptionPane.ERROR_MESSAGE); throw e; } } protected void moveMap(AtlasTreeModel atlasTreeModel, MapInterface map, LayerInterface targetLayer) throws InvalidNameException { atlasTreeModel.moveMap(map, targetLayer); } private TreeNode getNodeForEvent(DropTargetDragEvent dtde) { Point p = dtde.getLocation(); DropTargetContext dtc = dtde.getDropTargetContext(); JTree tree = (JTree) dtc.getComponent(); TreePath path = tree.getClosestPathForLocation(p.x, p.y); return (TreeNode) path.getLastPathComponent(); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/listeners/0000755000175000017500000000000012122526604025035 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/listeners/AtlasModelListener.java0000644000175000017500000000337512122526604031443 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ /** * */ package mobac.gui.listeners; import javax.swing.event.TreeModelEvent; import javax.swing.event.TreeModelListener; import mobac.gui.atlastree.JAtlasTree; import mobac.gui.panels.JProfilesPanel; public class AtlasModelListener implements TreeModelListener { JAtlasTree atlasTree; JProfilesPanel profilesPanel; public AtlasModelListener(JAtlasTree atlasTree, JProfilesPanel profilesPanel) { super(); this.atlasTree = atlasTree; this.profilesPanel = profilesPanel; } protected void changed() { profilesPanel.getSaveAsButton().setEnabled(atlasTree.getAtlas().getLayerCount() > 0); } public void treeNodesChanged(TreeModelEvent e) { changed(); } public void treeNodesInserted(TreeModelEvent e) { changed(); } public void treeNodesRemoved(TreeModelEvent e) { changed(); } public void treeStructureChanged(TreeModelEvent e) { changed(); } }mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/AtlasProgress.java0000644000175000017500000006642612174511554026504 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui; import java.awt.Container; import java.awt.Dimension; import java.awt.Font; import java.awt.GridBagLayout; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.File; import java.util.ArrayList; import java.util.Timer; import java.util.TimerTask; import javax.swing.Box; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.SwingUtilities; import javax.swing.ToolTipManager; import javax.swing.UIManager; import mobac.program.AtlasThread; import mobac.program.Logging; import mobac.program.interfaces.AtlasInterface; import mobac.program.interfaces.LayerInterface; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSourceListener; import mobac.program.model.AtlasOutputFormat; import mobac.program.model.Settings; import mobac.utilities.GBC; import mobac.utilities.GUIExceptionHandler; import mobac.utilities.I18nUtils; import mobac.utilities.OSUtilities; import mobac.utilities.Utilities; import org.apache.log4j.Logger; /** * A window showing the progress while {@link AtlasThread} downloads and processes the map tiles. * */ public class AtlasProgress extends JFrame implements ActionListener, MapSourceListener { private static Logger log = Logger.getLogger(AtlasProgress.class); private static final long serialVersionUID = -1L; private static final Timer TIMER = new Timer(true); private JProgressBar atlasProgressBar; private JProgressBar mapDownloadProgressBar; private JProgressBar mapCreationProgressBar; private Container background; private long initialTotalTime; private long initialMapDownloadTime; private static class Data { AtlasInterface atlasInterface; MapInterface map; MapInfo mapInfo; long numberOfDownloadedBytes = 0; long numberOfBytesLoadedFromCache = 0; int totalNumberOfTiles = 0; int totalNumberOfMaps = 0; int totalProgress = 0; int totalProgressTenthPercent = -1; int currentMapNumber = 0; int mapDownloadProgress = 0; int mapDownloadNumberOfTiles = 0; int mapCreationProgress = 0; int mapCreationMax = 0; int mapRetryErrors = 0; int mapPermanentErrors = 0; int prevMapsRetryErrors = 0; int prevMapsPermanentErrors = 0; boolean paused = false; } private final Data data = new Data(); private boolean aborted = false; private boolean finished = false; private JLabel windowTitle; private JLabel title; private JLabel mapInfoLabel; private JLabel mapDownloadTitle; private JLabel atlasPercent; private JLabel mapDownloadPercent; private JLabel atlasMapsDone; private JLabel mapDownloadElementsDone; private JLabel atlasTimeLeft; private JLabel mapDownloadTimeLeft; private JLabel mapCreation; private JLabel nrOfDownloadedBytes; private JLabel nrOfDownloadedBytesValue; private JLabel nrOfDownloadedBytesPerSecond; private JLabel nrOfDownloadedBytesPerSecondValue; private JLabel nrOfCacheBytes; private JLabel nrOfCacheBytesValue; private JLabel activeDownloads; private JLabel activeDownloadsValue; private JLabel retryableDownloadErrors; private JLabel retryableDownloadErrorsValue; private JLabel permanentDownloadErrors; private JLabel permanentDownloadErrorsValue; private JLabel totalDownloadTime; private JLabel totalDownloadTimeValue; private JCheckBox ignoreDlErrors; private JLabel statusLabel; private JButton dismissWindowButton; private JButton openProgramFolderButton; private JButton abortAtlasCreationButton; private JButton pauseResumeDownloadButton; private AtlasCreationController downloadControlListener = null; private UpdateTask updateTask = null; private GUIUpdater guiUpdater = null; private AtlasThread atlasThread; private ArrayList mapInfos = null; private static String TEXT_MAP_DOWNLOAD = I18nUtils.localizedStringForKey("dlg_download_zoom_level_progress"); private static String TEXT_PERCENT = I18nUtils.localizedStringForKey("dlg_download_done_percent"); private static String TEXT_TENTHPERCENT = I18nUtils.localizedStringForKey("dlg_download_done_tenthpercent"); public AtlasProgress(AtlasThread atlasThread) { super(I18nUtils.localizedStringForKey("dlg_download_title")); this.atlasThread = atlasThread; ToolTipManager.sharedInstance().setDismissDelay(12000); if (MainGUI.getMainGUI() == null) // Atlas creation started via command-line, no MainGUi available setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); else setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); setIconImages(MainGUI.MOBAC_ICONS); setLayout(new GridBagLayout()); updateTask = new UpdateTask(); guiUpdater = new GUIUpdater(); createComponents(); // Initialize the layout in respect to the layout (font size ...) pack(); guiUpdater.run(); // The layout is now initialized - we disable it because we don't want // want to the labels to jump around if the content changes. background.setLayout(null); setResizable(false); Dimension dScreen = Toolkit.getDefaultToolkit().getScreenSize(); Dimension dContent = getSize(); setLocation((dScreen.width - dContent.width) / 2, (dScreen.height - dContent.height) / 2); initialTotalTime = System.currentTimeMillis(); initialMapDownloadTime = System.currentTimeMillis(); addWindowListener(new CloseListener()); } private void createComponents() { background = new JPanel(new GridBagLayout()); windowTitle = new JLabel(I18nUtils.localizedStringForKey("dlg_download_window_title")); title = new JLabel(I18nUtils.localizedStringForKey("dlg_download_map_progress")); mapInfoLabel = new JLabel(); atlasMapsDone = new JLabel(I18nUtils.localizedStringForKey("dlg_download_map_done_count_default")); atlasPercent = new JLabel(String.format(TEXT_TENTHPERCENT, 100.0)); atlasTimeLeft = new JLabel(I18nUtils.localizedStringForKey("dlg_download_remain_time_default"), JLabel.RIGHT); atlasProgressBar = new JProgressBar(); mapDownloadTitle = new JLabel(TEXT_MAP_DOWNLOAD + "000"); mapDownloadElementsDone = new JLabel(I18nUtils.localizedStringForKey("dlg_download_tile_done_count_default")); mapDownloadPercent = new JLabel(String.format(TEXT_PERCENT, 100)); mapDownloadTimeLeft = new JLabel(I18nUtils.localizedStringForKey("dlg_download_remain_time_default"), JLabel.RIGHT); mapDownloadProgressBar = new JProgressBar(); mapCreation = new JLabel(I18nUtils.localizedStringForKey("dlg_download_map_create_title")); mapCreationProgressBar = new JProgressBar(); nrOfDownloadedBytesPerSecond = new JLabel(I18nUtils.localizedStringForKey("dlg_download_avg_speed")); nrOfDownloadedBytesPerSecondValue = new JLabel(); nrOfDownloadedBytes = new JLabel(I18nUtils.localizedStringForKey("dlg_download_total_bytes")); nrOfDownloadedBytesValue = new JLabel(); nrOfCacheBytes = new JLabel(I18nUtils.localizedStringForKey("dlg_download_bytes_from_cache")); nrOfCacheBytesValue = new JLabel(); activeDownloads = new JLabel(I18nUtils.localizedStringForKey("dlg_download_thread_count")); activeDownloadsValue = new JLabel(); retryableDownloadErrors = new JLabel(I18nUtils.localizedStringForKey("dlg_download_retry_count")); retryableDownloadErrors.setToolTipText(I18nUtils.localizedStringForKey("dlg_download_error_tips")); retryableDownloadErrorsValue = new JLabel(); retryableDownloadErrorsValue.setToolTipText(retryableDownloadErrors.getToolTipText()); permanentDownloadErrors = new JLabel(I18nUtils.localizedStringForKey("dlg_download_failed_count")); permanentDownloadErrors.setToolTipText(I18nUtils.localizedStringForKey("dlg_download_error_tips")); permanentDownloadErrorsValue = new JLabel(); permanentDownloadErrorsValue.setToolTipText(permanentDownloadErrors.getToolTipText()); totalDownloadTime = new JLabel(I18nUtils.localizedStringForKey("dlg_download_total_time")); totalDownloadTimeValue = new JLabel(); ignoreDlErrors = new JCheckBox(I18nUtils.localizedStringForKey("dlg_download_checkbox_ignore_error"), Settings.getInstance().ignoreDlErrors); statusLabel = new JLabel(I18nUtils.localizedStringForKey("dlg_download_status_title")); Font f = statusLabel.getFont(); statusLabel.setFont(f.deriveFont(Font.BOLD)); abortAtlasCreationButton = new JButton(I18nUtils.localizedStringForKey("dlg_download_btn_abort")); abortAtlasCreationButton.setToolTipText(I18nUtils.localizedStringForKey("dlg_download_btn_abort_tips")); dismissWindowButton = new JButton(I18nUtils.localizedStringForKey("dlg_download_btn_close_win")); dismissWindowButton.setToolTipText(I18nUtils.localizedStringForKey("dlg_download_btn_close_win_tips_disable")); dismissWindowButton.setVisible(false); openProgramFolderButton = new JButton(I18nUtils.localizedStringForKey("dlg_download_btn_open_folder")); openProgramFolderButton.setToolTipText(I18nUtils .localizedStringForKey("dlg_download_btn_open_folder_tips_disabled")); openProgramFolderButton.setEnabled(false); pauseResumeDownloadButton = new JButton(I18nUtils.localizedStringForKey("dlg_download_btn_pause_resume")); GBC gbcRIF = GBC.std().insets(0, 0, 20, 0).fill(GBC.HORIZONTAL); GBC gbcEol = GBC.eol(); GBC gbcEolFill = GBC.eol().fill(GBC.HORIZONTAL); GBC gbcEolFillI = GBC.eol().fill(GBC.HORIZONTAL).insets(0, 5, 0, 0); // background.add(windowTitle, gbcEolFill); // background.add(Box.createVerticalStrut(10), gbcEol); background.add(mapInfoLabel, gbcEolFill); background.add(Box.createVerticalStrut(20), gbcEol); background.add(title, gbcRIF); background.add(atlasMapsDone, gbcRIF); background.add(atlasPercent, gbcRIF); background.add(atlasTimeLeft, gbcEolFill); background.add(atlasProgressBar, gbcEolFillI); background.add(Box.createVerticalStrut(20), gbcEol); background.add(mapDownloadTitle, gbcRIF); background.add(mapDownloadElementsDone, gbcRIF); background.add(mapDownloadPercent, gbcRIF); background.add(mapDownloadTimeLeft, gbcEolFill); background.add(mapDownloadProgressBar, gbcEolFillI); background.add(Box.createVerticalStrut(20), gbcEol); background.add(mapCreation, gbcEol); background.add(mapCreationProgressBar, gbcEolFillI); background.add(Box.createVerticalStrut(10), gbcEol); JPanel infoPanel = new JPanel(new GridBagLayout()); GBC gbci = GBC.std().insets(0, 3, 3, 3); infoPanel.add(nrOfDownloadedBytes, gbci); infoPanel.add(nrOfDownloadedBytesValue, gbci.toggleEol()); infoPanel.add(nrOfCacheBytes, gbci.toggleEol()); infoPanel.add(nrOfCacheBytesValue, gbci.toggleEol()); infoPanel.add(nrOfDownloadedBytesPerSecond, gbci.toggleEol()); infoPanel.add(nrOfDownloadedBytesPerSecondValue, gbci.toggleEol()); infoPanel.add(activeDownloads, gbci.toggleEol()); infoPanel.add(activeDownloadsValue, gbci.toggleEol()); infoPanel.add(retryableDownloadErrors, gbci.toggleEol()); infoPanel.add(retryableDownloadErrorsValue, gbci.toggleEol()); infoPanel.add(permanentDownloadErrors, gbci.toggleEol()); infoPanel.add(permanentDownloadErrorsValue, gbci.toggleEol()); infoPanel.add(totalDownloadTime, gbci.toggleEol()); infoPanel.add(totalDownloadTimeValue, gbci.toggleEol()); JPanel bottomPanel = new JPanel(new GridBagLayout()); bottomPanel.add(infoPanel, GBC.std().gridheight(2).fillH()); bottomPanel.add(ignoreDlErrors, GBC.eol().anchor(GBC.EAST)); bottomPanel.add(statusLabel, GBC.eol().anchor(GBC.CENTER)); GBC gbcRight = GBC.std().anchor(GBC.SOUTHEAST).insets(5, 0, 0, 0); bottomPanel.add(Box.createHorizontalGlue(), GBC.std().fill(GBC.HORIZONTAL)); bottomPanel.add(abortAtlasCreationButton, gbcRight); bottomPanel.add(dismissWindowButton, gbcRight); bottomPanel.add(pauseResumeDownloadButton, gbcRight); bottomPanel.add(openProgramFolderButton, gbcRight); background.add(bottomPanel, gbcEolFillI); JPanel borderPanel = new JPanel(new GridBagLayout()); borderPanel.add(background, GBC.std().insets(10, 10, 10, 10).fill()); add(borderPanel, GBC.std().fill()); abortAtlasCreationButton.addActionListener(this); dismissWindowButton.addActionListener(this); openProgramFolderButton.addActionListener(this); pauseResumeDownloadButton.addActionListener(this); } public void initAtlas(AtlasInterface atlasInterface) { data.atlasInterface = atlasInterface; if (atlasInterface.getOutputFormat().equals(AtlasOutputFormat.TILESTORE)) data.totalNumberOfTiles = (int) atlasInterface.calculateTilesToDownload(); else data.totalNumberOfTiles = (int) atlasInterface.calculateTilesToDownload() * 2; int mapCount = 0; int tileCount = 0; mapInfos = new ArrayList(100); for (LayerInterface layer : atlasInterface) { mapCount += layer.getMapCount(); for (MapInterface map : layer) { int before = tileCount; int mapTiles = (int) map.calculateTilesToDownload(); tileCount += mapTiles + mapTiles; mapInfos.add(new MapInfo(map, before, tileCount)); } } mapInfos.trimToSize(); data.totalNumberOfMaps = mapCount; initialTotalTime = System.currentTimeMillis(); initialMapDownloadTime = -1; updateGUI(); setVisible(true); TIMER.schedule(updateTask, 0, 500); } public void initMapDownload(MapInterface map) { int index = mapInfos.indexOf(new MapInfo(map, 0, 0)); data.mapInfo = mapInfos.get(index); data.totalProgress = data.mapInfo.tileCountOnStart; data.map = map; data.mapDownloadNumberOfTiles = (int) map.calculateTilesToDownload(); initialMapDownloadTime = System.currentTimeMillis(); data.prevMapsPermanentErrors += data.mapPermanentErrors; data.prevMapsRetryErrors += data.mapRetryErrors; data.mapCreationProgress = 0; data.mapDownloadProgress = 0; data.currentMapNumber = index + 1; updateGUI(); } /** * Initialize the GUI progress bars * * @param maxTilesToProcess */ public void initMapCreation(int maxTilesToProcess) { data.mapCreationProgress = 0; data.mapCreationMax = maxTilesToProcess; initialMapDownloadTime = -1; updateGUI(); } public void setErrorCounter(int retryErrors, int permanentErrors) { data.mapRetryErrors = retryErrors; data.mapPermanentErrors = permanentErrors; updateGUI(); } public void incMapDownloadProgress() { data.mapDownloadProgress++; data.totalProgress++; updateGUI(); } public void incMapCreationProgress() { setMapCreationProgress(data.mapCreationProgress + 1); } public void incMapCreationProgress(int stepSize) { setMapCreationProgress(data.mapCreationProgress + stepSize); } public void setMapCreationProgress(int progress) { data.mapCreationProgress = progress; data.totalProgress = data.mapInfo.tileCountOnStart + data.mapInfo.mapTiles + (int) (((long) data.mapInfo.mapTiles) * data.mapCreationProgress / data.mapCreationMax); updateGUI(); } public boolean ignoreDownloadErrors() { return ignoreDlErrors.isSelected(); } public void tileDownloaded(int size) { synchronized (data) { data.numberOfDownloadedBytes += size; } updateGUI(); } public void tileLoadedFromCache(int size) { synchronized (data) { data.numberOfBytesLoadedFromCache += size; } updateGUI(); } private String formatTime(long longSeconds) { String timeString = ""; if (longSeconds < 0) { timeString = I18nUtils.localizedStringForKey("dlg_download_time_unknown"); } else { int minutes = (int) (longSeconds / 60); int seconds = (int) (longSeconds % 60); if (minutes > 0) timeString += Integer.toString(minutes) + " " + (minutes == 1 ? I18nUtils.localizedStringForKey("minute") : I18nUtils .localizedStringForKey("minutes")) + " "; timeString += Integer.toString(seconds) + " " + (seconds == 1 ? I18nUtils.localizedStringForKey("second") : I18nUtils .localizedStringForKey("seconds")); } return timeString; } public void setZoomLevel(int theZoomLevel) { mapDownloadTitle.setText(TEXT_MAP_DOWNLOAD + Integer.toString(theZoomLevel)); } public void atlasCreationFinished() { finished = true; stopUpdateTask(); forceUpdateGUI(); downloadControlListener = null; SwingUtilities.invokeLater(new Runnable() { public void run() { abortAtlasCreationButton.setEnabled(false); if (aborted) { windowTitle.setText(I18nUtils.localizedStringForKey("dlg_download_abort_window_title")); setTitle(I18nUtils.localizedStringForKey("dlg_download_abort_title")); } else { windowTitle.setText(I18nUtils.localizedStringForKey("dlg_download_succeed_window_title")); setTitle(I18nUtils.localizedStringForKey("dlg_download_succeed_title")); } // mapInfoLabel.setText(""); atlasMapsDone.setText(String.format(I18nUtils.localizedStringForKey("dlg_download_map_done_count"), data.currentMapNumber, data.totalNumberOfMaps)); abortAtlasCreationButton.setVisible(false); dismissWindowButton.setToolTipText(I18nUtils .localizedStringForKey("dlg_download_btn_close_win_tips_enable")); dismissWindowButton.setVisible(true); if (!aborted) { openProgramFolderButton.setToolTipText(I18nUtils .localizedStringForKey("dlg_download_btn_open_folder_tips_enabled")); openProgramFolderButton.setEnabled(true); } } }); } private synchronized void stopUpdateTask() { try { updateTask.cancel(); updateTask = null; } catch (Exception e) { } } public void closeWindow() { try { stopUpdateTask(); downloadControlListener = null; setVisible(false); } finally { dispose(); } } public AtlasCreationController getDownloadControlListener() { return downloadControlListener; } public void setDownloadControlerListener(AtlasCreationController threadControlListener) { this.downloadControlListener = threadControlListener; } public void actionPerformed(ActionEvent event) { Object source = event.getSource(); File atlasFolder = Settings.getInstance().getAtlasOutputDirectory(); if (openProgramFolderButton.equals(source)) { try { OSUtilities.openFolderBrowser(atlasFolder); } catch (Exception e) { log.error("", e); } } else if (dismissWindowButton.equals(source)) { downloadControlListener = null; closeWindow(); } else if (abortAtlasCreationButton.equals(source)) { aborted = true; stopUpdateTask(); if (downloadControlListener != null) downloadControlListener.abortAtlasCreation(); else closeWindow(); } else if (pauseResumeDownloadButton.equals(source)) { if (downloadControlListener != null) downloadControlListener.pauseResumeAtlasCreation(); } } public void updateGUI() { guiUpdater.updateAsynchronously(); } public void forceUpdateGUI() { SwingUtilities.invokeLater(guiUpdater); } private class GUIUpdater implements Runnable { int scheduledCounter = 0; public void updateAsynchronously() { // If there is still at least one scheduled update request to be // executed we don't have add another one as this can result in an // to overloaded swing invocation queue. synchronized (this) { if (scheduledCounter > 0) return; scheduledCounter++; } SwingUtilities.invokeLater(this); } public void run() { synchronized (this) { scheduledCounter--; } if (data.map != null) { String text = String.format(I18nUtils.localizedStringForKey("dlg_download_map_info_label"), data.map.getName(), data.map.getLayer().getName(), data.map.getMapSource().toString()); mapInfoLabel.setText(text); } // atlas progress atlasProgressBar.setMaximum(data.totalNumberOfTiles); atlasProgressBar.setValue(data.totalProgress); int newTenthPercent = (int) (data.totalProgress * 1000d / (double) data.totalNumberOfTiles); try { boolean pauseState = atlasThread.isPaused(); String statusText = I18nUtils.localizedStringForKey("dlg_download_status_running"); if (aborted) statusText = I18nUtils.localizedStringForKey("dlg_download_status_aborted"); else if (finished) statusText = I18nUtils.localizedStringForKey("dlg_download_status_finished"); else if (pauseState) statusText = I18nUtils.localizedStringForKey("dlg_download_status_paused"); else statusText = I18nUtils.localizedStringForKey("dlg_download_status_running"); statusLabel.setText(I18nUtils.localizedStringForKey("dlg_download_status_title") + " " + statusText); if (data.totalProgressTenthPercent != newTenthPercent || pauseState != data.paused) { data.totalProgressTenthPercent = newTenthPercent; atlasPercent.setText(String.format(TEXT_TENTHPERCENT, data.totalProgressTenthPercent / 10.0)); if (data.atlasInterface != null) { String text = String.format(I18nUtils.localizedStringForKey("dlg_download_atlas_progress"), data.totalProgressTenthPercent / 10, data.atlasInterface.getName(), data.atlasInterface.getOutputFormat()); if (pauseState) text += " [" + I18nUtils.localizedStringForKey("dlg_download_status_paused") + "]"; AtlasProgress.this.setTitle(text); } } data.paused = pauseState; } catch (NullPointerException e) { } long seconds = -1; int totalProgress = data.totalProgress; if (totalProgress != 0) { // Avoid for a possible division by zero int totalTilesRemaining = data.totalNumberOfTiles - totalProgress; long totalElapsedTime = System.currentTimeMillis() - initialTotalTime; seconds = (totalElapsedTime * totalTilesRemaining / (1000L * totalProgress)); } atlasTimeLeft.setText(String.format(I18nUtils.localizedStringForKey("dlg_download_remain_time"), formatTime(seconds))); // layer progress mapDownloadProgressBar.setMaximum(data.mapDownloadNumberOfTiles); mapDownloadProgressBar.setValue(data.mapDownloadProgress); mapDownloadPercent.setText(String.format(TEXT_PERCENT, (int) (mapDownloadProgressBar.getPercentComplete() * 100))); mapDownloadElementsDone.setText(String.format( I18nUtils.localizedStringForKey("dlg_download_tile_done_count"), data.mapDownloadProgress, data.mapDownloadNumberOfTiles)); seconds = -1; int mapDlProgress = data.mapDownloadProgress; if (mapDlProgress != 0 && initialMapDownloadTime > 0) seconds = ((System.currentTimeMillis() - initialMapDownloadTime) * (data.mapDownloadNumberOfTiles - mapDlProgress) / (1000L * mapDlProgress)); mapDownloadTimeLeft.setText(String.format(I18nUtils.localizedStringForKey("dlg_download_remain_time"), formatTime(seconds))); // map progress mapCreation.setText(I18nUtils.localizedStringForKey("dlg_download_map_create_title")); mapCreationProgressBar.setValue(data.mapCreationProgress); mapCreationProgressBar.setMaximum(data.mapCreationMax); atlasMapsDone.setText(String.format(I18nUtils.localizedStringForKey("dlg_download_map_done_count"), (data.currentMapNumber - 1), data.totalNumberOfMaps)); // bytes per second long rate = data.numberOfDownloadedBytes * 1000; long time = System.currentTimeMillis() - initialMapDownloadTime; if (data.mapCreationProgress == 0 && initialMapDownloadTime > 0) { if (time == 0) { nrOfDownloadedBytesPerSecondValue.setText("??"); } else { rate = rate / time; nrOfDownloadedBytesPerSecondValue.setText(String.format( I18nUtils.localizedStringForKey("dlg_download_avg_speed_value"), Utilities.formatBytes(rate))); } } // downloaded bytes nrOfDownloadedBytesValue.setText(": " + Utilities.formatBytes(data.numberOfDownloadedBytes)); nrOfCacheBytesValue.setText(": " + Utilities.formatBytes(data.numberOfBytesLoadedFromCache)); // total creation time long totalSeconds = (System.currentTimeMillis() - initialTotalTime) / 1000; totalDownloadTimeValue.setText(": " + formatTime(totalSeconds)); totalDownloadTimeValue.repaint(); // active downloads int activeDownloads = (atlasThread == null) ? 0 : atlasThread.getActiveDownloads(); activeDownloadsValue.setText(": " + activeDownloads); activeDownloadsValue.repaint(); int totalRetryableErrors = data.prevMapsRetryErrors + data.mapRetryErrors; retryableDownloadErrorsValue.setText(String.format( I18nUtils.localizedStringForKey("dlg_download_retry_count_value"), data.mapRetryErrors, totalRetryableErrors)); retryableDownloadErrorsValue.repaint(); int totalPermanentErrors = data.prevMapsPermanentErrors + data.mapPermanentErrors; permanentDownloadErrorsValue.setText(String.format( I18nUtils.localizedStringForKey("dlg_download_failed_count_value"), data.mapPermanentErrors, totalPermanentErrors)); permanentDownloadErrorsValue.repaint(); } } private class UpdateTask extends TimerTask { @Override public void run() { updateGUI(); } } private class CloseListener extends WindowAdapter { @Override public void windowClosing(WindowEvent e) { log.debug("Closing event detected for atlas progress window"); AtlasCreationController listener = AtlasProgress.this.downloadControlListener; if (listener != null) listener.abortAtlasCreation(); } } protected static class MapInfo { final MapInterface map; final int tileCountOnStart; final int tileCountOnEnd; final int mapTiles; public MapInfo(MapInterface map, int tileCountOnStart, int tileCountOnEnd) { super(); this.map = map; this.tileCountOnStart = tileCountOnStart; this.tileCountOnEnd = tileCountOnEnd; this.mapTiles = (int) map.calculateTilesToDownload(); } @Override public int hashCode() { return map.hashCode(); } @Override public boolean equals(Object obj) { if (!(obj instanceof MapInfo)) return false; return map.equals(((MapInfo) obj).map); } } public static interface AtlasCreationController { public void abortAtlasCreation(); public void pauseResumeAtlasCreation(); public boolean isPaused(); } public static void main(String[] args) { Logging.configureLogging(); GUIExceptionHandler.installToolkitEventQueueProxy(); try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception e) { log.error("The selection of look and feel failed!", e); } AtlasProgress ap = new AtlasProgress(null); ap.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); ap.setVisible(true); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/0000755000175000017500000000000012150552674024504 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/PreviewMap.java0000644000175000017500000004233112150552674027431 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.mapview; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.util.LinkedList; import mobac.gui.mapview.controller.DefaultMapController; import mobac.gui.mapview.controller.JMapController; import mobac.gui.mapview.controller.MapKeyboardController; import mobac.gui.mapview.controller.RectangleSelectionMapController; import mobac.gui.mapview.interfaces.MapEventListener; import mobac.mapsources.MapSourcesManager; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSourceTextAttribution; import mobac.program.interfaces.MapSpace; import mobac.program.model.Bookmark; import mobac.program.model.EastNorthCoordinate; import mobac.program.model.MapSelection; import mobac.program.model.MercatorPixelCoordinate; import mobac.program.model.Settings; import mobac.utilities.I18nUtils; import mobac.utilities.MyMath; import org.apache.log4j.Logger; public class PreviewMap extends JMapViewer { private static final long serialVersionUID = 1L; public static final Color GRID_COLOR = new Color(200, 20, 20, 130); public static final Color SEL_COLOR = new Color(0.9f, 0.7f, 0.7f, 0.6f); public static final Color MAP_COLOR = new Color(1.0f, 0.84f, 0.0f, 0.4f); public static final int MAP_CONTROLLER_RECTANGLE_SELECT = 0; public static final int MAP_CONTROLLER_GPX = 1; protected static final Font LOADING_FONT = new Font("Sans Serif", Font.BOLD, 30); private static Logger log = Logger.getLogger(PreviewMap.class); /** * Interactive map selection max/min pixel coordinates regarding zoom level MAX_ZOOM */ private Point iSelectionMin; private Point iSelectionMax; /** * Map selection max/min pixel coordinates regarding zoom level MAX_ZOOM with respect to the grid zoom. */ private Point gridSelectionStart; private Point gridSelectionEnd; /** * Pre-painted transparent tile with grid lines on it. This makes painting the grid a lot faster in difference to * painting each line or rectangle if the grid zoom is much higher that the current zoom level. */ private BufferedImage gridTile = new BufferedImage(256, 256, BufferedImage.TYPE_INT_ARGB); private int gridZoom = -1; private int gridSize; protected LinkedList mapEventListeners = new LinkedList(); protected JMapController mapKeyboardController; protected JMapController mapSelectionController; protected DefaultMapController defaultMapController; private final WgsGrid wgsGrid = new WgsGrid(Settings.getInstance().wgsGrid, this); public PreviewMap() { super(MapSourcesManager.getInstance().getDefaultMapSource(), 5); setEnabled(false); defaultMapController = new DefaultMapController(this); mapMarkersVisible = false; setZoomContolsVisible(false); mapKeyboardController = new MapKeyboardController(this, true); setMapSelectionController(new RectangleSelectionMapController(this)); } public void setDisplayPositionByLatLon(EastNorthCoordinate c, int zoom) { setDisplayPositionByLatLon(new Point(getWidth() / 2, getHeight() / 2), c.lat, c.lon, zoom); } /** * Updates the current position in {@link Settings} to the current view */ public void settingsSave() { Settings settings = Settings.getInstance(); settings.mapviewZoom = getZoom(); settings.mapviewCenterCoordinate = getCenterCoordinate(); settings.mapviewGridZoom = gridZoom; settings.mapviewMapSource = mapSource.getName(); settings.mapviewSelectionMin = iSelectionMin; settings.mapviewSelectionMax = iSelectionMax; } /** * Sets the current view by the current values from {@link Settings} */ public void settingsLoad() { Settings settings = Settings.getInstance(); MapSource mapSource = MapSourcesManager.getInstance().getSourceByName(settings.mapviewMapSource); if (mapSource != null) setMapSource(mapSource); EastNorthCoordinate c = settings.mapviewCenterCoordinate; gridZoom = settings.mapviewGridZoom; setDisplayPositionByLatLon(c, settings.mapviewZoom); setSelectionByTileCoordinate(MAX_ZOOM, settings.mapviewSelectionMin, settings.mapviewSelectionMax, true); } @Override public void setMapSource(MapSource newMapSource) { if (newMapSource.equals(mapSource)) return; log.trace("Preview map source changed from " + mapSource + " to " + newMapSource); super.setMapSource(newMapSource); if (mapEventListeners == null) return; for (MapEventListener listener : mapEventListeners) listener.mapSourceChanged(mapSource); } protected void zoomChanged(int oldZoom) { log.trace("Preview map zoom changed from " + oldZoom + " to " + zoom); if (mapEventListeners != null) for (MapEventListener listener : mapEventListeners) listener.zoomChanged(zoom); updateGridValues(); } public void setGridZoom(int gridZoom) { if (gridZoom == this.gridZoom) return; this.gridZoom = gridZoom; updateGridValues(); applyGridOnSelection(); updateMapSelection(); repaint(); } public int getGridZoom() { return gridZoom; } /** * Updates the gridSize and the gridTile. This method has to called if * mapSource or zoom as been changed. */ protected void updateGridValues() { if (gridZoom < 0) return; int zoomToGridZoom = zoom - gridZoom; int tileSize = mapSource.getMapSpace().getTileSize(); if (zoomToGridZoom > 0) { gridSize = tileSize << zoomToGridZoom; gridTile = null; } else { gridSize = tileSize >> (-zoomToGridZoom); BufferedImage newGridTile = null; if (gridSize > 2) { newGridTile = new BufferedImage(tileSize, tileSize, BufferedImage.TYPE_INT_ARGB); Graphics2D g = newGridTile.createGraphics(); int alpha = 5 + (6 + zoomToGridZoom) * 16; alpha = Math.max(0, alpha); alpha = Math.min(130, alpha); g.setColor(new Color(200, 20, 20, alpha)); for (int x = 0; x < tileSize; x += gridSize) g.drawLine(x, 0, x, 255); for (int y = 0; y < tileSize; y += gridSize) g.drawLine(0, y, 255, y); } gridTile = newGridTile; } } @Override protected void paintComponent(Graphics graphics) { if (!isEnabled()) { graphics.setFont(LOADING_FONT); graphics.drawString(I18nUtils.localizedStringForKey("map_loading_wait"), 100, 100); return; } if (mapSource == null) return; Graphics2D g = (Graphics2D) graphics; super.paintComponent(g); Point tlc = getTopLeftCoordinate(); if (gridZoom >= 0) { // Only paint grid if it is enabled (gridZoom not -1) int max = (256 << zoom); int w = Math.min(getWidth(), max - tlc.x); int h = Math.min(getHeight(), max - tlc.y); g.setColor(GRID_COLOR); // g.setStroke(new BasicStroke(4.0f)); if (gridSize > 1) { int tilesize = mapSource.getMapSpace().getTileSize(); if (gridSize >= tilesize) { int off_x = tlc.x < 0 ? -tlc.x : -(tlc.x % gridSize); int off_y = tlc.y < 0 ? -tlc.y : -(tlc.y % gridSize); for (int x = off_x; x <= w; x += gridSize) { g.drawLine(x, off_y, x, h); } for (int y = off_y; y <= h; y += gridSize) { g.drawLine(off_x, y, w, y); } } else { int off_x = (tlc.x < 0) ? tlc.x : tlc.x % tilesize; int off_y = (tlc.y < 0) ? tlc.y : tlc.y % tilesize; for (int x = -off_x; x < w; x += 256) { for (int y = -off_y; y < h; y += 256) { g.drawImage(gridTile, x, y, null); } } } } } if (gridSelectionStart != null && gridSelectionEnd != null) { // Draw the selection rectangle widened by the current grid int zoomDiff = MAX_ZOOM - zoom; int x_min = (gridSelectionStart.x >> zoomDiff) - tlc.x; int y_min = (gridSelectionStart.y >> zoomDiff) - tlc.y; int x_max = (gridSelectionEnd.x >> zoomDiff) - tlc.x; int y_max = (gridSelectionEnd.y >> zoomDiff) - tlc.y; int w = x_max - x_min + 1; int h = y_max - y_min + 1; g.setColor(SEL_COLOR); g.fillRect(x_min, y_min, w, h); } if (iSelectionMin != null && iSelectionMax != null) { // Draw the selection rectangle exactly as it has been specified by the user int zoomDiff = MAX_ZOOM - zoom; int x_min = (iSelectionMin.x >> zoomDiff) - tlc.x; int y_min = (iSelectionMin.y >> zoomDiff) - tlc.y; int x_max = (iSelectionMax.x >> zoomDiff) - tlc.x; int y_max = (iSelectionMax.y >> zoomDiff) - tlc.y; int w = x_max - x_min + 1; int h = y_max - y_min + 1; g.setColor(GRID_COLOR); g.drawRect(x_min, y_min, w, h); } if (mapSource instanceof MapSourceTextAttribution) { MapSourceTextAttribution ta = (MapSourceTextAttribution) mapSource; String attributionText = ta.getAttributionText(); if (attributionText != null) { Rectangle2D stringBounds = g.getFontMetrics().getStringBounds(attributionText, g); int text_x = getWidth() - 10 - (int) stringBounds.getWidth(); int text_y = getHeight() - 1 - (int) stringBounds.getHeight(); g.setColor(Color.black); g.drawString(attributionText, text_x + 1, text_y + 1); g.setColor(Color.white); g.drawString(attributionText, text_x, text_y); } } if (Settings.getInstance().wgsGrid.enabled) { wgsGrid.paintWgsGrid(g, mapSource.getMapSpace(), tlc, zoom); } ScaleBar.paintScaleBar(this, g, mapSource.getMapSpace(), tlc, zoom); } public Bookmark getPositionBookmark() { return new Bookmark(mapSource, zoom, center.x, center.y); } public void gotoPositionBookmark(Bookmark bookmark) { setMapSource(bookmark.getMapSource()); setDisplayPositionByLatLon(bookmark, bookmark.getZoom()); setZoom(bookmark.getZoom()); } /** * @return Coordinate of the point in the center of the currently displayed map region */ public EastNorthCoordinate getCenterCoordinate() { MapSpace mapSpace = mapSource.getMapSpace(); double lon = mapSpace.cXToLon(center.x, zoom); double lat = mapSpace.cYToLat(center.y, zoom); return new EastNorthCoordinate(lat, lon); } /** * @return Coordinate of the top left corner visible regarding the current map source (pixel) */ public Point getTopLeftCoordinate() { return new Point(center.x - (getWidth() / 2), center.y - (getHeight() / 2)); } public void zoomTo(MapSelection ms) { if (!ms.isAreaSelected()) return; log.trace("Setting selection to: " + ms); Point max = ms.getBottomRightPixelCoordinate(MAX_ZOOM); Point min = ms.getTopLeftPixelCoordinate(MAX_ZOOM); setDisplayToFitPixelCoordinates(max.x, max.y, min.x, min.y); } /** * Zooms to the specified {@link MapSelection} and sets the selection to it; * * @param ms * @param notifyListeners */ public void setSelectionAndZoomTo(MapSelection ms, boolean notifyListeners) { log.trace("Setting selection to: " + ms); Point max = ms.getBottomRightPixelCoordinate(MAX_ZOOM); Point min = ms.getTopLeftPixelCoordinate(MAX_ZOOM); setDisplayToFitPixelCoordinates(max.x, max.y, min.x, min.y); Point pStart = ms.getTopLeftPixelCoordinate(zoom); Point pEnd = ms.getBottomRightPixelCoordinate(zoom); setSelectionByTileCoordinate(pStart, pEnd, notifyListeners); } /** * * @param pStart * x/y tile coordinate of the top left tile regarding the current zoom level * @param pEnd * x/y tile coordinate of the bottom right tile regarding the current zoom level * @param notifyListeners */ public void setSelectionByTileCoordinate(Point pStart, Point pEnd, boolean notifyListeners) { setSelectionByTileCoordinate(zoom, pStart, pEnd, notifyListeners); } /** * Sets the rectangular selection to the absolute tile coordinates pStart and pEnd * regarding the zoom-level cZoom. * * @param cZoom * @param pStart * @param pEnd * @param notifyListeners */ public void setSelectionByTileCoordinate(int cZoom, Point pStart, Point pEnd, boolean notifyListeners) { if (pStart == null || pEnd == null) { iSelectionMin = null; iSelectionMax = null; gridSelectionStart = null; gridSelectionEnd = null; return; } Point pNewStart = new Point(); Point pNewEnd = new Point(); int mapMaxCoordinate = mapSource.getMapSpace().getMaxPixels(cZoom) - 1; // Sort x/y coordinate of points so that pNewStart < pnewEnd and limit selection to map size pNewStart.x = Math.max(0, Math.min(mapMaxCoordinate, Math.min(pStart.x, pEnd.x))); pNewStart.y = Math.max(0, Math.min(mapMaxCoordinate, Math.min(pStart.y, pEnd.y))); pNewEnd.x = Math.max(0, Math.min(mapMaxCoordinate, Math.max(pStart.x, pEnd.x))); pNewEnd.y = Math.max(0, Math.min(mapMaxCoordinate, Math.max(pStart.y, pEnd.y))); int zoomDiff = MAX_ZOOM - cZoom; pNewEnd.x <<= zoomDiff; pNewEnd.y <<= zoomDiff; pNewStart.x <<= zoomDiff; pNewStart.y <<= zoomDiff; iSelectionMin = pNewStart; iSelectionMax = pNewEnd; gridSelectionStart = null; gridSelectionEnd = null; updateGridValues(); applyGridOnSelection(); if (notifyListeners) updateMapSelection(); repaint(); } protected void applyGridOnSelection() { if (gridZoom < 0) { gridSelectionStart = iSelectionMin; gridSelectionEnd = iSelectionMax; return; } if (iSelectionMin == null || iSelectionMax == null) return; int gridZoomDiff = MAX_ZOOM - gridZoom; int gridFactor = mapSource.getMapSpace().getTileSize() << gridZoomDiff; Point pNewStart = new Point(iSelectionMin); Point pNewEnd = new Point(iSelectionMax); // Snap to the current grid pNewStart.x = MyMath.roundDownToNearest(pNewStart.x, gridFactor); pNewStart.y = MyMath.roundDownToNearest(pNewStart.y, gridFactor); pNewEnd.x = MyMath.roundUpToNearest(pNewEnd.x, gridFactor) - 1; pNewEnd.y = MyMath.roundUpToNearest(pNewEnd.y, gridFactor) - 1; gridSelectionStart = pNewStart; gridSelectionEnd = pNewEnd; } /** * Notifies all registered {@link MapEventListener} of a * {@link MapEventListener#selectionChanged(MercatorPixelCoordinate, MercatorPixelCoordinate)} event. */ public void updateMapSelection() { int x_min, y_min, x_max, y_max; if (gridZoom >= 0) { if (gridSelectionStart == null || gridSelectionEnd == null) return; x_min = gridSelectionStart.x; y_min = gridSelectionStart.y; x_max = gridSelectionEnd.x; y_max = gridSelectionEnd.y; } else { if (iSelectionMin == null || iSelectionMax == null) return; x_min = iSelectionMin.x; y_min = iSelectionMin.y; x_max = iSelectionMax.x; y_max = iSelectionMax.y; } MercatorPixelCoordinate min = new MercatorPixelCoordinate(mapSource.getMapSpace(), x_min, y_min, MAX_ZOOM); MercatorPixelCoordinate max = new MercatorPixelCoordinate(mapSource.getMapSpace(), x_max, y_max, MAX_ZOOM); // log.debug("sel min: [" + min + "]"); // log.debug("sel max: [" + max + "]"); for (MapEventListener listener : mapEventListeners) listener.selectionChanged(max, min); } public void addMapEventListener(MapEventListener l) { mapEventListeners.add(l); } public void selectPreviousMap() { for (MapEventListener listener : mapEventListeners) { listener.selectPreviousMapSource(); } } public void selectNextMap() { for (MapEventListener listener : mapEventListeners) { listener.selectNextMapSource(); } } /** * Clears the in-memory tile cache and performs a repaint which causes a reload of all displayed tiles (from disk or * if not present from the map source via network). */ public void refreshMap() { tileCache.clear(); repaint(); } public JMapController getMapKeyboardController() { return mapKeyboardController; } /** * @return Currently active mapSelectionController */ public JMapController getMapSelectionController() { return mapSelectionController; } /** * Sets a new mapSelectionController. Previous controller are disabled and removed. * * @param mapSelectionController */ public void setMapSelectionController(JMapController mapSelectionController) { if (this.mapSelectionController != null) this.mapSelectionController.disable(); this.mapSelectionController = mapSelectionController; mapSelectionController.enable(); for (MapEventListener listener : mapEventListeners) { listener.mapSelectionControllerChanged(mapSelectionController); } repaint(); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/JobDispatcher.java0000644000175000017500000000610612122526604030064 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.mapview; //License: GPL. Copyright 2008 by Jan Peter Stotz import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import mobac.program.tilestore.berkeleydb.DelayedInterruptThread; import org.apache.log4j.Logger; public class JobDispatcher implements ThreadFactory, RejectedExecutionHandler { private static final Logger log = Logger.getLogger(JobDispatcher.class); private static final JobDispatcher INSTANCE = new JobDispatcher(); private static final int WORKER_THREAD_MAX_COUNT = 5; /** * Specifies the time span in seconds that a worker thread waits for new jobs to perform. If the time span has * elapsed the worker thread terminates itself. Only the first worker thread works differently, it ignores the * timeout and will never terminate itself. */ private static final int WORKER_THREAD_TIMEOUT = 30; /** * @return the singleton instance of the {@link JobDispatcher} */ public static JobDispatcher getInstance() { return INSTANCE; } private int WORKER_THREAD_ID = 1; private final BlockingQueue jobQueue; private final ThreadPoolExecutor executor; /** * Removes all jobs from the queue that are currently not being processed. */ public void cancelOutstandingJobs() { jobQueue.clear(); } private JobDispatcher() { jobQueue = new LinkedBlockingQueue(); executor = new ThreadPoolExecutor(WORKER_THREAD_MAX_COUNT, WORKER_THREAD_MAX_COUNT, WORKER_THREAD_TIMEOUT, TimeUnit.SECONDS, jobQueue, this, this); executor.allowCoreThreadTimeOut(true); } public void addJob(Runnable job) { executor.execute(job); } public Thread newThread(Runnable r) { int id; synchronized (this) { id = WORKER_THREAD_ID++; } log.trace("New map preview worker thread created with id=" + id); return new DelayedInterruptThread(r, "Map preview thread " + id); } public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { log.error("Map preview job rejected: " + r); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/Tile.java0000644000175000017500000001644512127544350026252 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.mapview; //License: GPL. Copyright 2008 by Jan Peter Stotz import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import javax.imageio.ImageIO; import mobac.program.interfaces.MapSource; import mobac.utilities.Utilities; /** * Holds one map tile. Additionally the code for loading the tile image and painting it is also included in this class. * * @author Jan Peter Stotz */ public class Tile { /** * Hourglass image that is displayed until a map tile has been loaded */ public static BufferedImage LOADING_IMAGE; public static BufferedImage ERROR_IMAGE; static { try { LOADING_IMAGE = ImageIO.read(Utilities.getResourceImageUrl("hourglass.png")); ERROR_IMAGE = ImageIO.read(Utilities.getResourceImageUrl("error.png")); } catch (Exception e1) { LOADING_IMAGE = null; ERROR_IMAGE = null; } } public enum TileState { TS_NEW, TS_LOADING, TS_LOADED, TS_ERROR }; protected MapSource mapSource; protected int xtile; protected int ytile; protected int zoom; protected BufferedImage image; protected String key; protected TileState tileState = TileState.TS_NEW; /** * Creates a tile with empty image. * * @param mapSource * @param xtile * @param ytile * @param zoom */ public Tile(MapSource mapSource, int xtile, int ytile, int zoom) { super(); this.mapSource = mapSource; this.xtile = xtile; this.ytile = ytile; this.zoom = zoom; this.image = LOADING_IMAGE; this.key = getTileKey(mapSource, xtile, ytile, zoom); } public Tile(MapSource source, int xtile, int ytile, int zoom, BufferedImage image) { this(source, xtile, ytile, zoom); this.image = image; } /** * Tries to get tiles of a lower or higher zoom level (one or two level difference) from cache and use it as a * placeholder until the tile has been loaded. */ public void loadPlaceholderFromCache(MemoryTileCache cache) { int tileSize = mapSource.getMapSpace().getTileSize(); BufferedImage tmpImage = new BufferedImage(tileSize, tileSize, BufferedImage.TYPE_INT_RGB); Graphics2D g = (Graphics2D) tmpImage.getGraphics(); // g.drawImage(image, 0, 0, null); for (int zoomDiff = 1; zoomDiff < 5; zoomDiff++) { // first we check if there are already the 2^x tiles // of a higher detail level int zoom_high = zoom + zoomDiff; if (zoomDiff < 3 && zoom_high <= JMapViewer.MAX_ZOOM) { int factor = 1 << zoomDiff; int xtile_high = xtile << zoomDiff; int ytile_high = ytile << zoomDiff; double scale = 1.0 / factor; g.setTransform(AffineTransform.getScaleInstance(scale, scale)); int paintedTileCount = 0; for (int x = 0; x < factor; x++) { for (int y = 0; y < factor; y++) { Tile tile = cache.getTile(mapSource, xtile_high + x, ytile_high + y, zoom_high); if (tile != null && tile.tileState == TileState.TS_LOADED) { paintedTileCount++; tile.paint(g, x * tileSize, y * tileSize); } } } if (paintedTileCount == factor * factor) { image = tmpImage; return; } } int zoom_low = zoom - zoomDiff; if (zoom_low >= JMapViewer.MIN_ZOOM) { int xtile_low = xtile >> zoomDiff; int ytile_low = ytile >> zoomDiff; int factor = (1 << zoomDiff); double scale = factor; AffineTransform at = new AffineTransform(); int translate_x = (xtile % factor) * tileSize; int translate_y = (ytile % factor) * tileSize; at.setTransform(scale, 0, 0, scale, -translate_x, -translate_y); g.setTransform(at); Tile tile = cache.getTile(mapSource, xtile_low, ytile_low, zoom_low); if (tile != null && tile.tileState == TileState.TS_LOADED) { tile.paint(g, 0, 0); image = tmpImage; return; } } } } public MapSource getSource() { return mapSource; } /** * @return tile number on the x axis of this tile */ public int getXtile() { return xtile; } /** * @return tile number on the y axis of this tile */ public int getYtile() { return ytile; } /** * @return zoom level of this tile */ public int getZoom() { return zoom; } public BufferedImage getImage() { return image; } public void setImage(BufferedImage image) { this.image = image; } public void setErrorImage() { image = ERROR_IMAGE; tileState = TileState.TS_ERROR; } public void loadImage(InputStream input) throws IOException { image = ImageIO.read(input); } public void loadImage(byte[] data) throws IOException { loadImage(new ByteArrayInputStream(data)); } /** * @return key that identifies a tile */ public String getKey() { return key; } public boolean isErrorTile() { return (ERROR_IMAGE.equals(image)); } public TileState getTileState() { return tileState; } public void setTileState(TileState tileState) { this.tileState = tileState; } /** * Paints the tile-image on the {@link Graphics} g at the position x/y. * * @param g * @param x * x-coordinate in g * @param y * y-coordinate in g */ public void paint(Graphics g, int x, int y) { if (image == null) return; int tileSize = mapSource.getMapSpace().getTileSize(); //Google Scale = 2, retina support g.drawImage(image, x, y, tileSize, tileSize, Color.WHITE, null); //g.drawImage(image, x, y, Color.WHITE); } public void paintTransparent(Graphics g, int x, int y) { if (image == null) return; int tileSize = mapSource.getMapSpace().getTileSize(); //Google Scale = 2, retina support g.drawImage(image, x, y, tileSize, tileSize, null); //g.drawImage(image, x, y, null); } @Override public String toString() { return "tile " + key; } @Override public boolean equals(Object obj) { if (!(obj instanceof Tile)) return false; Tile tile = (Tile) obj; return (xtile == tile.xtile) && (ytile == tile.ytile) && (zoom == tile.zoom); } @Override public int hashCode() { assert false : "hashCode not designed"; return -1; } public static String getTileKey(MapSource source, int xtile, int ytile, int zoom) { return zoom + "/" + xtile + "/" + ytile + "@" + source.getName(); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/WgsGrid.java0000644000175000017500000002210312127544350026707 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.mapview; import java.awt.BasicStroke; import java.awt.Color; import java.awt.FontMetrics; import java.awt.Graphics2D; import java.awt.Point; import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.Stroke; import javax.swing.JComponent; import mobac.program.interfaces.MapSpace; import mobac.program.model.Coordinate; import mobac.program.model.SettingsWgsGrid; import mobac.utilities.I18nUtils; public class WgsGrid { public static enum WgsDensity { DEGREES_90(0), DEGREES_45(1), DEGREES_30(2), DEGREES_15(3), DEGREES_10(4), DEGREES_5(5), DEGREES_2(6), DEGREE_1( 7), MINUTES_30(8), MINUTES_20(9), MINUTES_10(10), MINUTES_5(11), MINUTES_2(12), MINUTE_1(13), SECONDS_30( 15), SECONDS_20(15), SECONDS_10(16), SECONDS_5(17), SECONDS_2(18), SECOND_1(19); public final int iStep, minZoom; public final boolean compressDegree, compressMinute, displayMinute, displaySecond; //private final String string; private WgsDensity(final int minZoom) { this.minZoom = minZoom; String[] split = name().split("_"); int value = Integer.parseInt(split[1]); if (split[0].startsWith("D")) { iStep = value * Coordinate.DEGREE; displayMinute = displaySecond = false; compressDegree = compressMinute = false; } else if (split[0].startsWith("M")) { iStep = value * Coordinate.MINUTE; compressDegree = true/* value <= 15 */; displayMinute = true; displaySecond = compressMinute = false; } else { iStep = value * Coordinate.SECOND; compressDegree = displayMinute = displaySecond = true; compressMinute = true/* value <= 15 */; } } public String toString() { String[] split = name().split("_"); String unitKey = "map_ctrl_wgs_grid_density_"+ split[0].toLowerCase(); return I18nUtils.localizedStringForKey("map_ctrl_wgs_grid_density_prefix") + " " + split[1] + " " + I18nUtils.localizedStringForKey(unitKey); } } public static enum Placement { BOTTOM_RIGHT, BOTTOM_LEFT, TOP_RIGHT, TOP_LEFT } private static final WgsDensity DENSITIES[] = WgsDensity.values(); private static final Stroke BASIC_STROKE = new BasicStroke(1f); private static final int LABEL_OFFSET = 2; private final StringBuilder stringBuilder = new StringBuilder(16); private final Rectangle viewport = new Rectangle(); public final SettingsWgsGrid s; private final JComponent c; private Placement placement = Placement.BOTTOM_RIGHT; private BasicStroke stroke; private int lastDegree, lastMinute; public WgsGrid(SettingsWgsGrid s, JComponent c) { this.s = s; this.c = c; } public void paintWgsGrid(Graphics2D g, MapSpace ms, Point tlc, int zoom) { if (!s.enabled) { return; } // Check density WgsDensity density = s.density; while (zoom < density.minZoom) { int index = density.ordinal(); if (--index <= 0) { return; } density = DENSITIES[index]; } final int maxPixels = ms.getMaxPixels(zoom); // Check viewport viewport.width = c.getWidth(); viewport.height = c.getHeight(); if (tlc.x > maxPixels || tlc.y > maxPixels || tlc.x + viewport.width < 0 || tlc.y + viewport.width < 0) { return; } viewport.x = c.getX(); viewport.y = c.getY(); // Translate according to mapSpace viewport.translate(tlc.x, tlc.y); g = (Graphics2D) g.create(); g.translate(-tlc.x, -tlc.y); // Calculate viewport coordinates final int x1 = Math.max(tlc.x, 0); final int y1 = Math.max(tlc.y, 0); final int x2 = Math.min(tlc.x + viewport.width, maxPixels); final int y2 = Math.min(tlc.y + viewport.height, maxPixels); // Calculate line coordinates final int hLineX1 = x1 + 1; final int hLineX2 = x2 - 1; final int vLineY1 = y1 + 1; final int vLineY2 = y2 - 1; // Calculate line indexes final int vMin = Coordinate.doubleToInt(ms.cXToLon(x1, zoom)) / density.iStep; final int vMax = Coordinate.doubleToInt(ms.cXToLon(x2, zoom)) / density.iStep; final int hMin = Coordinate.doubleToInt(ms.cYToLat(y2, zoom)) / density.iStep; final int hMax = Coordinate.doubleToInt(ms.cYToLat(y1, zoom)) / density.iStep; g.setBackground(Color.WHITE); g.setColor(s.color); g.setStroke(checkAndGetStroke()); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // Paint vertical lines for (int i = vMin; i <= vMax; i++) { int iLon = i * density.iStep; int x = ms.cLonToX(Coordinate.intToDouble(iLon), zoom); if (x > x1 && x < x2) { g.drawLine(x, vLineY1, x, vLineY2); } } // Paint horizontal lines for (int i = hMin; i <= hMax; i++) { int iLat = i * density.iStep; int y = ms.cLatToY(Coordinate.intToDouble(iLat), zoom); if (y > y1 && y < y2) { g.drawLine(hLineX1, y, hLineX2, y); } } // Set up font metrics g.setStroke(BASIC_STROKE); g.setFont(s.font); final FontMetrics fontMetrics = g.getFontMetrics(); final int fontDescent = fontMetrics.getDescent(); final int fontHeight = fontMetrics.getHeight(); resetLabelCompression(); // Shared Y coordinates for vertical labels int labelRectX; int labelRectY = y2 - LABEL_OFFSET - fontHeight; int labelY = y2 - LABEL_OFFSET - fontDescent; int labelX; // Paint vertical labels for (int i = vMin; i <= vMax; i++) { // Calculate coordinates int iLon = i * density.iStep; int x = ms.cLonToX(Coordinate.intToDouble(iLon), zoom); // Prepare label String label = getLabel(iLon, density); int stringWidth = fontMetrics.stringWidth(label); labelRectX = labelX = x - stringWidth / 2; // Paint label if (viewport.contains(labelRectX, labelRectY, stringWidth, fontHeight)) { g.clearRect(labelRectX, labelRectY, stringWidth, fontHeight); g.drawRect(labelRectX, labelRectY, stringWidth, fontHeight); g.drawString(label, labelX, labelY); } else { resetLabelCompression(); } } resetLabelCompression(); viewport.height -= fontHeight + LABEL_OFFSET; labelX = labelRectX = x1 + LABEL_OFFSET; // Paint horizontal labels for (int i = hMin; i <= hMax; i++) { int iLat = i * density.iStep; int y = ms.cLatToY(Coordinate.intToDouble(iLat), zoom); // Prepare label String label = getLabel(iLat, density); final int stringWidth = fontMetrics.stringWidth(label); if (placement == Placement.BOTTOM_RIGHT || placement == Placement.TOP_RIGHT) { labelX = labelRectX = x2 - LABEL_OFFSET - stringWidth; } labelRectY = y - fontHeight / 2; labelY = labelRectY + fontHeight - fontDescent; // Paint label if (viewport.contains(labelRectX, labelRectY, stringWidth, fontHeight)) { g.clearRect(labelRectX, labelRectY, stringWidth, fontHeight); g.drawRect(labelRectX, labelRectY, stringWidth, fontHeight); g.drawString(label, labelX, labelY); } else { resetLabelCompression(); } } g.dispose(); } public void setPosition(Placement placement) { this.placement = placement != null ? placement : Placement.BOTTOM_RIGHT; } private Stroke checkAndGetStroke() { if (stroke == null || stroke.getLineWidth() != s.width) { stroke = new BasicStroke(s.width); } return stroke; } private void resetLabelCompression() { lastDegree = Integer.MAX_VALUE; lastMinute = Integer.MAX_VALUE; } private String getLabel(int coord, WgsDensity density) { coord = Math.abs(coord); int degree = Coordinate.getDegree(coord); int minute = Coordinate.getMinute(coord); int second = Coordinate.getSecond(coord); stringBuilder.setLength(0); stringBuilder.append(" "); if (!s.compressLabels || lastDegree != degree || !density.compressDegree) { stringBuilder.append(degree); stringBuilder.append('\u00B0'); } if (density.displayMinute && (!s.compressLabels || lastMinute != minute || !density.compressMinute)) { if (minute < 10) { stringBuilder.append('0'); } stringBuilder.append(minute); stringBuilder.append('\''); } if (density.displaySecond) { if (second < 10) { stringBuilder.append('0'); } stringBuilder.append(second); stringBuilder.append('\"'); } stringBuilder.append(" "); lastDegree = degree; lastMinute = minute; return stringBuilder.toString(); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/MemoryTileCache.java0000644000175000017500000001730012122526604030353 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.mapview; //License: GPL. Copyright 2008 by Jan Peter Stotz import java.lang.management.ManagementFactory; import java.lang.management.MemoryMXBean; import java.lang.management.MemoryNotificationInfo; import java.lang.management.MemoryPoolMXBean; import java.lang.management.MemoryUsage; import java.util.Hashtable; import javax.management.Notification; import javax.management.NotificationBroadcaster; import javax.management.NotificationListener; import mobac.gui.mapview.Tile.TileState; import mobac.program.interfaces.MapSource; import org.apache.log4j.Logger; /** * {@link TileImageCache} implementation that stores all {@link Tile} objects in memory up to a certain limit ( * {@link #getCacheSize()}). If the limit is exceeded the least recently used {@link Tile} objects will be deleted. * * @author Jan Peter Stotz * @author r_x */ public class MemoryTileCache implements NotificationListener { protected final Logger log; /** * Default cache size */ protected int cacheSize = 200; protected Hashtable hashtable; /** * List of all tiles in their last recently used order */ protected CacheLinkedListElement lruTiles; public MemoryTileCache() { log = Logger.getLogger(this.getClass()); hashtable = new Hashtable(cacheSize); lruTiles = new CacheLinkedListElement(); cacheSize = 500; MemoryMXBean mbean = ManagementFactory.getMemoryMXBean(); NotificationBroadcaster emitter = (NotificationBroadcaster) mbean; emitter.addNotificationListener(this, null, null); // Set-up each memory pool to notify if the free memory falls below 10% for (MemoryPoolMXBean memPool : ManagementFactory.getMemoryPoolMXBeans()) { if (memPool.isUsageThresholdSupported()) { MemoryUsage memUsage = memPool.getUsage(); memPool.setUsageThreshold((long) (memUsage.getMax() * 0.95)); } } } /** * In case we are running out of memory we free half of the cached down to a minimum of 25 cached tiles. */ public void handleNotification(Notification notification, Object handback) { log.trace("Memory notification: " + notification.toString()); if (!MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED.equals(notification.getType())) return; synchronized (lruTiles) { int count_half = lruTiles.getElementCount() / 2; count_half = Math.max(25, count_half); if (lruTiles.getElementCount() <= count_half) return; log.warn("memory low - freeing cached tiles: " + lruTiles.getElementCount() + " -> " + count_half); try { while (lruTiles.getElementCount() > count_half) { removeEntry(lruTiles.getLastElement()); } } catch (Exception e) { log.error("", e); } } } public void addTile(Tile tile) { CacheEntry entry = createCacheEntry(tile); hashtable.put(tile.getKey(), entry); lruTiles.addFirst(entry); if (hashtable.size() > cacheSize) removeOldEntries(); } public Tile getTile(MapSource source, int x, int y, int z) { CacheEntry entry = hashtable.get(Tile.getTileKey(source, x, y, z)); if (entry == null) return null; // We don't care about placeholder tiles and hourglass image tiles, the // important tiles are the loaded ones if (entry.tile.getTileState() == TileState.TS_LOADED) lruTiles.moveElementToFirstPos(entry); return entry.tile; } /** * Removes the least recently used tiles */ protected void removeOldEntries() { synchronized (lruTiles) { try { while (lruTiles.getElementCount() > cacheSize) { removeEntry(lruTiles.getLastElement()); } } catch (Exception e) { log.warn("", e); } } } protected void removeEntry(CacheEntry entry) { hashtable.remove(entry.tile.getKey()); lruTiles.removeEntry(entry); } protected CacheEntry createCacheEntry(Tile tile) { return new CacheEntry(tile); } /** * Clears the cache deleting all tiles from memory */ public void clear() { synchronized (lruTiles) { hashtable.clear(); lruTiles.clear(); } } public int getTileCount() { return hashtable.size(); } public int getCacheSize() { return cacheSize; } /** * Changes the maximum number of {@link Tile} objects that this cache holds. * * @param cacheSize * new maximum number of tiles */ public void setCacheSize(int cacheSize) { this.cacheSize = cacheSize; if (hashtable.size() > cacheSize) removeOldEntries(); } /** * Linked list element holding the {@link Tile} and links to the {@link #next} and {@link #prev} item in the list. */ protected static class CacheEntry { Tile tile; CacheEntry next; CacheEntry prev; protected CacheEntry(Tile tile) { this.tile = tile; } public Tile getTile() { return tile; } public CacheEntry getNext() { return next; } public CacheEntry getPrev() { return prev; } } /** * Special implementation of a double linked list for {@link CacheEntry} elements. It supports element removal in * constant time - in difference to the Java implementation which needs O(n). * * @author Jan Peter Stotz */ protected static class CacheLinkedListElement { protected CacheEntry firstElement = null; protected CacheEntry lastElement; protected int elementCount; public CacheLinkedListElement() { clear(); } public synchronized void clear() { elementCount = 0; firstElement = null; lastElement = null; } /** * Add the element to the head of the list. * * @param new element to be added */ public synchronized void addFirst(CacheEntry element) { if (elementCount == 0) { firstElement = element; lastElement = element; element.prev = null; element.next = null; } else { element.next = firstElement; firstElement.prev = element; element.prev = null; firstElement = element; } elementCount++; } /** * Removes the specified elemntent form the list. * * @param element * to be removed */ public synchronized void removeEntry(CacheEntry element) { if (element.next != null) { element.next.prev = element.prev; } if (element.prev != null) { element.prev.next = element.next; } if (element == firstElement) firstElement = element.next; if (element == lastElement) lastElement = element.prev; element.next = null; element.prev = null; elementCount--; } public synchronized void moveElementToFirstPos(CacheEntry entry) { if (firstElement == entry) return; removeEntry(entry); addFirst(entry); } public int getElementCount() { return elementCount; } public CacheEntry getLastElement() { return lastElement; } public CacheEntry getFirstElement() { return firstElement; } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/JMapViewer.java0000644000175000017500000004013612122526604027355 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.mapview; //License: GPL. Copyright 2008 by Jan Peter Stotz import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Insets; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.geom.Point2D; import java.util.ConcurrentModificationException; import java.util.LinkedList; import java.util.List; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JPanel; import javax.swing.JSlider; import javax.swing.SwingUtilities; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import mobac.gui.mapview.interfaces.MapLayer; import mobac.gui.mapview.interfaces.MapTileLayer; import mobac.gui.mapview.interfaces.TileLoaderListener; import mobac.gui.mapview.layer.DefaultMapTileLayer; import mobac.gui.mapview.layer.MapGridLayer; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSpace; import mobac.utilities.Utilities; import org.apache.log4j.Logger; /** * * Provides a simple panel that displays pre-rendered map tiles loaded from the OpenStreetMap project. * * @author Jan Peter Stotz * */ public class JMapViewer extends JPanel implements TileLoaderListener { private static final long serialVersionUID = 1L; private static Logger log = Logger.getLogger(JMapViewer.class); /** * Vectors for clock-wise tile painting */ protected static final Point[] move = { new Point(1, 0), new Point(0, 1), new Point(-1, 0), new Point(0, -1) }; public static final int MAX_ZOOM = 22; public static final int MIN_ZOOM = 0; protected TileLoader tileLoader; protected MemoryTileCache tileCache; protected MapSource mapSource; protected boolean usePlaceHolderTiles = true; protected boolean mapMarkersVisible; protected MapGridLayer mapGridLayer = null; protected List mapTileLayers; public List mapLayers; /** * x- and y-position of the center of this map-panel on the world map denoted in screen pixel regarding the current * zoom level. */ protected Point center = new Point(); /** * Current zoom level */ protected int zoom; protected JSlider zoomSlider = new JSlider(0, 0); protected JButton zoomInButton; protected JButton zoomOutButton; protected JobDispatcher jobDispatcher; public JMapViewer(MapSource defaultMapSource, int downloadThreadCount) { super(); mapTileLayers = new LinkedList(); mapLayers = new LinkedList(); tileLoader = new TileLoader(this); tileCache = new MemoryTileCache(); jobDispatcher = JobDispatcher.getInstance(); mapMarkersVisible = true; setLayout(null); setMapSource(defaultMapSource); initializeZoomSlider(); setMinimumSize(new Dimension(256, 256)); setPreferredSize(new Dimension(400, 400)); setDisplayPositionByLatLon(50.0, 9.0, 1); } protected void initializeZoomSlider() { zoomSlider.setOrientation(JSlider.VERTICAL); zoomSlider.setBounds(10, 10, 30, 150); zoomSlider.setOpaque(false); zoomSlider.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { setZoom(zoomSlider.getValue()); } }); add(zoomSlider); int size = 18; try { ImageIcon icon = Utilities.loadResourceImageIcon("plus.png"); zoomInButton = new JButton(icon); } catch (Exception e) { zoomInButton = new JButton("+"); zoomInButton.setFont(new Font("sansserif", Font.BOLD, 9)); zoomInButton.setMargin(new Insets(0, 0, 0, 0)); } zoomInButton.setBounds(4, 155, size, size); zoomInButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { zoomIn(); } }); add(zoomInButton); try { ImageIcon icon = Utilities.loadResourceImageIcon("minus.png"); zoomOutButton = new JButton(icon); } catch (Exception e) { zoomOutButton = new JButton("-"); zoomOutButton.setFont(new Font("sansserif", Font.BOLD, 9)); zoomOutButton.setMargin(new Insets(0, 0, 0, 0)); } zoomOutButton.setBounds(8 + size, 155, size, size); zoomOutButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { zoomOut(); } }); add(zoomOutButton); } /** * Changes the map pane so that it is centered on the specified coordinate at the given zoom level. * * @param lat * latitude of the specified coordinate * @param lon * longitude of the specified coordinate * @param zoom * {@link #MIN_ZOOM} <= zoom level <= {@link #MAX_ZOOM} */ public void setDisplayPositionByLatLon(double lat, double lon, int zoom) { setDisplayPositionByLatLon(new Point(getWidth() / 2, getHeight() / 2), lat, lon, zoom); } /** * Changes the map pane so that the specified coordinate at the given zoom level is displayed on the map at the * screen coordinate mapPoint. * * @param mapPoint * point on the map denoted in pixels where the coordinate should be set * @param lat * latitude of the specified coordinate * @param lon * longitude of the specified coordinate * @param zoom * {@link #MIN_ZOOM} <= zoom level <= {@link MapSource#getMaxZoom()} */ public void setDisplayPositionByLatLon(Point mapPoint, double lat, double lon, int zoom) { zoom = Math.max(Math.min(zoom, mapSource.getMaxZoom()), mapSource.getMinZoom()); MapSpace mapSpace = mapSource.getMapSpace(); int x = mapSpace.cLonToX(lon, zoom); int y = mapSpace.cLatToY(lat, zoom); setDisplayPosition(mapPoint, x, y, zoom); } public void setDisplayPosition(int x, int y, int zoom) { setDisplayPosition(new Point(getWidth() / 2, getHeight() / 2), x, y, zoom); } public void setDisplayPosition(Point mapPoint, int x, int y, int zoom) { if (zoom > mapSource.getMaxZoom() || zoom < MIN_ZOOM) return; // Get the plain tile number Point p = new Point(); p.x = x - mapPoint.x + getWidth() / 2; p.y = y - mapPoint.y + getHeight() / 2; center = p; setIgnoreRepaint(true); try { int oldZoom = this.zoom; this.zoom = zoom; if (oldZoom != zoom) zoomChanged(oldZoom); if (zoomSlider.getValue() != zoom) zoomSlider.setValue(zoom); } finally { setIgnoreRepaint(false); repaint(); } } /** * Sets the displayed map pane and zoom level so that the two points (x1/y1) and (x2/y2) visible. Please note that * the coordinates have to be specified regarding {@link #MAX_ZOOM}. * * @param x1 * @param y1 * @param x2 * @param y2 */ public void setDisplayToFitPixelCoordinates(int x1, int y1, int x2, int y2) { int mapZoomMax = mapSource.getMaxZoom(); int height = Math.max(0, getHeight()); int width = Math.max(0, getWidth()); int newZoom = MAX_ZOOM; int x = Math.abs(x1 - x2); int y = Math.abs(y1 - y2); while (x > width || y > height || newZoom > mapZoomMax) { newZoom--; x >>= 1; y >>= 1; } // Do not select a zoom level that is unsupported by the current map // source newZoom = Math.max(mapSource.getMinZoom(), Math.min(mapSource.getMaxZoom(), newZoom)); x = Math.min(x2, x1) + Math.abs(x1 - x2) / 2; y = Math.min(y2, y1) + Math.abs(y1 - y2) / 2; int z = 1 << (MAX_ZOOM - newZoom); x /= z; y /= z; setDisplayPosition(x, y, newZoom); } public Point2D.Double getPosition() { MapSpace mapSpace = mapSource.getMapSpace(); double lon = mapSpace.cXToLon(center.x, zoom); double lat = mapSpace.cYToLat(center.y, zoom); return new Point2D.Double(lat, lon); } public Point2D.Double getPosition(Point mapPoint) { MapSpace mapSpace = mapSource.getMapSpace(); int x = center.x + mapPoint.x - getWidth() / 2; int y = center.y + mapPoint.y - getHeight() / 2; double lon = mapSpace.cXToLon(x, zoom); double lat = mapSpace.cYToLat(y, zoom); return new Point2D.Double(lat, lon); } /** * Calculates the position on the map of a given coordinate * * @param lat * @param lon * @return point on the map or null if the point is not visible */ public Point getMapPosition(double lat, double lon) { MapSpace mapSpace = mapSource.getMapSpace(); int x = mapSpace.cLonToX(lon, zoom); int y = mapSpace.cLatToY(lat, zoom); x -= center.x - getWidth() / 2; y -= center.y - getHeight() / 2; if (x < 0 || y < 0 || x > getWidth() || y > getHeight()) return null; return new Point(x, y); } @Override protected void paintComponent(Graphics graphics) { Graphics2D g = (Graphics2D) graphics; // if (mapIsMoving) { // mapIsMoving = false; // Doesn't look very pretty but is much more faster // g.copyArea(0, 0, getWidth(), getHeight(), -mapMoveX, -mapMoveY); // return; // } super.paintComponent(g); int iMove = 0; int tileSize = mapSource.getMapSpace().getTileSize(); int tilex = center.x / tileSize; int tiley = center.y / tileSize; int off_x = (center.x % tileSize); int off_y = (center.y % tileSize); int w2 = getWidth() / 2; int h2 = getHeight() / 2; int topLeftX = center.x - w2; int topLeftY = center.y - h2; int posx = w2 - off_x; int posy = h2 - off_y; int diff_left = off_x; int diff_right = tileSize - off_x; int diff_top = off_y; int diff_bottom = tileSize - off_y; boolean start_left = diff_left < diff_right; boolean start_top = diff_top < diff_bottom; if (start_top) { if (start_left) iMove = 2; else iMove = 3; } else { if (start_left) iMove = 1; else iMove = 0; } // calculate the visibility borders int x_min = -tileSize; int y_min = -tileSize; int x_max = getWidth(); int y_max = getHeight(); // paint the tiles in a spiral, starting from center of the map boolean painted = (mapTileLayers.size() > 0); for (MapTileLayer l : mapTileLayers) { l.startPainting(mapSource); } int x = 0; while (painted) { painted = false; for (int i = 0; i < 4; i++) { if (i % 2 == 0) x++; for (int j = 0; j < x; j++) { if (x_min <= posx && posx <= x_max && y_min <= posy && posy <= y_max) { // tile is visible painted = true; for (MapTileLayer l : mapTileLayers) { l.paintTile(g, posx, posy, tilex, tiley, zoom); } } Point p = move[iMove]; posx += p.x * tileSize; posy += p.y * tileSize; tilex += p.x; tiley += p.y; } iMove = (iMove + 1) % move.length; } } int bottomRightX = topLeftX + getWidth(); int bottomRightY = topLeftY + getHeight(); try { for (MapLayer l : mapLayers) { l.paint(this, (Graphics2D) g, zoom, topLeftX, topLeftY, bottomRightX, bottomRightY); } } catch (ConcurrentModificationException e) { // This may happen when multiple GPX files are loaded at once and in the mean time the map view is // repainted. SwingUtilities.invokeLater(new Runnable() { public void run() { JMapViewer.this.repaint(); } }); } // outer border of the map int mapSize = tileSize << zoom; g.setColor(Color.BLACK); g.drawRect(w2 - center.x, h2 - center.y, mapSize, mapSize); // g.drawString("Tiles in cache: " + tileCache.getTileCount(), 50, 20); } /** * Moves the visible map pane. * * @param x * horizontal movement in pixel. * @param y * vertical movement in pixel */ public void moveMap(int x, int y) { center.x += x; center.y += y; repaint(); } /** * @return the current zoom level */ public int getZoom() { return zoom; } /** * Increases the current zoom level by one */ public void zoomIn() { setZoom(zoom + 1); } /** * Increases the current zoom level by one */ public void zoomIn(Point mapPoint) { setZoom(zoom + 1, mapPoint); } /** * Decreases the current zoom level by one */ public void zoomOut() { setZoom(zoom - 1); } /** * Decreases the current zoom level by one */ public void zoomOut(Point mapPoint) { setZoom(zoom - 1, mapPoint); } public void setZoom(int zoom, Point mapPoint) { if (zoom > mapSource.getMaxZoom() || zoom < mapSource.getMinZoom() || zoom == this.zoom) return; Point2D.Double zoomPos = getPosition(mapPoint); jobDispatcher.cancelOutstandingJobs(); // Clearing outstanding load // requests setDisplayPositionByLatLon(mapPoint, zoomPos.x, zoomPos.y, zoom); } public void setZoom(int zoom) { setZoom(zoom, new Point(getWidth() / 2, getHeight() / 2)); repaint(); } /** * Every time the zoom level changes this method is called. Override it in derived implementations for adapting zoom * dependent values. The new zoom level can be obtained via {@link #getZoom()}. * * @param oldZoom * the previous zoom level */ protected void zoomChanged(int oldZoom) { zoomSlider.setToolTipText("Zoom level " + zoom); zoomInButton.setToolTipText("Zoom to level " + (zoom + 1)); zoomOutButton.setToolTipText("Zoom to level " + (zoom - 1)); zoomOutButton.setEnabled(zoom > mapSource.getMinZoom()); zoomInButton.setEnabled(zoom < mapSource.getMaxZoom()); } public boolean isTileGridVisible() { return (mapGridLayer != null); } public void setTileGridVisible(boolean tileGridVisible) { if (isTileGridVisible() == tileGridVisible) return; if (tileGridVisible) { mapGridLayer = new MapGridLayer(); addMapTileLayers(mapGridLayer); } else { removeMapTileLayers(mapGridLayer); mapGridLayer = null; } repaint(); } public boolean getMapMarkersVisible() { return mapMarkersVisible; } public void setZoomContolsVisible(boolean visible) { zoomSlider.setVisible(visible); zoomInButton.setVisible(visible); zoomOutButton.setVisible(visible); } public boolean getZoomContolsVisible() { return zoomSlider.isVisible(); } public MemoryTileCache getTileImageCache() { return tileCache; } public TileLoader getTileLoader() { return tileLoader; } public MapSource getMapSource() { return mapSource; } public void setMapSource(MapSource mapSource) { if (mapSource.getMaxZoom() > MAX_ZOOM) throw new RuntimeException("Maximum zoom level too high"); if (mapSource.getMinZoom() < MIN_ZOOM) throw new RuntimeException("Minumim zoom level too low"); this.mapSource = mapSource; zoomSlider.setMinimum(mapSource.getMinZoom()); zoomSlider.setMaximum(mapSource.getMaxZoom()); jobDispatcher.cancelOutstandingJobs(); if (zoom > mapSource.getMaxZoom()) setZoom(mapSource.getMaxZoom()); mapTileLayers.clear(); log.info("Map layer changed to: " + mapSource); mapTileLayers.add(new DefaultMapTileLayer(this, mapSource)); if (mapGridLayer != null) mapTileLayers.add(mapGridLayer); repaint(); } public JobDispatcher getJobDispatcher() { return jobDispatcher; } public boolean isUsePlaceHolderTiles() { return usePlaceHolderTiles; } public void tileLoadingFinished(Tile tile, boolean success) { repaint(); } public void addMapTileLayers(MapTileLayer mapTileLayer) { mapTileLayers.add(mapTileLayer); } public void removeMapTileLayers(MapTileLayer mapTileLayer) { mapTileLayers.remove(mapTileLayer); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/interfaces/0000755000175000017500000000000012122526604026620 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/interfaces/TileLoaderListener.java0000644000175000017500000000251612122526604033221 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.mapview.interfaces; import mobac.gui.mapview.MemoryTileCache; import mobac.gui.mapview.Tile; //License: GPL. Copyright 2008 by Jan Peter Stotz public interface TileLoaderListener { /** * Will be called if a new {@link Tile} has been loaded successfully. * Loaded can mean downloaded or loaded from file cache. * * @param tile */ public void tileLoadingFinished(Tile tile, boolean success); public MemoryTileCache getTileImageCache(); } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/interfaces/MapEventListener.java0000644000175000017500000000325712122526604032717 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.mapview.interfaces; import mobac.gui.mapview.controller.JMapController; import mobac.program.interfaces.MapSource; import mobac.program.model.MercatorPixelCoordinate; public interface MapEventListener { /** the selection changed */ public void selectionChanged(MercatorPixelCoordinate max, MercatorPixelCoordinate min); /** the zoom changed */ public void zoomChanged(int newZoomLevel); /** the grid zoom changed */ public void gridZoomChanged(int newGridZoomLevel); /** select the next map source from the map list */ public void selectNextMapSource(); /** select the previous map source from the map list */ public void selectPreviousMapSource(); public void mapSourceChanged(MapSource newMapSource); public void mapSelectionControllerChanged(JMapController newMapController); } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/interfaces/MapLayer.java0000644000175000017500000000306012122526604031174 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.mapview.interfaces; import java.awt.Graphics2D; import mobac.gui.mapview.JMapViewer; /** * General purpose map layer */ public interface MapLayer { /** * * @param map * @param g * @param zoom * current zoom level * @param minX * top left x coordinate of the visible map region * @param minYtop * left y coordinate of the visible map region * @param maxX * bottom right x coordinate of the visible map region * @param maxY * bottom right y coordinate of the visible map region */ public void paint(JMapViewer map, Graphics2D g, int zoom, int minX, int minY, int maxX, int maxY); } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/interfaces/MapTileLayer.java0000644000175000017500000000276112122526604032021 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.mapview.interfaces; import java.awt.Graphics; import mobac.program.interfaces.MapSource; public interface MapTileLayer { public void startPainting(MapSource mapSource); /** * Paints the tile identified by tilex/tiley/ * zoom onto the {@link Graphics} g with it's * upper left corner at gx/gy. The size of each * tile has to be 256 pixel x 256 pixel. * * @param g * @param gx * @param gy * @param tilex * @param tiley */ public void paintTile(Graphics g, int gx, int gy, int tilex, int tiley, int zoom); } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/TileLoader.java0000644000175000017500000001075612127544350027400 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.mapview; //License: GPL. Copyright 2008 by Jan Peter Stotz import java.awt.image.BufferedImage; import java.net.ConnectException; import mobac.exceptions.DownloadFailedException; import mobac.gui.mapview.Tile.TileState; import mobac.gui.mapview.interfaces.TileLoaderListener; import mobac.program.download.TileDownLoader; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSource.LoadMethod; import mobac.program.tilestore.TileStore; import mobac.program.tilestore.TileStoreEntry; import org.apache.log4j.Logger; /** * A {@link TileLoaderJobCreator} implementation that loads tiles from OSM via HTTP and saves all loaded files in a * directory located in the the temporary directory. If a tile is present in this file cache it will not be loaded from * OSM again. * * @author Jan Peter Stotz * @author r_x */ public class TileLoader { private static final Logger log = Logger.getLogger(TileLoader.class); protected TileStore tileStore; protected TileLoaderListener listener; public TileLoader(TileLoaderListener listener) { super(); this.listener = listener; tileStore = TileStore.getInstance(); } public Runnable createTileLoaderJob(final MapSource source, final int tilex, final int tiley, final int zoom) { return new TileAsyncLoadJob(source, tilex, tiley, zoom); } protected class TileAsyncLoadJob implements Runnable { final int tilex, tiley, zoom; final MapSource mapSource; Tile tile; boolean fileTilePainted = false; protected TileStoreEntry tileStoreEntry = null; public TileAsyncLoadJob(MapSource source, int tilex, int tiley, int zoom) { super(); this.mapSource = source; this.tilex = tilex; this.tiley = tiley; this.zoom = zoom; } public void run() { MemoryTileCache cache = listener.getTileImageCache(); synchronized (cache) { tile = cache.getTile(mapSource, tilex, tiley, zoom); if (tile == null || tile.tileState != TileState.TS_NEW) return; tile.setTileState(TileState.TS_LOADING); } if (loadTileFromStore()) return; if (fileTilePainted) { Runnable job = new Runnable() { public void run() { loadOrUpdateTile(); } }; JobDispatcher.getInstance().addJob(job); } else { loadOrUpdateTile(); } } protected void loadOrUpdateTile() { try { BufferedImage image = mapSource.getTileImage(zoom, tilex, tiley, LoadMethod.DEFAULT); if (image != null) { tile.setImage(image); tile.setTileState(TileState.TS_LOADED); listener.tileLoadingFinished(tile, true); } else { tile.setErrorImage(); listener.tileLoadingFinished(tile, false); } return; } catch (ConnectException e) { log.warn("Downloading of " + tile + " failed " + e.getMessage()); } catch (DownloadFailedException e) { log.warn("Downloading of " + tile + " failed " + e.getMessage()); } catch (Exception e) { log.debug("Downloading of " + tile + " failed", e); } tile.setErrorImage(); listener.tileLoadingFinished(tile, false); } protected boolean loadTileFromStore() { try { BufferedImage image = mapSource.getTileImage(zoom, tilex, tiley, LoadMethod.CACHE); if (image == null) return false; tile.setImage(image); listener.tileLoadingFinished(tile, true); if (TileDownLoader.isTileExpired(tileStoreEntry)) return false; fileTilePainted = true; return true; } catch (Exception e) { log.error("Failed to load tile (z=" + zoom + ",x=" + tilex + ",y=" + tiley + ") from tile store", e); } return false; } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/GridZoom.java0000644000175000017500000000271212127544350027077 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.mapview; import mobac.utilities.I18nUtils; public class GridZoom { private int zoom; public int getZoom() { return zoom; } public GridZoom(int zoom) { this.zoom = zoom; } @Override public String toString() { return String.format(I18nUtils.localizedStringForKey("map_ctrl_zoom_grid_prefix_fmt"), zoom); } @Override public boolean equals(Object obj) { if (!(obj instanceof GridZoom)) return false; return ((GridZoom) obj).zoom == zoom; } @Override public int hashCode() { assert false : "hashCode not designed"; return -1; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/ScaleBar.java0000644000175000017500000000612612122526604027021 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.mapview; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.Point; import java.awt.Rectangle; import java.awt.Stroke; import javax.swing.JComponent; import mobac.program.interfaces.MapSpace; import mobac.program.model.Settings; import mobac.program.model.UnitSystem; import mobac.utilities.MyMath; /** * Simple scale bar showing the map scale using the selected unit system. */ public class ScaleBar { private static final Stroke STROKE = new BasicStroke(1); private static final Font FONT = new Font("Sans Serif", Font.PLAIN, 12); /** * Horizontal margin between scale bar and right border of the map */ private static final int MARGIN_X = 40; /** * Vertical margin between scale bar and bottom border of the map */ private static final int MARGIN_Y = 40; private static final int DESIRED_SCALE_BAR_WIDTH = 150; public static void paintScaleBar(JComponent c, Graphics2D g, MapSpace mapSpace, Point tlc, int zoom) { Rectangle r = c.getBounds(); int posX; int posY = r.height - r.y; posY -= MARGIN_Y; posX = MARGIN_X; // int coordX = tlc.x + posX; int coordY = tlc.y + posY; int w1 = DESIRED_SCALE_BAR_WIDTH; UnitSystem unitSystem = Settings.getInstance().unitSystem; // Calculate the angular distance of our desired scale bar double ad = mapSpace.horizontalDistance(zoom, coordY, w1); String unit = unitSystem.unitLarge; // convert angular into the selected unit system double dist1 = ad * unitSystem.earthRadius; // distance is smaller that one (km/mi)? the use smaller units (m/ft) if (dist1 < 1.0) { dist1 *= unitSystem.unitFactor; unit = unitSystem.unitSmall; } // Round everything to a nice value double dist2 = MyMath.prettyRound(dist1); double factor = dist2 / dist1; // apply the round factor to the width of our scale bar int w2 = (int) (w1 * factor); g.setStroke(STROKE); g.setColor(Color.YELLOW); g.fillRect(posX, posY - 10, w2, 20); g.setColor(Color.BLACK); g.drawRect(posX, posY - 10, w2, 20); String value = Integer.toString((int) dist2) + " " + unit; g.setFont(FONT); g.drawString(value, posX + 10, posY + 4); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/controller/0000755000175000017500000000000012127544350026663 5ustar paulliupaulliu././@LongLink0000000000000000000000000000016600000000000011570 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/controller/PolygonCircleSelectionMapController.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/controller/PolygonCircleSelectionM0000644000175000017500000000521212122526604033337 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.mapview.controller; import java.awt.Point; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import mobac.gui.mapview.PreviewMap; /** * Implements the GUI logic for the preview map panel that manages the map selection and actions triggered by key * strokes. * */ public class PolygonCircleSelectionMapController extends AbstractPolygonSelectionMapController implements MouseMotionListener, MouseListener { private static final int POLYGON_POINTS = 16; private static final double ANGLE_PART = Math.PI * 2.0 / POLYGON_POINTS; private Point center; public PolygonCircleSelectionMapController(PreviewMap map) { super(map); } public void mouseClicked(MouseEvent e) { } public void mousePressed(MouseEvent e) { if (e.getButton() == MouseEvent.BUTTON1) { center = convertToAbsolutePoint(e.getPoint()); polygonPoints.ensureCapacity(POLYGON_POINTS); } } public void mouseDragged(MouseEvent e) { if ((e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) == MouseEvent.BUTTON1_DOWN_MASK) { if (center != null) { Point circlePoint = convertToAbsolutePoint(e.getPoint()); double radius = circlePoint.distance(center); polygonPoints.clear(); for (int i = 0; i < POLYGON_POINTS; i++) { double angle = ANGLE_PART * i; int y = (int) Math.round(Math.sin(angle) * radius); int x = (int) Math.round(Math.cos(angle) * radius); polygonPoints.add(new Point(center.x + x, center.y + y)); } map.grabFocus(); map.repaint(); } } } public void mouseMoved(MouseEvent e) { } public void mouseReleased(MouseEvent e) { } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } } ././@LongLink0000000000000000000000000000016000000000000011562 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/controller/PolygonSelectionMapController.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/controller/PolygonSelectionMapCont0000644000175000017500000000371712122526604033372 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.mapview.controller; import java.awt.Point; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import mobac.gui.mapview.PreviewMap; /** * Implements the GUI logic for the preview map panel that manages the map selection and actions triggered by key * strokes. * */ public class PolygonSelectionMapController extends AbstractPolygonSelectionMapController implements MouseListener { public PolygonSelectionMapController(PreviewMap map) { super(map); } public void mouseClicked(MouseEvent e) { } public void mousePressed(MouseEvent e) { } public void mouseReleased(MouseEvent e) { if (e.getButton() == MouseEvent.BUTTON1) { if (finished) reset(); Point mapPoint = map.getTopLeftCoordinate(); mapPoint.x += e.getX(); mapPoint.y += e.getY(); mapPoint = map.getMapSource().getMapSpace().changeZoom(mapPoint, map.getZoom(), PreviewMap.MAX_ZOOM); polygonPoints.add(mapPoint); } map.grabFocus(); map.repaint(); } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } } ././@LongLink0000000000000000000000000000017000000000000011563 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/controller/AbstractPolygonSelectionMapController.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/controller/AbstractPolygonSelectio0000644000175000017500000000374412122526604033416 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.mapview.controller; import java.awt.Point; import java.util.ArrayList; import mobac.gui.mapview.JMapViewer; import mobac.gui.mapview.PreviewMap; import mobac.gui.mapview.layer.PolygonSelectionLayer; /** */ public abstract class AbstractPolygonSelectionMapController extends JMapController { protected boolean finished = false; protected ArrayList polygonPoints = new ArrayList(); protected PolygonSelectionLayer mapLayer = null; public AbstractPolygonSelectionMapController(PreviewMap map) { super(map, false); mapLayer = new PolygonSelectionLayer(this); } public void reset() { polygonPoints = new ArrayList(); finished = false; } public void finishPolygon() { finished = true; } @Override public void enable() { map.mapLayers.add(mapLayer); super.enable(); } @Override public void disable() { map.mapLayers.remove(mapLayer); super.disable(); } /** * @return List of absolute tile coordinate points regarding {@link JMapViewer#MAX_ZOOM} */ public ArrayList getPolygonPoints() { return polygonPoints; } } ././@LongLink0000000000000000000000000000015000000000000011561 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/controller/MapKeyboardController.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/controller/MapKeyboardController.j0000644000175000017500000002365712122526604033312 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.mapview.controller; import java.awt.event.ActionEvent; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; import java.util.Timer; import java.util.TimerTask; import javax.swing.AbstractAction; import javax.swing.ActionMap; import javax.swing.ComponentInputMap; import javax.swing.InputMap; import javax.swing.JComponent; import javax.swing.KeyStroke; import mobac.gui.mapview.PreviewMap; /** * Implements the GUI logic for the preview map panel that manages the map * movement by mouse and actions triggered by key strokes. */ public class MapKeyboardController extends JMapController { /** A Timer for smoothly moving the map area */ private static final Timer timer = new Timer(true); /** Does the moving */ private MoveTask moveTask = new MoveTask(); /** How often to do the moving (milliseconds) */ private static long timerInterval = 20; /** The maximum speed (pixels per timer interval) */ private static final double MAX_SPEED = 20; /** The speed increase per timer interval when a cursor button is clicked */ private static final double ACCELERATION = 0.10; private final InputMap inputMap; public MapKeyboardController(PreviewMap map, boolean enabled) { super(map); inputMap = new ComponentInputMap(map); ActionMap actionMap = map.getActionMap(); // map moving inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, false), "MOVE_RIGHT"); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, false), "MOVE_LEFT"); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "MOVE_UP"); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), "MOVE_DOWN"); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, true), "STOP_MOVE_HORIZONTALLY"); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, true), "STOP_MOVE_HORIZONTALLY"); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true), "STOP_MOVE_VERTICALLY"); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "STOP_MOVE_VERTICALLY"); // zooming. To avoid confusion about which modifier key to use, // we just add all keys left of the space bar inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, InputEvent.CTRL_DOWN_MASK, false), "ZOOM_IN"); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, InputEvent.META_DOWN_MASK, false), "ZOOM_IN"); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, InputEvent.ALT_DOWN_MASK, false), "ZOOM_IN"); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, InputEvent.CTRL_DOWN_MASK, false), "ZOOM_OUT"); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, InputEvent.META_DOWN_MASK, false), "ZOOM_OUT"); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, InputEvent.ALT_DOWN_MASK, false), "ZOOM_OUT"); // map selection inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, InputEvent.CTRL_DOWN_MASK, false), "PREVIOUS_MAP"); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, InputEvent.META_DOWN_MASK, false), "PREVIOUS_MAP"); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, InputEvent.ALT_DOWN_MASK, false), "PREVIOUS_MAP"); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, InputEvent.CTRL_DOWN_MASK, false), "NEXT_MAP"); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, InputEvent.META_DOWN_MASK, false), "NEXT_MAP"); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, InputEvent.ALT_DOWN_MASK, false), "NEXT_MAP"); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_F5, 0, true), "REFRESH"); // action mapping actionMap.put("MOVE_RIGHT", new MoveRightAction()); actionMap.put("MOVE_LEFT", new MoveLeftAction()); actionMap.put("MOVE_UP", new MoveUpAction()); actionMap.put("MOVE_DOWN", new MoveDownAction()); actionMap.put("STOP_MOVE_HORIZONTALLY", new StopMoveHorizontallyAction()); actionMap.put("STOP_MOVE_VERTICALLY", new StopMoveVerticallyAction()); actionMap.put("ZOOM_IN", new ZoomInAction()); actionMap.put("ZOOM_OUT", new ZoomOutAction()); actionMap.put("NEXT_MAP", new NextMapAction()); actionMap.put("PREVIOUS_MAP", new PreviousMapAction()); actionMap.put("REFRESH", new RefreshAction()); if (enabled) enable(); } @Override public void disable() { map.setInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW, new ComponentInputMap(map)); } @Override public void enable() { map.setInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW, inputMap); } private class MoveRightAction extends AbstractAction { private static final long serialVersionUID = -6758721144600926744L; public void actionPerformed(ActionEvent e) { moveTask.setDirectionX(1); } } private class MoveLeftAction extends AbstractAction { private static final long serialVersionUID = 2695221718338284951L; public void actionPerformed(ActionEvent e) { moveTask.setDirectionX(-1); } } private class MoveUpAction extends AbstractAction { private static final long serialVersionUID = -8414310977137213707L; public void actionPerformed(ActionEvent e) { moveTask.setDirectionY(-1); } } private class MoveDownAction extends AbstractAction { private static final long serialVersionUID = -5360890019457799681L; public void actionPerformed(ActionEvent e) { moveTask.setDirectionY(1); } } private class StopMoveHorizontallyAction extends AbstractAction { private static final long serialVersionUID = -5360890019457799681L; public void actionPerformed(ActionEvent e) { moveTask.setDirectionX(0); } } private class StopMoveVerticallyAction extends AbstractAction { private static final long serialVersionUID = -5360890019457799681L; public void actionPerformed(ActionEvent e) { moveTask.setDirectionY(0); } } /** Moves the map depending on which cursor keys are pressed (or not) */ private class MoveTask extends TimerTask { /** The current x speed (pixels per timer interval) */ private double speedX = 1; /** The current y speed (pixels per timer interval) */ private double speedY = 1; /** The horizontal direction of movement, -1:left, 0:stop, 1:right */ private int directionX = 0; /** The vertical direction of movement, -1:up, 0:stop, 1:down */ private int directionY = 0; /** * Indicated if moveTask is currently enabled (periodically * executed via timer) or disabled */ protected boolean scheduled = false; protected void setDirectionX(int directionX) { this.directionX = directionX; updateScheduleStatus(); } protected void setDirectionY(int directionY) { this.directionY = directionY; updateScheduleStatus(); } private void updateScheduleStatus() { boolean newMoveTaskState = !(directionX == 0 && directionY == 0); if (newMoveTaskState != scheduled) { scheduled = newMoveTaskState; if (newMoveTaskState) timer.schedule(this, 0, timerInterval); else { // We have to create a new instance because rescheduling a // once canceled TimerTask is not possible moveTask = new MoveTask(); cancel(); // Stop this TimerTask } } } @Override public void run() { // update the x speed switch (directionX) { case -1: if (speedX > -1) speedX = -1; if (speedX > -1 * MAX_SPEED) speedX -= ACCELERATION; break; case 0: speedX = 0; break; case 1: if (speedX < 1) speedX = 1; if (speedX < MAX_SPEED) speedX += ACCELERATION; break; } // update the y speed switch (directionY) { case -1: if (speedY > -1) speedY = -1; if (speedY > -1 * MAX_SPEED) speedY -= ACCELERATION; break; case 0: speedY = 0; break; case 1: if (speedY < 1) speedY = 1; if (speedY < MAX_SPEED) speedY += ACCELERATION; break; } // move the map int moveX = (int) Math.floor(speedX); int moveY = (int) Math.floor(speedY); if (moveX != 0 || moveY != 0) map.moveMap(moveX, moveY); } } private class ZoomInAction extends AbstractAction { private static final long serialVersionUID = 1471739991027644588L; public void actionPerformed(ActionEvent e) { map.zoomIn(); } } private class ZoomOutAction extends AbstractAction { private static final long serialVersionUID = 1471739991027644588L; public void actionPerformed(ActionEvent e) { map.zoomOut(); } } private class PreviousMapAction extends AbstractAction { private static final long serialVersionUID = -1492075614917423363L; public void actionPerformed(ActionEvent e) { ((PreviewMap) map).selectPreviousMap(); } } private class NextMapAction extends AbstractAction { private static final long serialVersionUID = -1491235614917423363L; public void actionPerformed(ActionEvent e) { ((PreviewMap) map).selectNextMap(); } } private class RefreshAction extends AbstractAction { private static final long serialVersionUID = -7235666079485033823L; public void actionPerformed(ActionEvent e) { ((PreviewMap) map).refreshMap(); } } } ././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/controller/DefaultMapController.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/controller/DefaultMapController.ja0000644000175000017500000001321012122526604033257 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.mapview.controller; //License: GPL. Copyright 2008 by Jan Peter Stotz import java.awt.Point; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelListener; import mobac.gui.mapview.PreviewMap; import mobac.utilities.OSUtilities; /** * Default map controller which implements map moving by pressing the right mouse button and zooming by double click or * by mouse wheel. * * @author Jan Peter Stotz * */ public class DefaultMapController extends JMapController implements MouseListener, MouseMotionListener, MouseWheelListener { private static final int MOUSE_BUTTONS_MASK = MouseEvent.BUTTON3_DOWN_MASK | MouseEvent.BUTTON1_DOWN_MASK | MouseEvent.BUTTON2_DOWN_MASK; private static final int MAC_MOUSE_BUTTON3_MASK = MouseEvent.CTRL_DOWN_MASK | MouseEvent.BUTTON1_DOWN_MASK; public DefaultMapController(PreviewMap map) { super(map, true); } private Point lastDragPoint; private boolean isMoving = false; private boolean movementEnabled = true; private int movementMouseButton = MouseEvent.BUTTON3; private int movementMouseButtonMask = MouseEvent.BUTTON3_DOWN_MASK; private boolean wheelZoomEnabled = true; private boolean doubleClickZoomEnabled = true; public void mouseDragged(MouseEvent e) { if (!movementEnabled || !isMoving) return; // Is only the selected mouse button pressed? if ((e.getModifiersEx() & MOUSE_BUTTONS_MASK) == movementMouseButtonMask) { Point p = e.getPoint(); if (lastDragPoint != null) { int diffx = lastDragPoint.x - p.x; int diffy = lastDragPoint.y - p.y; map.moveMap(diffx, diffy); } lastDragPoint = p; } } public void mouseClicked(MouseEvent e) { if (doubleClickZoomEnabled && e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON1) map.zoomIn(e.getPoint()); } public void mousePressed(MouseEvent e) { if (e.getButton() == movementMouseButton || OSUtilities.isPlatformOsx() && e.getModifiersEx() == MAC_MOUSE_BUTTON3_MASK) { lastDragPoint = null; isMoving = true; } } public void mouseReleased(MouseEvent e) { if (e.getButton() == movementMouseButton || OSUtilities.isPlatformOsx() && e.getButton() == MouseEvent.BUTTON1) { lastDragPoint = null; isMoving = false; } } public void mouseWheelMoved(MouseWheelEvent e) { if (wheelZoomEnabled) map.setZoom(map.getZoom() - e.getWheelRotation(), e.getPoint()); } public boolean isMovementEnabled() { return movementEnabled; } /** * Enables or disables that the map pane can be moved using the mouse. * * @param movementEnabled */ public void setMovementEnabled(boolean movementEnabled) { this.movementEnabled = movementEnabled; } public int getMovementMouseButton() { return movementMouseButton; } /** * Sets the mouse button that is used for moving the map. Possible values are: *
    *
  • {@link MouseEvent#BUTTON1} (left mouse button)
  • *
  • {@link MouseEvent#BUTTON2} (middle mouse button)
  • *
  • {@link MouseEvent#BUTTON3} (right mouse button)
  • *
* * @param movementMouseButton */ public void setMovementMouseButton(int movementMouseButton) { this.movementMouseButton = movementMouseButton; switch (movementMouseButton) { case MouseEvent.BUTTON1: movementMouseButtonMask = MouseEvent.BUTTON1_DOWN_MASK; break; case MouseEvent.BUTTON2: movementMouseButtonMask = MouseEvent.BUTTON2_DOWN_MASK; break; case MouseEvent.BUTTON3: movementMouseButtonMask = MouseEvent.BUTTON3_DOWN_MASK; break; default: throw new RuntimeException("Unsupported button"); } } public boolean isWheelZoomEnabled() { return wheelZoomEnabled; } public void setWheelZoomEnabled(boolean wheelZoomEnabled) { this.wheelZoomEnabled = wheelZoomEnabled; } public boolean isDoubleClickZoomEnabled() { return doubleClickZoomEnabled; } public void setDoubleClickZoomEnabled(boolean doubleClickZoomEnabled) { this.doubleClickZoomEnabled = doubleClickZoomEnabled; } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void mouseMoved(MouseEvent e) { // Mac OSX simulates with ctrl + mouse 1 the second mouse button hence // no dragging events get fired. if (!OSUtilities.isPlatformOsx() || !movementEnabled || !isMoving) return; // Is only the selected mouse button pressed? if (e.getModifiersEx() == MouseEvent.CTRL_DOWN_MASK) { Point p = e.getPoint(); if (lastDragPoint != null) { int diffx = lastDragPoint.x - p.x; int diffy = lastDragPoint.y - p.y; map.moveMap(diffx, diffy); } lastDragPoint = p; } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/controller/GpxMapController.java0000644000175000017500000000701112127544350032765 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.mapview.controller; import java.awt.Point; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.math.BigDecimal; import javax.swing.JOptionPane; import mobac.data.gpx.gpx11.Gpx; import mobac.data.gpx.gpx11.WptType; import mobac.gui.actions.GpxEditor; import mobac.gui.gpxtree.GpxEntry; import mobac.gui.gpxtree.GpxRootEntry; import mobac.gui.gpxtree.RteEntry; import mobac.gui.gpxtree.TrksegEntry; import mobac.gui.mapview.PreviewMap; import mobac.gui.panels.JGpxPanel; import mobac.program.interfaces.MapSpace; import mobac.utilities.I18nUtils; /** * Allows to create new GPX way-points by clicking on the preview map */ public class GpxMapController extends JMapController implements MouseListener { private JGpxPanel panel; private GpxEntry entry; public GpxMapController(PreviewMap map, JGpxPanel panel, boolean enabled) { super(map, enabled); this.panel = panel; } public void mouseClicked(MouseEvent e) { // Add new GPX point to currently selected GPX file disable(); if (e.getButton() == MouseEvent.BUTTON1) { entry = panel.getSelectedEntry(); Gpx gpx = entry.getLayer().getGpx(); Point p = e.getPoint(); Point tl = ((PreviewMap) map).getTopLeftCoordinate(); p.x += tl.x; p.y += tl.y; MapSpace mapSpace = map.getMapSource().getMapSpace(); int maxPixel = mapSpace.getMaxPixels(map.getZoom()); if (p.x < 0 || p.x > maxPixel || p.y < 0 || p.y > maxPixel) return; // outside of world region double lon = mapSpace.cXToLon(p.x, map.getZoom()); double lat = mapSpace.cYToLat(p.y, map.getZoom()); String name = JOptionPane.showInputDialog(null, I18nUtils.localizedStringForKey("dlg_gpx_inpu_point_name")); if (name == null) return; Gpx gpx11 = (Gpx) gpx; WptType wpt = new WptType(); wpt.setName(name); wpt.setLat(new BigDecimal(lat)); wpt.setLon(new BigDecimal(lon)); GpxEditor editor = GpxEditor.getInstance(); if (entry.getClass() == GpxRootEntry.class) { gpx11.getWpt().add(wpt); } else if (entry instanceof RteEntry) { editor.findRteAndAdd((RteEntry) entry, wpt); } else if (entry instanceof TrksegEntry) { editor.findTrksegAndAdd((TrksegEntry) entry, wpt); } panel.addWpt(wpt, entry); } map.repaint(); } public void repaint() { map.repaint(); } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void mousePressed(MouseEvent e) { } public void mouseReleased(MouseEvent e) { } @Override public void disable() { super.disable(); ((PreviewMap) map).getMapSelectionController().enable(); } } ././@LongLink0000000000000000000000000000016200000000000011564 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/controller/RectangleSelectionMapController.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/controller/RectangleSelectionMapCo0000644000175000017500000000742712122526604033307 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.mapview.controller; import java.awt.Point; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import mobac.gui.mapview.JMapViewer; import mobac.gui.mapview.PreviewMap; import mobac.gui.mapview.layer.RectangleSelectionLayer; /** * Implements the GUI logic for the preview map panel that manages the map selection and actions triggered by key * strokes. * */ public class RectangleSelectionMapController extends JMapController implements MouseMotionListener, MouseListener { /** * start point of selection rectangle in absolute tile coordinated regarding {@link JMapViewer#MAX_ZOOM} */ private Point iStartSelectionPoint; /** * end point of selection rectangle in absolute tile coordinated regarding {@link JMapViewer#MAX_ZOOM} */ private Point iEndSelectionPoint; protected RectangleSelectionLayer mapLayer; public RectangleSelectionMapController(PreviewMap map) { super(map, false); mapLayer = new RectangleSelectionLayer(this); } @Override public void enable() { super.enable(); // map.mapLayers.add(mapLayer); } @Override public void disable() { map.mapLayers.remove(mapLayer); map.setSelectionByTileCoordinate(null, null, true); super.disable(); } /** * Start drawing the selection rectangle if it was the 1st button (left button) */ public void mousePressed(MouseEvent e) { if (e.getButton() == MouseEvent.BUTTON1) { iStartSelectionPoint = convertToAbsolutePoint(e.getPoint()); iEndSelectionPoint = convertToAbsolutePoint(e.getPoint()); } map.grabFocus(); } public void mouseDragged(MouseEvent e) { if ((e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) == MouseEvent.BUTTON1_DOWN_MASK) { if (iStartSelectionPoint != null) { iEndSelectionPoint = convertToAbsolutePoint(e.getPoint()); map.setSelectionByTileCoordinate(PreviewMap.MAX_ZOOM, iStartSelectionPoint, iEndSelectionPoint, true); } } } /** * When dragging the map change the cursor back to it's pre-move cursor. If a double-click occurs center and zoom * the map on the clicked location. */ public void mouseReleased(MouseEvent e) { if (e.getButton() == MouseEvent.BUTTON1) { if (e.getClickCount() == 1) { map.setSelectionByTileCoordinate(PreviewMap.MAX_ZOOM, iStartSelectionPoint, convertToAbsolutePoint(e.getPoint()), true); } } map.grabFocus(); } public void mouseMoved(MouseEvent e) { } public void mouseClicked(MouseEvent e) { map.grabFocus(); } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public Point getiStartSelectionPoint() { return iStartSelectionPoint; } public Point getiEndSelectionPoint() { return iEndSelectionPoint; } public RectangleSelectionLayer getMapLayer() { return mapLayer; } public PreviewMap getMap() { return map; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/controller/JMapController.java0000644000175000017500000000542412122526604032423 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.mapview.controller; //License: GPL. Copyright 2008 by Jan Peter Stotz import java.awt.Point; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.event.MouseWheelListener; import mobac.gui.mapview.PreviewMap; /** * Abstract base class for all mouse controller implementations. For implementing your own controller create a class * that derives from this one and implements one or more of the following interfaces: *
    *
  • {@link MouseListener}
  • *
  • {@link MouseMotionListener}
  • *
  • {@link MouseWheelListener}
  • *
*/ public abstract class JMapController { protected final PreviewMap map; protected boolean enabled = false; public JMapController(PreviewMap map) { this.map = map; } public JMapController(PreviewMap map, boolean enabled) { this(map); if (enabled) enable(); } public void enable() { if (enabled) return; if (this instanceof MouseListener) map.addMouseListener((MouseListener) this); if (this instanceof MouseWheelListener) map.addMouseWheelListener((MouseWheelListener) this); if (this instanceof MouseMotionListener) map.addMouseMotionListener((MouseMotionListener) this); this.enabled = true; } public void disable() { if (!enabled) return; if (this instanceof MouseListener) map.removeMouseListener((MouseListener) this); if (this instanceof MouseWheelListener) map.removeMouseWheelListener((MouseWheelListener) this); if (this instanceof MouseMotionListener) map.removeMouseMotionListener((MouseMotionListener) this); this.enabled = false; } protected Point convertToAbsolutePoint(Point p) { Point mapPoint = map.getTopLeftCoordinate(); mapPoint.x += p.getX(); mapPoint.y += p.getY(); mapPoint = map.getMapSource().getMapSpace().changeZoom(mapPoint, map.getZoom(), PreviewMap.MAX_ZOOM); return mapPoint; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/layer/0000755000175000017500000000000012127544350025614 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/layer/MapGridLayer.java0000644000175000017500000000261212122526604030775 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.mapview.layer; import java.awt.Graphics; import mobac.gui.mapview.interfaces.MapTileLayer; import mobac.program.interfaces.MapSource; /** * A simple layer that paints the tile borders. */ public class MapGridLayer implements MapTileLayer { protected int tileSize; public void startPainting(MapSource mapSource) { tileSize = mapSource.getMapSpace().getTileSize(); } public void paintTile(Graphics g, int gx, int gy, int tilex, int tiley, int zoom) { g.drawRect(gx, gy, tileSize, tileSize); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/layer/RectangleSelectionLayer.java0000644000175000017500000000451412122526604033227 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.mapview.layer; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Point; import java.awt.geom.AffineTransform; import mobac.gui.mapview.JMapViewer; import mobac.gui.mapview.PreviewMap; import mobac.gui.mapview.controller.RectangleSelectionMapController; import mobac.gui.mapview.interfaces.MapLayer; import mobac.program.interfaces.MapSpace; /** * Displays a polygon on the map - only for testing purposes */ public class RectangleSelectionLayer implements MapLayer { private final RectangleSelectionMapController mapController; public RectangleSelectionLayer(RectangleSelectionMapController rectangleSelectionMapController) { this.mapController = rectangleSelectionMapController; } public void paint(JMapViewer map, Graphics2D g, int zoom, int minX, int minY, int maxX, int maxY) { MapSpace mapSpace = map.getMapSource().getMapSpace(); g.setColor(Color.BLUE); Point p1 = mapController.getiStartSelectionPoint(); Point p2 = mapController.getiEndSelectionPoint(); if (p1 == null || p2 == null) return; p1 = mapSpace.changeZoom(p1, PreviewMap.MAX_ZOOM, zoom); p2 = mapSpace.changeZoom(p2, PreviewMap.MAX_ZOOM, zoom); int x = Math.min(p1.x, p2.x); int y = Math.min(p1.y, p2.y); int w = Math.abs(p1.x - p2.x); int h = Math.abs(p1.y - p2.y); AffineTransform at = g.getTransform(); try { g.translate(-minX, -minY); g.drawRect(x, y, w, h); } finally { g.setTransform(at); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/layer/OverlayMapTileLayer.java0000644000175000017500000000502612122526604032351 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.mapview.layer; import java.awt.Graphics; import mobac.gui.mapview.JMapViewer; import mobac.gui.mapview.Tile; import mobac.gui.mapview.Tile.TileState; import mobac.gui.mapview.interfaces.MapTileLayer; import mobac.program.interfaces.MapSource; public class OverlayMapTileLayer implements MapTileLayer { protected JMapViewer mapViewer; protected MapSource mapSource; public OverlayMapTileLayer(JMapViewer mapViewer, MapSource tileSource) { this.mapViewer = mapViewer; this.mapSource = tileSource; } public void startPainting(MapSource mapSource) { } public void paintTile(Graphics g, int gx, int gy, int tilex, int tiley, int zoom) { Tile tile = getTile(tilex, tiley, zoom); if (tile == null) return; tile.paintTransparent(g, gx, gy); } /** * retrieves a tile from the cache. If the tile is not present in the cache a load job is added to the working queue * of {@link JobThread}. * * @param tilex * @param tiley * @param zoom * @return specified tile from the cache or null if the tile was not found in the cache. */ protected Tile getTile(int tilex, int tiley, int zoom) { int max = (1 << zoom); if (tilex < 0 || tilex >= max || tiley < 0 || tiley >= max) return null; Tile tile = mapViewer.getTileImageCache().getTile(mapSource, tilex, tiley, zoom); if (tile == null) { tile = new Tile(mapSource, tilex, tiley, zoom); mapViewer.getTileImageCache().addTile(tile); } if (tile.getTileState() == TileState.TS_NEW) { mapViewer.getJobDispatcher().addJob( mapViewer.getTileLoader().createTileLoaderJob(mapSource, tilex, tiley, zoom)); } return tile; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/layer/PolygonSelectionLayer.java0000644000175000017500000000471712122526604032757 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.mapview.layer; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Point; import java.awt.geom.AffineTransform; import java.util.List; import mobac.gui.mapview.JMapViewer; import mobac.gui.mapview.PreviewMap; import mobac.gui.mapview.controller.AbstractPolygonSelectionMapController; import mobac.gui.mapview.interfaces.MapLayer; import mobac.program.interfaces.MapSpace; /** * Displays a polygon on the map - only for testing purposes */ public class PolygonSelectionLayer implements MapLayer { private final AbstractPolygonSelectionMapController mapController; public PolygonSelectionLayer(AbstractPolygonSelectionMapController mapController) { this.mapController = mapController; } public void paint(JMapViewer map, Graphics2D g, int zoom, int minX, int minY, int maxX, int maxY) { MapSpace mapSpace = map.getMapSource().getMapSpace(); g.setColor(Color.RED); Point lastPoint = null; List pointList = mapController.getPolygonPoints(); if (pointList.size() == 0) return; AffineTransform at = g.getTransform(); try { g.translate(-minX, -minY); for (Point p : pointList) { Point p1 = mapSpace.changeZoom(p, PreviewMap.MAX_ZOOM, zoom); g.fillOval(p1.x - 3, p1.y - 3, 6, 6); if (lastPoint != null) { g.drawLine(p1.x, p1.y, lastPoint.x, lastPoint.y); } lastPoint = p1; } // Draw line back to the starting point Point p1 = mapSpace.changeZoom(pointList.get(0), PreviewMap.MAX_ZOOM, zoom); g.drawLine(p1.x, p1.y, lastPoint.x, lastPoint.y); } finally { g.setTransform(at); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/layer/TileStoreCoverageLayer.java0000644000175000017500000001144612127544350033050 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.mapview.layer; import java.awt.Graphics2D; import java.awt.Point; import java.awt.image.BufferedImage; import java.util.Iterator; import javax.swing.JOptionPane; import mobac.gui.MainGUI; import mobac.gui.dialogs.WorkinprogressDialog; import mobac.gui.mapview.JMapViewer; import mobac.gui.mapview.PreviewMap; import mobac.gui.mapview.interfaces.MapLayer; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSpace; import mobac.program.tilestore.TileStore; import mobac.program.tilestore.berkeleydb.DelayedInterruptThread; import mobac.utilities.GUIExceptionHandler; import mobac.utilities.I18nUtils; public class TileStoreCoverageLayer implements MapLayer { private final MapSource mapSource; private final int zoom; private final Point pixelCoordinateMin; private final Point pixelCoordinateMax; private final Point tileNumMin; private final Point tileNumMax; private BufferedImage coverageImage = null; public static void removeCacheCoverageLayers() { try { PreviewMap previewMap = MainGUI.getMainGUI().previewMap; Iterator mapLayers = previewMap.mapLayers.iterator(); MapLayer ml; while (mapLayers.hasNext()) { ml = mapLayers.next(); if (ml instanceof TileStoreCoverageLayer) { mapLayers.remove(); } } } catch (Exception e) { } } public TileStoreCoverageLayer(PreviewMap mapViewer, MapSource mapSource, int zoom) { this.mapSource = mapSource; this.zoom = zoom; MapSpace mapSpace = mapSource.getMapSpace(); int tileSize = mapSpace.getTileSize(); int mapViewerZoom = mapViewer.getZoom(); Point min = mapViewer.getTopLeftCoordinate(); Point max = new Point(min.x + mapViewer.getWidth(), min.y + mapViewer.getHeight()); min = mapSpace.changeZoom(min, mapViewerZoom, zoom); max = mapSpace.changeZoom(max, mapViewerZoom, zoom); tileNumMax = new Point(max.x / tileSize, max.y / tileSize); tileNumMin = new Point(min.x / tileSize, min.y / tileSize); pixelCoordinateMax = new Point(tileNumMax.x * tileSize + tileSize - 1, tileNumMax.y * tileSize + tileSize - 1); pixelCoordinateMin = new Point(tileNumMin.x * tileSize, tileNumMin.y * tileSize); updateCoverageImage(); } private void updateCoverageImage() { coverageImage = null; Runnable r = new Runnable() { public void run() { try { coverageImage = TileStore.getInstance().getCacheCoverage(mapSource, zoom, tileNumMin, tileNumMax); if (coverageImage == null) JOptionPane.showMessageDialog(MainGUI.getMainGUI(), I18nUtils.localizedStringForKey("msg_tile_store_failed_retrieve_coverage"), I18nUtils.localizedStringForKey("Error"), JOptionPane.ERROR_MESSAGE); } catch (InterruptedException e) { } catch (Exception e) { GUIExceptionHandler.processException(e); } if (coverageImage == null) removeCacheCoverageLayers(); MainGUI.getMainGUI().previewMap.repaint(); } }; WorkinprogressDialog dialog = new WorkinprogressDialog(MainGUI.getMainGUI(), "Loading coverage data", DelayedInterruptThread.createThreadFactory()); dialog.startWork(r); } public void paint(JMapViewer mapViewer, Graphics2D g, int zoom, int minX, int minY, int maxX, int maxY) { if (coverageImage == null) return; paintCoverage(g, zoom, minX, minY, maxX, maxY); } protected void paintCoverage(Graphics2D g, int zoom, int minX, int minY, int maxX, int maxY) { Point max = pixelCoordinateMax; Point min = pixelCoordinateMin; MapSpace mapSpace = mapSource.getMapSpace(); int mapX = mapSpace.xChangeZoom(min.x, this.zoom, zoom); int mapY = mapSpace.yChangeZoom(min.y, this.zoom, zoom); int mapW = mapSpace.xChangeZoom(max.x - min.x + 1, this.zoom, zoom); int mapH = mapSpace.yChangeZoom(max.y - min.y + 1, this.zoom, zoom); int x = mapX - minX; int y = mapY - minY; int w = mapW; int h = mapH; g.drawImage(coverageImage, x, y, w, h, null); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/layer/ShapeLayer.java0000644000175000017500000000345112122526604030514 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.mapview.layer; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Shape; import java.awt.geom.AffineTransform; import mobac.gui.mapview.JMapViewer; import mobac.gui.mapview.interfaces.MapLayer; /** * Displays a polygon on the map - only for testing purposes */ public class ShapeLayer implements MapLayer { private Color color = new Color(0f, 1f, 0f, 0.5f); private int calculationZoom; private Shape shape;; public ShapeLayer(Shape shape, int zoom) { this.shape = shape; } public void paint(JMapViewer map, Graphics2D g, int zoom, int minX, int minY, int maxX, int maxY) { AffineTransform af = g.getTransform(); g.translate(-minX, -minY); double scale; if (zoom < calculationZoom) scale = 1d / (1 << (calculationZoom - zoom)); else scale = 1 << (zoom - calculationZoom); g.scale(scale, scale); g.setColor(color); g.fill(shape); g.setTransform(af); } } ././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/layer/MapAreaHighlightingLayer.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/layer/MapAreaHighlightingLayer.jav0000644000175000017500000001335612122526604033154 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.mapview.layer; import java.awt.Graphics2D; import java.awt.Point; import java.awt.Polygon; import java.util.Iterator; import javax.swing.event.TreeModelEvent; import javax.swing.event.TreeModelListener; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import mobac.gui.MainGUI; import mobac.gui.atlastree.JAtlasTree; import mobac.gui.mapview.JMapViewer; import mobac.gui.mapview.PreviewMap; import mobac.gui.mapview.interfaces.MapLayer; import mobac.program.interfaces.AtlasInterface; import mobac.program.interfaces.AtlasObject; import mobac.program.interfaces.LayerInterface; import mobac.program.interfaces.MapInterface; import mobac.program.model.MapPolygon; public class MapAreaHighlightingLayer implements MapLayer, TreeModelListener { private final JAtlasTree tree; private TreeSelectionListener treeListener; private AtlasObject object; public static void removeHighlightingLayers() { PreviewMap previewMap = MainGUI.getMainGUI().previewMap; Iterator mapLayers = previewMap.mapLayers.iterator(); MapLayer ml; while (mapLayers.hasNext()) { ml = mapLayers.next(); if (ml instanceof MapAreaHighlightingLayer) { mapLayers.remove(); ((MapAreaHighlightingLayer) ml).unregisterTreeListener(); } } } public MapAreaHighlightingLayer(JAtlasTree tree) { this.tree = tree; object = (AtlasObject) tree.getSelectionPath().getLastPathComponent(); MainGUI.getMainGUI().previewMap.repaint(); treeListener = new TreeSelectionListener() { public void valueChanged(TreeSelectionEvent event) { try { object = (AtlasObject) event.getNewLeadSelectionPath().getLastPathComponent(); } catch (Exception e) { object = null; } MainGUI.getMainGUI().previewMap.repaint(); } }; tree.addTreeSelectionListener(treeListener); tree.getModel().addTreeModelListener(this); } public void paint(JMapViewer mapViewer, Graphics2D g, int zoom, int minX, int minY, int maxX, int maxY) { if (object == null) return; if (object instanceof AtlasInterface) { for (LayerInterface layer : (AtlasInterface) object) { for (MapInterface map : layer) { paintMap(map, g, zoom, minX, minY, maxX, maxY); } } } else if (object instanceof LayerInterface) { for (MapInterface map : (LayerInterface) object) { paintMap(map, g, zoom, minX, minY, maxX, maxY); } } else { paintMap((MapInterface) object, g, zoom, minX, minY, maxX, maxY); } } protected void paintMap(MapInterface map, Graphics2D g, int zoom, int minX, int minY, int maxX, int maxY) { if (map instanceof MapPolygon) paintMapPolygon((MapPolygon) map, g, zoom, minX, minY, maxX, maxY); else paintMapRectangle(map, g, zoom, minX, minY, maxX, maxY); } protected void paintMapRectangle(MapInterface map, Graphics2D g, int zoom, int minX, int minY, int maxX, int maxY) { Point max = map.getMaxTileCoordinate(); Point min = map.getMinTileCoordinate(); int zoomDiff = map.getZoom() - zoom; int mapX = applyZoomDiff(min.x, zoomDiff); int mapY = applyZoomDiff(min.y, zoomDiff); int mapW = applyZoomDiff(max.x - min.x + 1, zoomDiff); int mapH = applyZoomDiff(max.y - min.y + 1, zoomDiff); int x = mapX - minX; int y = mapY - minY; int w = mapW; int h = mapH; g.setColor(PreviewMap.MAP_COLOR); g.fillRect(x, y, w, h); g.setColor(PreviewMap.GRID_COLOR); g.drawRect(x, y, w, h); } protected void paintMapPolygon(MapPolygon map, Graphics2D g, int zoom, int minX, int minY, int maxX, int maxY) { Polygon p = map.getPolygon(); int zoomDiff = map.getZoom() - zoom; int[] px = new int[p.npoints]; int[] py = new int[p.npoints]; for (int i = 0; i < px.length; i++) { px[i] = applyZoomDiff(p.xpoints[i], zoomDiff) - minX; py[i] = applyZoomDiff(p.ypoints[i], zoomDiff) - minY; } g.setColor(PreviewMap.MAP_COLOR); g.fillPolygon(px, py, px.length); } private static int applyZoomDiff(int pixelCoord, int zoomDiff) { return (zoomDiff > 0) ? pixelCoord >> zoomDiff : pixelCoord << -zoomDiff; } protected void unregisterTreeListener() { if (treeListener == null) return; try { tree.getModel().removeTreeModelListener(this); tree.removeTreeSelectionListener(treeListener); treeListener = null; } catch (Exception e) { } } @Override protected void finalize() throws Throwable { unregisterTreeListener(); super.finalize(); } public void treeNodesChanged(TreeModelEvent e) { MainGUI.getMainGUI().previewMap.repaint(); } public void treeNodesInserted(TreeModelEvent e) { MainGUI.getMainGUI().previewMap.repaint(); } public void treeNodesRemoved(TreeModelEvent e) { MainGUI.getMainGUI().previewMap.repaint(); } public void treeStructureChanged(TreeModelEvent e) { MainGUI.getMainGUI().previewMap.repaint(); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/layer/DefaultMapTileLayer.java0000644000175000017500000000531012122526604032310 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.mapview.layer; import java.awt.Graphics; import mobac.gui.mapview.JMapViewer; import mobac.gui.mapview.Tile; import mobac.gui.mapview.Tile.TileState; import mobac.gui.mapview.interfaces.MapTileLayer; import mobac.program.interfaces.MapSource; public class DefaultMapTileLayer implements MapTileLayer { protected JMapViewer mapViewer; protected MapSource mapSource; protected boolean usePlaceHolders; public DefaultMapTileLayer(JMapViewer mapViewer, MapSource mapSource) { this.mapViewer = mapViewer; this.mapSource = mapSource; } public void startPainting(MapSource mapSource) { usePlaceHolders = mapViewer.isUsePlaceHolderTiles(); } public void paintTile(Graphics g, int gx, int gy, int tilex, int tiley, int zoom) { Tile tile = getTile(tilex, tiley, zoom); if (tile == null) return; tile.paint(g, gx, gy); } /** * retrieves a tile from the cache. If the tile is not present in the cache a load job is added to the working queue * of {@link JobThread}. * * @param tilex * @param tiley * @param zoom * @return specified tile from the cache or null if the tile was not found in the cache. */ protected Tile getTile(int tilex, int tiley, int zoom) { int max = (1 << zoom); if (tilex < 0 || tilex >= max || tiley < 0 || tiley >= max) return null; Tile tile = mapViewer.getTileImageCache().getTile(mapSource, tilex, tiley, zoom); if (tile == null) { tile = new Tile(mapSource, tilex, tiley, zoom); mapViewer.getTileImageCache().addTile(tile); if (usePlaceHolders) tile.loadPlaceholderFromCache(mapViewer.getTileImageCache()); } if (tile.getTileState() == TileState.TS_NEW) { mapViewer.getJobDispatcher().addJob( mapViewer.getTileLoader().createTileLoaderJob(mapSource, tilex, tiley, zoom)); } return tile; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/gui/mapview/layer/GpxLayer.java0000644000175000017500000001262512122526604030215 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.gui.mapview.layer; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Stroke; import java.io.File; import mobac.data.gpx.gpx11.Gpx; import mobac.data.gpx.gpx11.RteType; import mobac.data.gpx.gpx11.TrkType; import mobac.data.gpx.gpx11.TrksegType; import mobac.data.gpx.gpx11.WptType; import mobac.gui.mapview.JMapViewer; import mobac.gui.mapview.interfaces.MapLayer; import mobac.gui.panels.JGpxPanel; import mobac.program.interfaces.MapSpace; /** * A {@link MapLayer} displaying the content of a loaded GPX file in a {@link JMapViewer} instance. */ public class GpxLayer implements MapLayer { private static int POINT_RADIUS = 4; private static int POINT_DIAMETER = 2 * POINT_RADIUS; private Color wptPointColor = new Color(0, 0, 200); private Color trkPointColor = Color.RED; private Color rtePointColor = new Color(0, 200, 0); private Stroke outlineStroke = new BasicStroke(1); private Stroke lineStroke = new BasicStroke(2.0f); // private Logger log = Logger.getLogger(GpxLayer.class); /** the associated gpx file handle */ private File file; /** the associated gpx object */ private final Gpx gpx; /** the associated panel that displays the nodes of the gpx file */ private JGpxPanel panel; private boolean showWaypoints = true; private boolean showWaypointName = true; private boolean showTracks = true; private boolean showRoutes = true; private int lastTrackPointX = Integer.MIN_VALUE; private int lastTrackPointY = Integer.MIN_VALUE; public GpxLayer(Gpx gpx) { this.gpx = gpx; } public void paint(JMapViewer map, Graphics2D g, int zoom, int minX, int minY, int maxX, int maxY) { g.setColor(wptPointColor); final MapSpace mapSpace = map.getMapSource().getMapSpace(); if (showWaypoints) { for (WptType pt : gpx.getWpt()) { paintPoint(pt, wptPointColor, g, showWaypointName, mapSpace, zoom, minX, minY, maxX, maxY); } } if (showTracks) { for (TrkType trk : gpx.getTrk()) { for (TrksegType seg : trk.getTrkseg()) { lastTrackPointX = Integer.MIN_VALUE; lastTrackPointY = Integer.MIN_VALUE; for (WptType pt : seg.getTrkpt()) { paintTrack(pt, trkPointColor, g, mapSpace, zoom, minX, minY, maxX, maxY); } } } } if (showRoutes) { for (RteType rte : gpx.getRte()) { lastTrackPointX = Integer.MIN_VALUE; lastTrackPointY = Integer.MIN_VALUE; for (WptType pt : rte.getRtept()) { paintTrack(pt, rtePointColor, g, mapSpace, zoom, minX, minY, maxX, maxY); } } } } private boolean paintPoint(final WptType point, Color color, final Graphics2D g, boolean paintPointName, MapSpace mapSpace, int zoom, int minX, int minY, int maxX, int maxY) { int x = mapSpace.cLonToX(point.getLon().doubleValue(), zoom); if (x < minX || x > maxX) return false; // Point outside of visible region int y = mapSpace.cLatToY(point.getLat().doubleValue(), zoom); if (y < minY || y > maxY) return false; // Point outside of visible region x -= minX; y -= minY; g.setColor(color); g.fillOval(x - POINT_RADIUS, y - POINT_RADIUS, POINT_DIAMETER, POINT_DIAMETER); g.setColor(Color.BLACK); g.setStroke(outlineStroke); g.drawOval(x - POINT_RADIUS, y - POINT_RADIUS, POINT_DIAMETER, POINT_DIAMETER); if (paintPointName && point.getName() != null) g.drawString(point.getName(), x + POINT_RADIUS + 5, y - POINT_RADIUS); return true; } private boolean paintTrack(final WptType point, Color color, final Graphics2D g, MapSpace mapSpace, int zoom, int minX, int minY, int maxX, int maxY) { // Absolute map space coordinates int xAbs = mapSpace.cLonToX(point.getLon().doubleValue(), zoom); int yAbs = mapSpace.cLatToY(point.getLat().doubleValue(), zoom); // Relative coordinates regarding the top left point on map int x = xAbs - minX; int y = yAbs - minY; g.setColor(color); if (lastTrackPointX != Integer.MIN_VALUE && lastTrackPointY != Integer.MIN_VALUE) { g.setStroke(lineStroke); g.drawLine(lastTrackPointX, lastTrackPointY, x, y); } lastTrackPointX = x; lastTrackPointY = y; return true; } /** * The associated gpx object * * @return */ public Gpx getGpx() { return gpx; } public void setPanel(JGpxPanel panel) { this.panel = panel; } public JGpxPanel getPanel() { return panel; } public void setFile(File file) { this.file = file; } /** * The associated gpx file handle * * @return */ public File getFile() { return file; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/data/0000755000175000017500000000000012122526606023154 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/data/gpx/0000755000175000017500000000000012122526606023752 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/data/gpx/GPXUtils.java0000644000175000017500000001065512122526606026303 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.data.gpx; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import javax.swing.JOptionPane; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import javax.xml.bind.util.JAXBResult; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.stream.StreamSource; import mobac.data.gpx.gpx11.Gpx; import mobac.program.Logging; import mobac.utilities.Utilities; import org.w3c.dom.Document; public class GPXUtils { public static boolean checkJAXBVersion() { boolean res = Utilities.checkJAXBVersion(); if (!res) JOptionPane.showMessageDialog(null, "Outdated Java Runtime Environment and JAXB version", "Mobile Atlas Creator has detected that your used " + "Java Runtime Environment is too old.\n Please update " + "the Java Runtime Environment to at least \nversion " + "1.6.0_14 and restart Mobile Atlas Creator.", JOptionPane.ERROR_MESSAGE); return res; } public static Gpx loadGpxFile(File f) throws JAXBException { // Create GPX 1.1 JAXB context JAXBContext context = JAXBContext.newInstance(Gpx.class); Unmarshaller unmarshaller = context.createUnmarshaller(); InputStream is = null; try { is = new FileInputStream(f); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); DocumentBuilder loader = factory.newDocumentBuilder(); Document document = loader.parse(is); String namespace = document.getDocumentElement().getNamespaceURI(); if ("http://www.topografix.com/GPX/1/1".equals(namespace)) { return (Gpx) unmarshaller.unmarshal(document); } if ("http://www.topografix.com/GPX/1/0".equals(namespace)) { Source xmlSource = new javax.xml.transform.dom.DOMSource(document); Source xsltSource = new StreamSource(Utilities .loadResourceAsStream("xsl/gpx10to11.xsl")); JAXBResult result = new JAXBResult(unmarshaller); TransformerFactory transFact = TransformerFactory.newInstance(); Transformer trans = transFact.newTransformer(xsltSource); trans.transform(xmlSource, result); return (Gpx) result.getResult(); } throw new JAXBException("Expected GPX 1.0 or GPX1.1 namespace but found \n\"" + namespace + "\""); } catch (JAXBException e) { throw e; } catch (Exception e) { throw new JAXBException(e); } finally { Utilities.closeStream(is); } } public static void saveGpxFile(Gpx gpx, File f) throws JAXBException { // Create GPX 1.1 JAXB context JAXBContext context = JAXBContext.newInstance(Gpx.class); Marshaller marshaller = context.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); OutputStream os = null; try { os = new FileOutputStream(f); marshaller.marshal(gpx, os); } catch (FileNotFoundException e) { throw new JAXBException(e); } finally { Utilities.closeStream(os); } } public static void main(String[] args) { Logging.configureConsoleLogging(); try { loadGpxFile(new File("misc/samples/gpx/gpx11 wpt.gpx")); loadGpxFile(new File("misc/samples/gpx/gpx10 wpt.gpx")); } catch (JAXBException e) { e.printStackTrace(); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/data/gpx/gpx11/0000755000175000017500000000000012122526606024712 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/data/gpx/gpx11/CopyrightType.java0000644000175000017500000001046012122526606030370 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ // // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.3 in JDK 1.6 // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. // Generated on: 2009.08.04 at 03:45:03 PM MESZ // package mobac.data.gpx.gpx11; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlSchemaType; import javax.xml.bind.annotation.XmlType; import javax.xml.datatype.XMLGregorianCalendar; /** * * Information about the copyright holder and any license governing use of this file. By linking to an appropriate license, * you may place your data into the public domain or grant additional usage rights. * * *

Java class for copyrightType complex type. * *

The following schema fragment specifies the expected content contained within this class. * *

 * <complexType name="copyrightType">
 *   <complexContent>
 *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       <sequence>
 *         <element name="year" type="{http://www.w3.org/2001/XMLSchema}gYear" minOccurs="0"/>
 *         <element name="license" type="{http://www.w3.org/2001/XMLSchema}anyURI" minOccurs="0"/>
 *       </sequence>
 *       <attribute name="author" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
 *     </restriction>
 *   </complexContent>
 * </complexType>
 * 
* * */ @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "copyrightType", propOrder = { "year", "license" }) public class CopyrightType { @XmlSchemaType(name = "gYear") protected XMLGregorianCalendar year; @XmlSchemaType(name = "anyURI") protected String license; @XmlAttribute(required = true) protected String author; /** * Gets the value of the year property. * * @return * possible object is * {@link XMLGregorianCalendar } * */ public XMLGregorianCalendar getYear() { return year; } /** * Sets the value of the year property. * * @param value * allowed object is * {@link XMLGregorianCalendar } * */ public void setYear(XMLGregorianCalendar value) { this.year = value; } /** * Gets the value of the license property. * * @return * possible object is * {@link String } * */ public String getLicense() { return license; } /** * Sets the value of the license property. * * @param value * allowed object is * {@link String } * */ public void setLicense(String value) { this.license = value; } /** * Gets the value of the author property. * * @return * possible object is * {@link String } * */ public String getAuthor() { return author; } /** * Sets the value of the author property. * * @param value * allowed object is * {@link String } * */ public void setAuthor(String value) { this.author = value; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/data/gpx/gpx11/ExtensionsType.java0000644000175000017500000000611212122526606030556 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ // // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.3 in JDK 1.6 // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. // Generated on: 2009.08.04 at 03:45:03 PM MESZ // package mobac.data.gpx.gpx11; import java.util.ArrayList; import java.util.List; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAnyElement; import javax.xml.bind.annotation.XmlType; import org.w3c.dom.Element; /** * * You can add extend GPX by adding your own elements from another schema here. * * *

Java class for extensionsType complex type. * *

The following schema fragment specifies the expected content contained within this class. * *

 * <complexType name="extensionsType">
 *   <complexContent>
 *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       <sequence>
 *         <any/>
 *       </sequence>
 *     </restriction>
 *   </complexContent>
 * </complexType>
 * 
* * */ @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "extensionsType", propOrder = { "any" }) public class ExtensionsType { @XmlAnyElement(lax = true) protected List any; /** * Gets the value of the any property. * *

* This accessor method returns a reference to the live list, * not a snapshot. Therefore any modification you make to the * returned list will be present inside the JAXB object. * This is why there is not a set method for the any property. * *

* For example, to add a new item, do as follows: *

     *    getAny().add(newItem);
     * 
* * *

* Objects of the following type(s) are allowed in the list * {@link Object } * {@link Element } * * */ public List getAny() { if (any == null) { any = new ArrayList(); } return this.any; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/data/gpx/gpx11/package-info.java0000644000175000017500000000327412122526606030107 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ // // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.3 in JDK 1.6 // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. // Generated on: 2009.08.04 at 03:45:03 PM MESZ // @javax.xml.bind.annotation.XmlSchema(namespace = "http://www.topografix.com/GPX/1/1", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED) @XmlJavaTypeAdapters({ @XmlJavaTypeAdapter(value = BigDecimalAdapter.class, type = BigDecimal.class) }) package mobac.data.gpx.gpx11; import java.math.BigDecimal; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters; import mobac.program.jaxb.BigDecimalAdapter; mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/data/gpx/gpx11/PersonType.java0000644000175000017500000000746212122526606027676 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ // // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.3 in JDK 1.6 // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. // Generated on: 2009.08.04 at 03:45:03 PM MESZ // package mobac.data.gpx.gpx11; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlType; /** * * A person or organization. * * *

Java class for personType complex type. * *

The following schema fragment specifies the expected content contained within this class. * *

 * <complexType name="personType">
 *   <complexContent>
 *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       <sequence>
 *         <element name="name" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
 *         <element name="email" type="{http://www.topografix.com/GPX/1/1}emailType" minOccurs="0"/>
 *         <element name="link" type="{http://www.topografix.com/GPX/1/1}linkType" minOccurs="0"/>
 *       </sequence>
 *     </restriction>
 *   </complexContent>
 * </complexType>
 * 
* * */ @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "personType", propOrder = { "name", "email", "link" }) public class PersonType { protected String name; protected EmailType email; protected LinkType link; /** * Gets the value of the name property. * * @return * possible object is * {@link String } * */ public String getName() { return name; } /** * Sets the value of the name property. * * @param value * allowed object is * {@link String } * */ public void setName(String value) { this.name = value; } /** * Gets the value of the email property. * * @return * possible object is * {@link EmailType } * */ public EmailType getEmail() { return email; } /** * Sets the value of the email property. * * @param value * allowed object is * {@link EmailType } * */ public void setEmail(EmailType value) { this.email = value; } /** * Gets the value of the link property. * * @return * possible object is * {@link LinkType } * */ public LinkType getLink() { return link; } /** * Sets the value of the link property. * * @param value * allowed object is * {@link LinkType } * */ public void setLink(LinkType value) { this.link = value; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/data/gpx/gpx11/MetadataType.java0000644000175000017500000002053212122526606030141 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ // // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.3 in JDK 1.6 // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. // Generated on: 2009.08.04 at 03:45:03 PM MESZ // package mobac.data.gpx.gpx11; import java.util.ArrayList; import java.util.List; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlType; import javax.xml.datatype.XMLGregorianCalendar; /** * * Information about the GPX file, author, and copyright restrictions goes in the metadata section. Providing rich, * meaningful information about your GPX files allows others to search for and use your GPS data. * * *

Java class for metadataType complex type. * *

The following schema fragment specifies the expected content contained within this class. * *

 * <complexType name="metadataType">
 *   <complexContent>
 *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       <sequence>
 *         <element name="name" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
 *         <element name="desc" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
 *         <element name="author" type="{http://www.topografix.com/GPX/1/1}personType" minOccurs="0"/>
 *         <element name="copyright" type="{http://www.topografix.com/GPX/1/1}copyrightType" minOccurs="0"/>
 *         <element name="link" type="{http://www.topografix.com/GPX/1/1}linkType" maxOccurs="unbounded" minOccurs="0"/>
 *         <element name="time" type="{http://www.w3.org/2001/XMLSchema}dateTime" minOccurs="0"/>
 *         <element name="keywords" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
 *         <element name="bounds" type="{http://www.topografix.com/GPX/1/1}boundsType" minOccurs="0"/>
 *         <element name="extensions" type="{http://www.topografix.com/GPX/1/1}extensionsType" minOccurs="0"/>
 *       </sequence>
 *     </restriction>
 *   </complexContent>
 * </complexType>
 * 
* * */ @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "metadataType", propOrder = { "name", "desc", "author", "copyright", "link", "time", "keywords", "bounds", "extensions" }) public class MetadataType { protected String name; protected String desc; protected PersonType author; protected CopyrightType copyright; protected List link; protected XMLGregorianCalendar time; protected String keywords; protected BoundsType bounds; protected ExtensionsType extensions; /** * Gets the value of the name property. * * @return * possible object is * {@link String } * */ public String getName() { return name; } /** * Sets the value of the name property. * * @param value * allowed object is * {@link String } * */ public void setName(String value) { this.name = value; } /** * Gets the value of the desc property. * * @return * possible object is * {@link String } * */ public String getDesc() { return desc; } /** * Sets the value of the desc property. * * @param value * allowed object is * {@link String } * */ public void setDesc(String value) { this.desc = value; } /** * Gets the value of the author property. * * @return * possible object is * {@link PersonType } * */ public PersonType getAuthor() { return author; } /** * Sets the value of the author property. * * @param value * allowed object is * {@link PersonType } * */ public void setAuthor(PersonType value) { this.author = value; } /** * Gets the value of the copyright property. * * @return * possible object is * {@link CopyrightType } * */ public CopyrightType getCopyright() { return copyright; } /** * Sets the value of the copyright property. * * @param value * allowed object is * {@link CopyrightType } * */ public void setCopyright(CopyrightType value) { this.copyright = value; } /** * Gets the value of the link property. * *

* This accessor method returns a reference to the live list, * not a snapshot. Therefore any modification you make to the * returned list will be present inside the JAXB object. * This is why there is not a set method for the link property. * *

* For example, to add a new item, do as follows: *

     *    getLink().add(newItem);
     * 
* * *

* Objects of the following type(s) are allowed in the list * {@link LinkType } * * */ public List getLink() { if (link == null) { link = new ArrayList(); } return this.link; } /** * Gets the value of the time property. * * @return * possible object is * {@link XMLGregorianCalendar } * */ public XMLGregorianCalendar getTime() { return time; } /** * Sets the value of the time property. * * @param value * allowed object is * {@link XMLGregorianCalendar } * */ public void setTime(XMLGregorianCalendar value) { this.time = value; } /** * Gets the value of the keywords property. * * @return * possible object is * {@link String } * */ public String getKeywords() { return keywords; } /** * Sets the value of the keywords property. * * @param value * allowed object is * {@link String } * */ public void setKeywords(String value) { this.keywords = value; } /** * Gets the value of the bounds property. * * @return * possible object is * {@link BoundsType } * */ public BoundsType getBounds() { return bounds; } /** * Sets the value of the bounds property. * * @param value * allowed object is * {@link BoundsType } * */ public void setBounds(BoundsType value) { this.bounds = value; } /** * Gets the value of the extensions property. * * @return * possible object is * {@link ExtensionsType } * */ public ExtensionsType getExtensions() { return extensions; } /** * Sets the value of the extensions property. * * @param value * allowed object is * {@link ExtensionsType } * */ public void setExtensions(ExtensionsType value) { this.extensions = value; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/data/gpx/gpx11/PtType.java0000644000175000017500000001102012122526606026774 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ // // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.3 in JDK 1.6 // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. // Generated on: 2009.08.04 at 03:45:03 PM MESZ // package mobac.data.gpx.gpx11; import java.math.BigDecimal; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlType; import javax.xml.datatype.XMLGregorianCalendar; import mobac.data.gpx.interfaces.GpxPoint; /** * * A geographic point with optional elevation and time. Available for use by * other schemas. * * *

* Java class for ptType complex type. * *

* The following schema fragment specifies the expected content contained within * this class. * *

 * <complexType name="ptType">
 *   <complexContent>
 *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       <sequence>
 *         <element name="ele" type="{http://www.w3.org/2001/XMLSchema}decimal" minOccurs="0"/>
 *         <element name="time" type="{http://www.w3.org/2001/XMLSchema}dateTime" minOccurs="0"/>
 *       </sequence>
 *       <attribute name="lat" use="required" type="{http://www.topografix.com/GPX/1/1}latitudeType" />
 *       <attribute name="lon" use="required" type="{http://www.topografix.com/GPX/1/1}longitudeType" />
 *     </restriction>
 *   </complexContent>
 * </complexType>
 * 
* * */ @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "ptType", propOrder = { "ele", "time" }) public class PtType implements GpxPoint { protected BigDecimal ele; protected XMLGregorianCalendar time; @XmlAttribute(required = true) protected BigDecimal lat; @XmlAttribute(required = true) protected BigDecimal lon; /** * Gets the value of the ele property. * * @return possible object is {@link BigDecimal } * */ public BigDecimal getEle() { return ele; } /** * Sets the value of the ele property. * * @param value * allowed object is {@link BigDecimal } * */ public void setEle(BigDecimal value) { this.ele = value; } /** * Gets the value of the time property. * * @return possible object is {@link XMLGregorianCalendar } * */ public XMLGregorianCalendar getTime() { return time; } /** * Sets the value of the time property. * * @param value * allowed object is {@link XMLGregorianCalendar } * */ public void setTime(XMLGregorianCalendar value) { this.time = value; } /** * Gets the value of the lat property. * * @return possible object is {@link BigDecimal } * */ public BigDecimal getLat() { return lat; } /** * Sets the value of the lat property. * * @param value * allowed object is {@link BigDecimal } * */ public void setLat(BigDecimal value) { this.lat = value; } /** * Gets the value of the lon property. * * @return possible object is {@link BigDecimal } * */ public BigDecimal getLon() { return lon; } /** * Sets the value of the lon property. * * @param value * allowed object is {@link BigDecimal } * */ public void setLon(BigDecimal value) { this.lon = value; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/data/gpx/gpx11/EmailType.java0000644000175000017500000000641112122526606027450 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ // // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.3 in JDK 1.6 // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. // Generated on: 2009.08.04 at 03:45:03 PM MESZ // package mobac.data.gpx.gpx11; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlType; /** * * An email address. Broken into two parts (id and domain) to help prevent email harvesting. * * *

Java class for emailType complex type. * *

The following schema fragment specifies the expected content contained within this class. * *

 * <complexType name="emailType">
 *   <complexContent>
 *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       <attribute name="id" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
 *       <attribute name="domain" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
 *     </restriction>
 *   </complexContent>
 * </complexType>
 * 
* * */ @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "emailType") public class EmailType { @XmlAttribute(required = true) protected String id; @XmlAttribute(required = true) protected String domain; /** * Gets the value of the id property. * * @return * possible object is * {@link String } * */ public String getId() { return id; } /** * Sets the value of the id property. * * @param value * allowed object is * {@link String } * */ public void setId(String value) { this.id = value; } /** * Gets the value of the domain property. * * @return * possible object is * {@link String } * */ public String getDomain() { return domain; } /** * Sets the value of the domain property. * * @param value * allowed object is * {@link String } * */ public void setDomain(String value) { this.domain = value; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/data/gpx/gpx11/WptType.java0000644000175000017500000003441112122526606027174 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ // // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.3 in JDK 1.6 // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. // Generated on: 2009.08.04 at 03:45:03 PM MESZ // package mobac.data.gpx.gpx11; import java.math.BigDecimal; import java.math.BigInteger; import java.util.ArrayList; import java.util.List; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlSchemaType; import javax.xml.bind.annotation.XmlType; import javax.xml.datatype.XMLGregorianCalendar; import mobac.data.gpx.interfaces.GpxPoint; /** * * wpt represents a waypoint, point of interest, or named feature on a map. * * *

* Java class for wptType complex type. * *

* The following schema fragment specifies the expected content contained within * this class. * *

 * <complexType name="wptType">
 *   <complexContent>
 *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       <sequence>
 *         <element name="ele" type="{http://www.w3.org/2001/XMLSchema}decimal" minOccurs="0"/>
 *         <element name="time" type="{http://www.w3.org/2001/XMLSchema}dateTime" minOccurs="0"/>
 *         <element name="magvar" type="{http://www.topografix.com/GPX/1/1}degreesType" minOccurs="0"/>
 *         <element name="geoidheight" type="{http://www.w3.org/2001/XMLSchema}decimal" minOccurs="0"/>
 *         <element name="name" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
 *         <element name="cmt" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
 *         <element name="desc" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
 *         <element name="src" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
 *         <element name="link" type="{http://www.topografix.com/GPX/1/1}linkType" maxOccurs="unbounded" minOccurs="0"/>
 *         <element name="sym" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
 *         <element name="type" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
 *         <element name="fix" type="{http://www.topografix.com/GPX/1/1}fixType" minOccurs="0"/>
 *         <element name="sat" type="{http://www.w3.org/2001/XMLSchema}nonNegativeInteger" minOccurs="0"/>
 *         <element name="hdop" type="{http://www.w3.org/2001/XMLSchema}decimal" minOccurs="0"/>
 *         <element name="vdop" type="{http://www.w3.org/2001/XMLSchema}decimal" minOccurs="0"/>
 *         <element name="pdop" type="{http://www.w3.org/2001/XMLSchema}decimal" minOccurs="0"/>
 *         <element name="ageofdgpsdata" type="{http://www.w3.org/2001/XMLSchema}decimal" minOccurs="0"/>
 *         <element name="dgpsid" type="{http://www.topografix.com/GPX/1/1}dgpsStationType" minOccurs="0"/>
 *         <element name="extensions" type="{http://www.topografix.com/GPX/1/1}extensionsType" minOccurs="0"/>
 *       </sequence>
 *       <attribute name="lat" use="required" type="{http://www.topografix.com/GPX/1/1}latitudeType" />
 *       <attribute name="lon" use="required" type="{http://www.topografix.com/GPX/1/1}longitudeType" />
 *     </restriction>
 *   </complexContent>
 * </complexType>
 * 
* * */ @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "wptType", propOrder = { "ele", "time", "magvar", "geoidheight", "name", "cmt", "desc", "src", "link", "sym", "type", "fix", "sat", "hdop", "vdop", "pdop", "ageofdgpsdata", "dgpsid", "extensions" }) public class WptType implements GpxPoint { protected BigDecimal ele; protected XMLGregorianCalendar time; protected BigDecimal magvar; protected BigDecimal geoidheight; protected String name; protected String cmt; protected String desc; protected String src; protected List link; protected String sym; protected String type; protected String fix; @XmlSchemaType(name = "nonNegativeInteger") protected BigInteger sat; protected BigDecimal hdop; protected BigDecimal vdop; protected BigDecimal pdop; protected BigDecimal ageofdgpsdata; protected Integer dgpsid; protected ExtensionsType extensions; @XmlAttribute(required = true) protected BigDecimal lat; @XmlAttribute(required = true) protected BigDecimal lon; /** * Gets the value of the ele property. * * @return possible object is {@link BigDecimal } * */ public BigDecimal getEle() { return ele; } /** * Sets the value of the ele property. * * @param value * allowed object is {@link BigDecimal } * */ public void setEle(BigDecimal value) { this.ele = value; } /** * Gets the value of the time property. * * @return possible object is {@link XMLGregorianCalendar } * */ public XMLGregorianCalendar getTime() { return time; } /** * Sets the value of the time property. * * @param value * allowed object is {@link XMLGregorianCalendar } * */ public void setTime(XMLGregorianCalendar value) { this.time = value; } /** * Gets the value of the magvar property. * * @return possible object is {@link BigDecimal } * */ public BigDecimal getMagvar() { return magvar; } /** * Sets the value of the magvar property. * * @param value * allowed object is {@link BigDecimal } * */ public void setMagvar(BigDecimal value) { this.magvar = value; } /** * Gets the value of the geoidheight property. * * @return possible object is {@link BigDecimal } * */ public BigDecimal getGeoidheight() { return geoidheight; } /** * Sets the value of the geoidheight property. * * @param value * allowed object is {@link BigDecimal } * */ public void setGeoidheight(BigDecimal value) { this.geoidheight = value; } /** * Gets the value of the name property. * * @return possible object is {@link String } * */ public String getName() { return name; } /** * Sets the value of the name property. * * @param value * allowed object is {@link String } * */ public void setName(String value) { this.name = value; } /** * Gets the value of the cmt property. * * @return possible object is {@link String } * */ public String getCmt() { return cmt; } /** * Sets the value of the cmt property. * * @param value * allowed object is {@link String } * */ public void setCmt(String value) { this.cmt = value; } /** * Gets the value of the desc property. * * @return possible object is {@link String } * */ public String getDesc() { return desc; } /** * Sets the value of the desc property. * * @param value * allowed object is {@link String } * */ public void setDesc(String value) { this.desc = value; } /** * Gets the value of the src property. * * @return possible object is {@link String } * */ public String getSrc() { return src; } /** * Sets the value of the src property. * * @param value * allowed object is {@link String } * */ public void setSrc(String value) { this.src = value; } /** * Gets the value of the link property. * *

* This accessor method returns a reference to the live list, not a * snapshot. Therefore any modification you make to the returned list will * be present inside the JAXB object. This is why there is not a * set method for the link property. * *

* For example, to add a new item, do as follows: * *

	 * getLink().add(newItem);
	 * 
* * *

* Objects of the following type(s) are allowed in the list {@link LinkType } * * */ public List getLink() { if (link == null) { link = new ArrayList(); } return this.link; } /** * Gets the value of the sym property. * * @return possible object is {@link String } * */ public String getSym() { return sym; } /** * Sets the value of the sym property. * * @param value * allowed object is {@link String } * */ public void setSym(String value) { this.sym = value; } /** * Gets the value of the type property. * * @return possible object is {@link String } * */ public String getType() { return type; } /** * Sets the value of the type property. * * @param value * allowed object is {@link String } * */ public void setType(String value) { this.type = value; } /** * Gets the value of the fix property. * * @return possible object is {@link String } * */ public String getFix() { return fix; } /** * Sets the value of the fix property. * * @param value * allowed object is {@link String } * */ public void setFix(String value) { this.fix = value; } /** * Gets the value of the sat property. * * @return possible object is {@link BigInteger } * */ public BigInteger getSat() { return sat; } /** * Sets the value of the sat property. * * @param value * allowed object is {@link BigInteger } * */ public void setSat(BigInteger value) { this.sat = value; } /** * Gets the value of the hdop property. * * @return possible object is {@link BigDecimal } * */ public BigDecimal getHdop() { return hdop; } /** * Sets the value of the hdop property. * * @param value * allowed object is {@link BigDecimal } * */ public void setHdop(BigDecimal value) { this.hdop = value; } /** * Gets the value of the vdop property. * * @return possible object is {@link BigDecimal } * */ public BigDecimal getVdop() { return vdop; } /** * Sets the value of the vdop property. * * @param value * allowed object is {@link BigDecimal } * */ public void setVdop(BigDecimal value) { this.vdop = value; } /** * Gets the value of the pdop property. * * @return possible object is {@link BigDecimal } * */ public BigDecimal getPdop() { return pdop; } /** * Sets the value of the pdop property. * * @param value * allowed object is {@link BigDecimal } * */ public void setPdop(BigDecimal value) { this.pdop = value; } /** * Gets the value of the ageofdgpsdata property. * * @return possible object is {@link BigDecimal } * */ public BigDecimal getAgeofdgpsdata() { return ageofdgpsdata; } /** * Sets the value of the ageofdgpsdata property. * * @param value * allowed object is {@link BigDecimal } * */ public void setAgeofdgpsdata(BigDecimal value) { this.ageofdgpsdata = value; } /** * Gets the value of the dgpsid property. * * @return possible object is {@link Integer } * */ public Integer getDgpsid() { return dgpsid; } /** * Sets the value of the dgpsid property. * * @param value * allowed object is {@link Integer } * */ public void setDgpsid(Integer value) { this.dgpsid = value; } /** * Gets the value of the extensions property. * * @return possible object is {@link ExtensionsType } * */ public ExtensionsType getExtensions() { return extensions; } /** * Sets the value of the extensions property. * * @param value * allowed object is {@link ExtensionsType } * */ public void setExtensions(ExtensionsType value) { this.extensions = value; } /** * Gets the value of the lat property. * * @return possible object is {@link BigDecimal } * */ public BigDecimal getLat() { return lat; } /** * Sets the value of the lat property. * * @param value * allowed object is {@link BigDecimal } * */ public void setLat(BigDecimal value) { this.lat = value; } /** * Gets the value of the lon property. * * @return possible object is {@link BigDecimal } * */ public BigDecimal getLon() { return lon; } /** * Sets the value of the lon property. * * @param value * allowed object is {@link BigDecimal } * */ public void setLon(BigDecimal value) { this.lon = value; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/data/gpx/gpx11/Gpx.java0000644000175000017500000001711012122526606026313 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ // // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.3 in JDK 1.6 // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. // Generated on: 2009.08.04 at 03:45:03 PM MESZ // package mobac.data.gpx.gpx11; import java.util.ArrayList; import java.util.List; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; import mobac.program.ProgramInfo; /** * * GPX documents contain a metadata header, followed by waypoints, routes, and * tracks. You can add your own elements to the extensions section of the GPX * document. * * *

* Java class for anonymous complex type. * *

* The following schema fragment specifies the expected content contained within * this class. * *

 * <complexType>
 *   <complexContent>
 *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       <sequence>
 *         <element name="metadata" type="{http://www.topografix.com/GPX/1/1}metadataType" minOccurs="0"/>
 *         <element name="wpt" type="{http://www.topografix.com/GPX/1/1}wptType" maxOccurs="unbounded" minOccurs="0"/>
 *         <element name="rte" type="{http://www.topografix.com/GPX/1/1}rteType" maxOccurs="unbounded" minOccurs="0"/>
 *         <element name="trk" type="{http://www.topografix.com/GPX/1/1}trkType" maxOccurs="unbounded" minOccurs="0"/>
 *         <element name="extensions" type="{http://www.topografix.com/GPX/1/1}extensionsType" minOccurs="0"/>
 *       </sequence>
 *       <attribute name="version" use="required" type="{http://www.w3.org/2001/XMLSchema}string" fixed="1.1" />
 *       <attribute name="creator" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
 *     </restriction>
 *   </complexContent>
 * </complexType>
 * 
* * */ @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "", propOrder = { "metadata", "wpt", "rte", "trk", "extensions" }) @XmlRootElement(name = "gpx") public class Gpx { protected MetadataType metadata; protected List wpt; protected List rte; protected List trk; protected ExtensionsType extensions; @XmlAttribute(required = true) protected String version; @XmlAttribute(required = true) protected String creator; public static Gpx createGpx() { Gpx gpx = new Gpx(); gpx.setVersion("1.1"); gpx.setCreator(ProgramInfo.getVersionTitle()); return gpx; } protected Gpx() { } /** * Gets the value of the metadata property. * * @return possible object is {@link MetadataType } * */ public MetadataType getMetadata() { return metadata; } /** * Sets the value of the metadata property. * * @param value * allowed object is {@link MetadataType } * */ public void setMetadata(MetadataType value) { this.metadata = value; } /** * Gets the value of the wpt property. * *

* This accessor method returns a reference to the live list, not a * snapshot. Therefore any modification you make to the returned list will * be present inside the JAXB object. This is why there is not a * set method for the wpt property. * *

* For example, to add a new item, do as follows: * *

	 * getWpt().add(newItem);
	 * 
* * *

* Objects of the following type(s) are allowed in the list {@link WptType } * * */ public List getWpt() { if (wpt == null) { wpt = new ArrayList(); } return this.wpt; } /** * Gets the value of the rte property. * *

* This accessor method returns a reference to the live list, not a * snapshot. Therefore any modification you make to the returned list will * be present inside the JAXB object. This is why there is not a * set method for the rte property. * *

* For example, to add a new item, do as follows: * *

	 * getRte().add(newItem);
	 * 
* * *

* Objects of the following type(s) are allowed in the list {@link RteType } * * */ public List getRte() { if (rte == null) { rte = new ArrayList(); } return this.rte; } /** * Gets the value of the trk property. * *

* This accessor method returns a reference to the live list, not a * snapshot. Therefore any modification you make to the returned list will * be present inside the JAXB object. This is why there is not a * set method for the trk property. * *

* For example, to add a new item, do as follows: * *

	 * getTrk().add(newItem);
	 * 
* * *

* Objects of the following type(s) are allowed in the list {@link TrkType } * * */ public List getTrk() { if (trk == null) { trk = new ArrayList(); } return this.trk; } /** * Gets the value of the extensions property. * * @return possible object is {@link ExtensionsType } * */ public ExtensionsType getExtensions() { return extensions; } /** * Sets the value of the extensions property. * * @param value * allowed object is {@link ExtensionsType } * */ public void setExtensions(ExtensionsType value) { this.extensions = value; } /** * Gets the value of the version property. * * @return possible object is {@link String } * */ public String getVersion() { if (version == null) { return "1.1"; } else { return version; } } /** * Sets the value of the version property. * * @param value * allowed object is {@link String } * */ public void setVersion(String value) { this.version = value; } /** * Gets the value of the creator property. * * @return possible object is {@link String } * */ public String getCreator() { return creator; } /** * Sets the value of the creator property. * * @param value * allowed object is {@link String } * */ public void setCreator(String value) { this.creator = value; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/data/gpx/gpx11/LinkType.java0000644000175000017500000000775512122526606027332 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ // // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.3 in JDK 1.6 // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. // Generated on: 2009.08.04 at 03:45:03 PM MESZ // package mobac.data.gpx.gpx11; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlSchemaType; import javax.xml.bind.annotation.XmlType; /** * * A link to an external resource (Web page, digital photo, video clip, etc) with additional information. * * *

Java class for linkType complex type. * *

The following schema fragment specifies the expected content contained within this class. * *

 * <complexType name="linkType">
 *   <complexContent>
 *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       <sequence>
 *         <element name="text" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
 *         <element name="type" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
 *       </sequence>
 *       <attribute name="href" use="required" type="{http://www.w3.org/2001/XMLSchema}anyURI" />
 *     </restriction>
 *   </complexContent>
 * </complexType>
 * 
* * */ @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "linkType", propOrder = { "text", "type" }) public class LinkType { protected String text; protected String type; @XmlAttribute(required = true) @XmlSchemaType(name = "anyURI") protected String href; /** * Gets the value of the text property. * * @return * possible object is * {@link String } * */ public String getText() { return text; } /** * Sets the value of the text property. * * @param value * allowed object is * {@link String } * */ public void setText(String value) { this.text = value; } /** * Gets the value of the type property. * * @return * possible object is * {@link String } * */ public String getType() { return type; } /** * Sets the value of the type property. * * @param value * allowed object is * {@link String } * */ public void setType(String value) { this.type = value; } /** * Gets the value of the href property. * * @return * possible object is * {@link String } * */ public String getHref() { return href; } /** * Sets the value of the href property. * * @param value * allowed object is * {@link String } * */ public void setHref(String value) { this.href = value; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/data/gpx/gpx11/TrkType.java0000644000175000017500000002063012122526606027160 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ // // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.3 in JDK 1.6 // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. // Generated on: 2009.08.04 at 03:45:03 PM MESZ // package mobac.data.gpx.gpx11; import java.math.BigInteger; import java.util.ArrayList; import java.util.List; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlSchemaType; import javax.xml.bind.annotation.XmlType; /** * * trk represents a track - an ordered list of points describing a path. * * *

Java class for trkType complex type. * *

The following schema fragment specifies the expected content contained within this class. * *

 * <complexType name="trkType">
 *   <complexContent>
 *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       <sequence>
 *         <element name="name" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
 *         <element name="cmt" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
 *         <element name="desc" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
 *         <element name="src" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
 *         <element name="link" type="{http://www.topografix.com/GPX/1/1}linkType" maxOccurs="unbounded" minOccurs="0"/>
 *         <element name="number" type="{http://www.w3.org/2001/XMLSchema}nonNegativeInteger" minOccurs="0"/>
 *         <element name="type" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
 *         <element name="extensions" type="{http://www.topografix.com/GPX/1/1}extensionsType" minOccurs="0"/>
 *         <element name="trkseg" type="{http://www.topografix.com/GPX/1/1}trksegType" maxOccurs="unbounded" minOccurs="0"/>
 *       </sequence>
 *     </restriction>
 *   </complexContent>
 * </complexType>
 * 
* * */ @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "trkType", propOrder = { "name", "cmt", "desc", "src", "link", "number", "type", "extensions", "trkseg" }) public class TrkType { protected String name; protected String cmt; protected String desc; protected String src; protected List link; @XmlSchemaType(name = "nonNegativeInteger") protected BigInteger number; protected String type; protected ExtensionsType extensions; protected List trkseg; /** * Gets the value of the name property. * * @return * possible object is * {@link String } * */ public String getName() { return name; } /** * Sets the value of the name property. * * @param value * allowed object is * {@link String } * */ public void setName(String value) { this.name = value; } /** * Gets the value of the cmt property. * * @return * possible object is * {@link String } * */ public String getCmt() { return cmt; } /** * Sets the value of the cmt property. * * @param value * allowed object is * {@link String } * */ public void setCmt(String value) { this.cmt = value; } /** * Gets the value of the desc property. * * @return * possible object is * {@link String } * */ public String getDesc() { return desc; } /** * Sets the value of the desc property. * * @param value * allowed object is * {@link String } * */ public void setDesc(String value) { this.desc = value; } /** * Gets the value of the src property. * * @return * possible object is * {@link String } * */ public String getSrc() { return src; } /** * Sets the value of the src property. * * @param value * allowed object is * {@link String } * */ public void setSrc(String value) { this.src = value; } /** * Gets the value of the link property. * *

* This accessor method returns a reference to the live list, * not a snapshot. Therefore any modification you make to the * returned list will be present inside the JAXB object. * This is why there is not a set method for the link property. * *

* For example, to add a new item, do as follows: *

     *    getLink().add(newItem);
     * 
* * *

* Objects of the following type(s) are allowed in the list * {@link LinkType } * * */ public List getLink() { if (link == null) { link = new ArrayList(); } return this.link; } /** * Gets the value of the number property. * * @return * possible object is * {@link BigInteger } * */ public BigInteger getNumber() { return number; } /** * Sets the value of the number property. * * @param value * allowed object is * {@link BigInteger } * */ public void setNumber(BigInteger value) { this.number = value; } /** * Gets the value of the type property. * * @return * possible object is * {@link String } * */ public String getType() { return type; } /** * Sets the value of the type property. * * @param value * allowed object is * {@link String } * */ public void setType(String value) { this.type = value; } /** * Gets the value of the extensions property. * * @return * possible object is * {@link ExtensionsType } * */ public ExtensionsType getExtensions() { return extensions; } /** * Sets the value of the extensions property. * * @param value * allowed object is * {@link ExtensionsType } * */ public void setExtensions(ExtensionsType value) { this.extensions = value; } /** * Gets the value of the trkseg property. * *

* This accessor method returns a reference to the live list, * not a snapshot. Therefore any modification you make to the * returned list will be present inside the JAXB object. * This is why there is not a set method for the trkseg property. * *

* For example, to add a new item, do as follows: *

     *    getTrkseg().add(newItem);
     * 
* * *

* Objects of the following type(s) are allowed in the list * {@link TrksegType } * * */ public List getTrkseg() { if (trkseg == null) { trkseg = new ArrayList(); } return this.trkseg; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/data/gpx/gpx11/PtsegType.java0000644000175000017500000000577612122526606027520 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ // // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.3 in JDK 1.6 // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. // Generated on: 2009.08.04 at 03:45:03 PM MESZ // package mobac.data.gpx.gpx11; import java.util.ArrayList; import java.util.List; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlType; /** * * An ordered sequence of points. (for polygons or polylines, e.g.) * * *

Java class for ptsegType complex type. * *

The following schema fragment specifies the expected content contained within this class. * *

 * <complexType name="ptsegType">
 *   <complexContent>
 *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       <sequence>
 *         <element name="pt" type="{http://www.topografix.com/GPX/1/1}ptType" maxOccurs="unbounded" minOccurs="0"/>
 *       </sequence>
 *     </restriction>
 *   </complexContent>
 * </complexType>
 * 
* * */ @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "ptsegType", propOrder = { "pt" }) public class PtsegType { protected List pt; /** * Gets the value of the pt property. * *

* This accessor method returns a reference to the live list, * not a snapshot. Therefore any modification you make to the * returned list will be present inside the JAXB object. * This is why there is not a set method for the pt property. * *

* For example, to add a new item, do as follows: *

     *    getPt().add(newItem);
     * 
* * *

* Objects of the following type(s) are allowed in the list * {@link PtType } * * */ public List getPt() { if (pt == null) { pt = new ArrayList(); } return this.pt; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/data/gpx/gpx11/BoundsType.java0000644000175000017500000001010112122526606027642 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.data.gpx.gpx11; import java.math.BigDecimal; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlType; /** * * Two lat/lon pairs defining the extent of an element. * * *

* Java class for boundsType complex type. * *

* The following schema fragment specifies the expected content contained within * this class. * *

 * <complexType name="boundsType">
 *   <complexContent>
 *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       <attribute name="minlat" use="required" type="{http://www.topografix.com/GPX/1/1}latitudeType" />
 *       <attribute name="minlon" use="required" type="{http://www.topografix.com/GPX/1/1}longitudeType" />
 *       <attribute name="maxlat" use="required" type="{http://www.topografix.com/GPX/1/1}latitudeType" />
 *       <attribute name="maxlon" use="required" type="{http://www.topografix.com/GPX/1/1}longitudeType" />
 *     </restriction>
 *   </complexContent>
 * </complexType>
 * 
* * */ @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "boundsType") public class BoundsType { @XmlAttribute(required = true) protected BigDecimal minlat; @XmlAttribute(required = true) protected BigDecimal minlon; @XmlAttribute(required = true) protected BigDecimal maxlat; @XmlAttribute(required = true) protected BigDecimal maxlon; /** * Gets the value of the minlat property. * * @return possible object is {@link BigDecimal } * */ public BigDecimal getMinlat() { return minlat; } /** * Sets the value of the minlat property. * * @param value * allowed object is {@link BigDecimal } * */ public void setMinlat(BigDecimal value) { this.minlat = value; } /** * Gets the value of the minlon property. * * @return possible object is {@link BigDecimal } * */ public BigDecimal getMinlon() { return minlon; } /** * Sets the value of the minlon property. * * @param value * allowed object is {@link BigDecimal } * */ public void setMinlon(BigDecimal value) { this.minlon = value; } /** * Gets the value of the maxlat property. * * @return possible object is {@link BigDecimal } * */ public BigDecimal getMaxlat() { return maxlat; } /** * Sets the value of the maxlat property. * * @param value * allowed object is {@link BigDecimal } * */ public void setMaxlat(BigDecimal value) { this.maxlat = value; } /** * Gets the value of the maxlon property. * * @return possible object is {@link BigDecimal } * */ public BigDecimal getMaxlon() { return maxlon; } /** * Sets the value of the maxlon property. * * @param value * allowed object is {@link BigDecimal } * */ public void setMaxlon(BigDecimal value) { this.maxlon = value; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/data/gpx/gpx11/RteType.java0000644000175000017500000002065412122526606027160 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ // // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.3 in JDK 1.6 // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. // Generated on: 2009.08.04 at 03:45:03 PM MESZ // package mobac.data.gpx.gpx11; import java.math.BigInteger; import java.util.ArrayList; import java.util.List; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlSchemaType; import javax.xml.bind.annotation.XmlType; /** * * rte represents route - an ordered list of waypoints representing a series of turn points leading to a destination. * * *

Java class for rteType complex type. * *

The following schema fragment specifies the expected content contained within this class. * *

 * <complexType name="rteType">
 *   <complexContent>
 *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       <sequence>
 *         <element name="name" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
 *         <element name="cmt" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
 *         <element name="desc" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
 *         <element name="src" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
 *         <element name="link" type="{http://www.topografix.com/GPX/1/1}linkType" maxOccurs="unbounded" minOccurs="0"/>
 *         <element name="number" type="{http://www.w3.org/2001/XMLSchema}nonNegativeInteger" minOccurs="0"/>
 *         <element name="type" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
 *         <element name="extensions" type="{http://www.topografix.com/GPX/1/1}extensionsType" minOccurs="0"/>
 *         <element name="rtept" type="{http://www.topografix.com/GPX/1/1}wptType" maxOccurs="unbounded" minOccurs="0"/>
 *       </sequence>
 *     </restriction>
 *   </complexContent>
 * </complexType>
 * 
* * */ @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "rteType", propOrder = { "name", "cmt", "desc", "src", "link", "number", "type", "extensions", "rtept" }) public class RteType { protected String name; protected String cmt; protected String desc; protected String src; protected List link; @XmlSchemaType(name = "nonNegativeInteger") protected BigInteger number; protected String type; protected ExtensionsType extensions; protected List rtept; /** * Gets the value of the name property. * * @return * possible object is * {@link String } * */ public String getName() { return name; } /** * Sets the value of the name property. * * @param value * allowed object is * {@link String } * */ public void setName(String value) { this.name = value; } /** * Gets the value of the cmt property. * * @return * possible object is * {@link String } * */ public String getCmt() { return cmt; } /** * Sets the value of the cmt property. * * @param value * allowed object is * {@link String } * */ public void setCmt(String value) { this.cmt = value; } /** * Gets the value of the desc property. * * @return * possible object is * {@link String } * */ public String getDesc() { return desc; } /** * Sets the value of the desc property. * * @param value * allowed object is * {@link String } * */ public void setDesc(String value) { this.desc = value; } /** * Gets the value of the src property. * * @return * possible object is * {@link String } * */ public String getSrc() { return src; } /** * Sets the value of the src property. * * @param value * allowed object is * {@link String } * */ public void setSrc(String value) { this.src = value; } /** * Gets the value of the link property. * *

* This accessor method returns a reference to the live list, * not a snapshot. Therefore any modification you make to the * returned list will be present inside the JAXB object. * This is why there is not a set method for the link property. * *

* For example, to add a new item, do as follows: *

     *    getLink().add(newItem);
     * 
* * *

* Objects of the following type(s) are allowed in the list * {@link LinkType } * * */ public List getLink() { if (link == null) { link = new ArrayList(); } return this.link; } /** * Gets the value of the number property. * * @return * possible object is * {@link BigInteger } * */ public BigInteger getNumber() { return number; } /** * Sets the value of the number property. * * @param value * allowed object is * {@link BigInteger } * */ public void setNumber(BigInteger value) { this.number = value; } /** * Gets the value of the type property. * * @return * possible object is * {@link String } * */ public String getType() { return type; } /** * Sets the value of the type property. * * @param value * allowed object is * {@link String } * */ public void setType(String value) { this.type = value; } /** * Gets the value of the extensions property. * * @return * possible object is * {@link ExtensionsType } * */ public ExtensionsType getExtensions() { return extensions; } /** * Sets the value of the extensions property. * * @param value * allowed object is * {@link ExtensionsType } * */ public void setExtensions(ExtensionsType value) { this.extensions = value; } /** * Gets the value of the rtept property. * *

* This accessor method returns a reference to the live list, * not a snapshot. Therefore any modification you make to the * returned list will be present inside the JAXB object. * This is why there is not a set method for the rtept property. * *

* For example, to add a new item, do as follows: *

     *    getRtept().add(newItem);
     * 
* * *

* Objects of the following type(s) are allowed in the list * {@link WptType } * * */ public List getRtept() { if (rtept == null) { rtept = new ArrayList(); } return this.rtept; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/data/gpx/gpx11/TrksegType.java0000644000175000017500000000764112122526606027666 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ // // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.3 in JDK 1.6 // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. // Generated on: 2009.08.04 at 03:45:03 PM MESZ // package mobac.data.gpx.gpx11; import java.util.ArrayList; import java.util.List; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlType; /** * * A Track Segment holds a list of Track Points which are logically connected in order. To represent a single GPS track where GPS reception was lost, or the GPS receiver was turned off, start a new Track Segment for each continuous span of track data. * * *

Java class for trksegType complex type. * *

The following schema fragment specifies the expected content contained within this class. * *

 * <complexType name="trksegType">
 *   <complexContent>
 *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       <sequence>
 *         <element name="trkpt" type="{http://www.topografix.com/GPX/1/1}wptType" maxOccurs="unbounded" minOccurs="0"/>
 *         <element name="extensions" type="{http://www.topografix.com/GPX/1/1}extensionsType" minOccurs="0"/>
 *       </sequence>
 *     </restriction>
 *   </complexContent>
 * </complexType>
 * 
* * */ @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "trksegType", propOrder = { "trkpt", "extensions" }) public class TrksegType { protected List trkpt; protected ExtensionsType extensions; /** * Gets the value of the trkpt property. * *

* This accessor method returns a reference to the live list, * not a snapshot. Therefore any modification you make to the * returned list will be present inside the JAXB object. * This is why there is not a set method for the trkpt property. * *

* For example, to add a new item, do as follows: *

     *    getTrkpt().add(newItem);
     * 
* * *

* Objects of the following type(s) are allowed in the list * {@link WptType } * * */ public List getTrkpt() { if (trkpt == null) { trkpt = new ArrayList(); } return this.trkpt; } /** * Gets the value of the extensions property. * * @return * possible object is * {@link ExtensionsType } * */ public ExtensionsType getExtensions() { return extensions; } /** * Sets the value of the extensions property. * * @param value * allowed object is * {@link ExtensionsType } * */ public void setExtensions(ExtensionsType value) { this.extensions = value; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/data/gpx/interfaces/0000755000175000017500000000000012122526606026075 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/data/gpx/interfaces/GpxPoint.java0000644000175000017500000000204612122526606030512 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.data.gpx.interfaces; import java.math.BigDecimal; public interface GpxPoint { public BigDecimal getLat(); public BigDecimal getLon(); public BigDecimal getEle(); } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/Main.java0000644000175000017500000000650312134265562024002 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac; import javax.imageio.ImageIO; import javax.swing.SwingUtilities; import javax.swing.UIManager; import mobac.gui.MainGUI; import mobac.gui.SplashFrame; import mobac.mapsources.DefaultMapSourcesManager; import mobac.program.DirectoryManager; import mobac.program.EnvironmentSetup; import mobac.program.Logging; import mobac.program.ProgramInfo; import mobac.program.commandline.CommandLineEmpty; import mobac.program.commandline.CreateAtlas; import mobac.program.interfaces.CommandLineAction; import mobac.program.model.Settings; import mobac.program.tilestore.TileStore; import mobac.utilities.GUIExceptionHandler; /** * Java 6 version of the main starter class */ public class Main { protected CommandLineAction cmdAction = new CommandLineEmpty(); public Main() { try { parseCommandLine(); if (cmdAction.showSplashScreen()) SplashFrame.showFrame(); DirectoryManager.initialize(); Logging.configureLogging(); // MySocketImplFactory.install(); ProgramInfo.initialize(); // Load revision info Logging.logSystemInfo(); GUIExceptionHandler.installToolkitEventQueueProxy(); // Logging.logSystemProperties(); ImageIO.setUseCache(false); EnvironmentSetup.checkFileSetup(); Settings.loadOrQuit(); EnvironmentSetup.checkMemory(); EnvironmentSetup.copyMapPacks(); DefaultMapSourcesManager.initialize(); EnvironmentSetup.createDefaultAtlases(); TileStore.initialize(); EnvironmentSetup.upgrade(); cmdAction.runBeforeMainGUI(); if (cmdAction.showMainGUI()) { SwingUtilities.invokeLater(new Runnable() { public void run() { Logging.LOG.debug("Starting GUI"); MainGUI.createMainGui(); SplashFrame.hideFrame(); cmdAction.runMainGUI(); } }); } } catch (Throwable t) { GUIExceptionHandler.processException(t); System.exit(1); } } protected void parseCommandLine() { String[] args = StartMOBAC.ARGS; if (args.length >= 2) { if ("create".equalsIgnoreCase(args[0])) { if (args.length > 2) cmdAction = new CreateAtlas(args[1], args[2]); else cmdAction = new CreateAtlas(args[1]); return; } } } /** * Start MOBAC without Java Runtime version check */ public static void main(String[] args) { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); new Main(); } catch (Throwable t) { GUIExceptionHandler.processException(t); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/0000755000175000017500000000000012127544346024432 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/custom/0000755000175000017500000000000012127544346025744 5ustar paulliupaulliu././@LongLink0000000000000000000000000000015100000000000011562 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/custom/CustomLocalTileZipMapSource.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/custom/CustomLocalTileZipMapSource.0000644000175000017500000002207712127544346033322 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.custom; import java.awt.Color; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.Enumeration; import java.util.LinkedList; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import javax.imageio.ImageIO; import javax.swing.JOptionPane; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlTransient; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import mobac.exceptions.TileException; import mobac.gui.mapview.PreviewMap; import mobac.mapsources.MapSourceTools; import mobac.mapsources.mapspace.MapSpaceFactory; import mobac.program.Logging; import mobac.program.interfaces.FileBasedMapSource; import mobac.program.interfaces.MapSpace; import mobac.program.jaxb.ColorAdapter; import mobac.program.model.MapSourceLoaderInfo; import mobac.program.model.TileImageType; import mobac.utilities.I18nUtils; import mobac.utilities.Utilities; import org.apache.log4j.Logger; @XmlRootElement(name = "localTileZip") public class CustomLocalTileZipMapSource implements FileBasedMapSource { private static final Logger log = Logger.getLogger(CustomLocalTileZipMapSource.class); private MapSourceLoaderInfo loaderInfo = null; private MapSpace mapSpace = MapSpaceFactory.getInstance(256, true); private boolean initialized = false; private String fileSyntax = null; private TileImageType tileImageType = null; @XmlElement(nillable = false, defaultValue = "CustomLocal") private String name = "Custom"; private int minZoom = PreviewMap.MIN_ZOOM; private int maxZoom = PreviewMap.MAX_ZOOM; @XmlElement(name = "zipFile", required = true) private File[] zipFiles = new File[] {}; @XmlElement() private CustomMapSourceType sourceType = CustomMapSourceType.DIR_ZOOM_X_Y; @XmlElement(defaultValue = "false") private boolean invertYCoordinate = false; private LinkedList zips = new LinkedList(); @XmlElement(defaultValue = "#000000") @XmlJavaTypeAdapter(ColorAdapter.class) private Color backgroundColor = Color.BLACK; public CustomLocalTileZipMapSource() { super(); } protected synchronized void openZipFile() { for (File zipFile : zipFiles) { if (!zipFile.isFile()) { JOptionPane.showMessageDialog(null, String.format(I18nUtils.localizedStringForKey("msg_custom_map_invalid_source_zip_title"), name, zipFile.toString()), I18nUtils.localizedStringForKey("msg_custom_map_invalid_source_zip_title"), JOptionPane.ERROR_MESSAGE); } else { try { Logging.LOG.debug("Opening zip file " + zipFile.getAbsolutePath()); zips.add(new ZipFile(zipFile)); Logging.LOG.debug("Zip file open completed"); } catch (Exception e) { JOptionPane.showMessageDialog(null, String.format(I18nUtils.localizedStringForKey("msg_custom_map_failed_open_source_zip"), name, zipFile.toString()), I18nUtils.localizedStringForKey("msg_custom_map_failed_open_source_zip_title"), JOptionPane.ERROR_MESSAGE); } } } } public synchronized void initialize() { if (initialized) return; reinitialize(); } public void reinitialize() { try { openZipFile(); if (zips.size() == 0) return; switch (sourceType) { case DIR_ZOOM_X_Y: case DIR_ZOOM_Y_X: initializeDirType(); break; case QUADKEY: initializeQuadKeyType(); break; default: throw new RuntimeException("Invalid source type"); } } finally { initialized = true; } } public synchronized void initializeDirType() { int min = PreviewMap.MAX_ZOOM; int max = PreviewMap.MIN_ZOOM; for (ZipFile zip : zips) { for (int z = PreviewMap.MAX_ZOOM; z > PreviewMap.MIN_ZOOM; z--) { ZipEntry entry = zip.getEntry(Integer.toString(z) + "/"); if (entry != null) { max = Math.max(max, z); break; } } for (int z = PreviewMap.MIN_ZOOM; z < PreviewMap.MAX_ZOOM; z++) { ZipEntry entry = zip.getEntry(Integer.toString(z) + "/"); if (entry != null) { min = Math.min(min, z); break; } } } minZoom = min; maxZoom = max; Enumeration entries = zips.get(0).entries(); String syntax = "%d/%d/%d"; while (entries.hasMoreElements()) { ZipEntry entry = entries.nextElement(); if (entry.isDirectory()) continue; String name = entry.getName(); int i = name.lastIndexOf("/"); name = name.substring(i + 1); String[] parts = name.split("\\."); if (parts.length < 2 || parts.length > 3) break; syntax += "." + parts[1]; tileImageType = TileImageType.getTileImageType(parts[1]); if (parts.length == 3) syntax += "." + parts[2]; fileSyntax = syntax; log.debug("Detected file syntax: " + fileSyntax + " tileImageType=" + tileImageType); break; } } public synchronized void initializeQuadKeyType() { Pattern p = Pattern.compile("([0123]+)\\.(png|gif|jpg)", Pattern.CASE_INSENSITIVE); Enumeration entries = zips.get(0).entries(); String fileExt = null; while (entries.hasMoreElements()) { ZipEntry entry = entries.nextElement(); Matcher m = p.matcher(entry.getName()); if (!m.matches()) continue; fileExt = m.group(2); break; } if (fileExt == null) return; // Error no suitable file found fileSyntax = "%s." + fileExt; tileImageType = TileImageType.getTileImageType(fileExt); p = Pattern.compile("([0123]+)\\.(" + fileExt + ")", Pattern.CASE_INSENSITIVE); int min = PreviewMap.MAX_ZOOM; int max = 1; for (ZipFile zipFile : zips) { entries = zipFile.entries(); while (entries.hasMoreElements()) { ZipEntry entry = entries.nextElement(); Matcher m = p.matcher(entry.getName()); if (!m.matches()) continue; if (fileSyntax == null) fileSyntax = "%s." + m.group(2); int z = m.group(1).length(); min = Math.min(min, z); max = Math.max(max, z); } } minZoom = min; maxZoom = max; } public byte[] getTileData(int zoom, int x, int y, LoadMethod loadMethod) throws IOException, TileException, InterruptedException { if (!initialized) initialize(); if (fileSyntax == null) return null; if (log.isTraceEnabled()) log.trace(String.format("Loading tile z=%d x=%d y=%d", zoom, x, y)); if (invertYCoordinate) y = ((1 << zoom) - y - 1); ZipEntry entry = null; String fileName; switch (sourceType) { case DIR_ZOOM_X_Y: fileName = String.format(fileSyntax, zoom, x, y); break; case DIR_ZOOM_Y_X: fileName = String.format(fileSyntax, zoom, y, x); break; case QUADKEY: fileName = String.format(fileSyntax, MapSourceTools.encodeQuadTree(zoom, x, y)); break; default: throw new RuntimeException("Invalid source type"); } for (ZipFile zip : zips) { entry = zip.getEntry(fileName); if (entry != null) { InputStream in = zip.getInputStream(entry); byte[] data = Utilities.getInputBytes(in); in.close(); return data; } } log.debug("Map tile file not found in zip files: " + fileName); return null; } public BufferedImage getTileImage(int zoom, int x, int y, LoadMethod loadMethod) throws IOException, TileException, InterruptedException { byte[] data = getTileData(zoom, x, y, loadMethod); if (data == null) return null; return ImageIO.read(new ByteArrayInputStream(data)); } public TileImageType getTileImageType() { return tileImageType; } public int getMaxZoom() { return maxZoom; } public int getMinZoom() { return minZoom; } public String getName() { return name; } @Override public String toString() { return name; } public MapSpace getMapSpace() { return mapSpace; } public Color getBackgroundColor() { return backgroundColor; } @XmlTransient public MapSourceLoaderInfo getLoaderInfo() { return loaderInfo; } public void setLoaderInfo(MapSourceLoaderInfo loaderInfo) { this.loaderInfo = loaderInfo; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/custom/BeanShellHttpMapSource.java0000644000175000017500000001226112122526602033113 0ustar paulliupaulliupackage mobac.mapsources.custom; import java.awt.Color; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.StringWriter; import java.net.HttpURLConnection; import java.net.URL; import mobac.exceptions.TileException; import mobac.gui.mapview.PreviewMap; import mobac.mapsources.AbstractHttpMapSource; import mobac.mapsources.mapspace.MapSpaceFactory; import mobac.mapsources.mapspace.MercatorPower2MapSpace; import mobac.program.interfaces.MapSpace; import mobac.program.jaxb.ColorAdapter; import mobac.program.model.TileImageType; import mobac.utilities.Charsets; import mobac.utilities.Utilities; import bsh.EvalError; import bsh.Interpreter; public class BeanShellHttpMapSource extends AbstractHttpMapSource { private static final String AH_ERROR = "Sourced file: inline evaluation of: " + "``addHeaders(conn);'' : Command not found: addHeaders( sun.net.www.protocol.http.HttpURLConnection )"; private static int NUM = 0; private final Interpreter i; private Color backgroundColor = Color.BLACK; private boolean ignoreError = false; public static BeanShellHttpMapSource load(File f) throws EvalError, IOException { FileInputStream in = new FileInputStream(f); try { BufferedReader br = new BufferedReader(new InputStreamReader(in, Charsets.UTF_8)); StringWriter sw = new StringWriter(); String line = br.readLine(); while (line != null) { sw.write(line + "\n"); line = br.readLine(); } br.close(); return new BeanShellHttpMapSource(sw.toString()); } finally { Utilities.closeStream(in); } } public BeanShellHttpMapSource(String code) throws EvalError { super("", 0, 0, TileImageType.PNG, TileUpdate.None); name = "BeanShell map source " + NUM++; i = new Interpreter(); i.eval("import mobac.program.interfaces.HttpMapSource.TileUpdate;"); i.eval("import java.net.HttpURLConnection;"); i.eval("import mobac.utilities.beanshell.*;"); i.eval(code); Object o = i.get("name"); if (o != null) name = (String) o; o = i.get("tileSize"); if (o != null) { int tileSize = ((Integer) o).intValue(); mapSpace = MapSpaceFactory.getInstance(tileSize, true); } else mapSpace = MercatorPower2MapSpace.INSTANCE_256; o = i.get("minZoom"); if (o != null) minZoom = ((Integer) o).intValue(); else minZoom = 0; o = i.get("maxZoom"); if (o != null) maxZoom = ((Integer) o).intValue(); else maxZoom = PreviewMap.MAX_ZOOM; o = i.get("tileType"); if (o != null) tileType = TileImageType.getTileImageType((String) o); else throw new EvalError("tileType definition missing", null, null); o = i.get("tileUpdate"); if (o != null) tileUpdate = (TileUpdate) o; o = i.get("ignoreError"); if (o != null) { if (o instanceof String) { ignoreError = Boolean.parseBoolean((String) o); } else if (o instanceof Boolean) { ignoreError = ((Boolean) o).booleanValue(); } else throw new EvalError("Invalid type for \"ignoreError\": " + o.getClass(), null, null); } o = i.get("backgroundColor"); if (o != null) try { backgroundColor = ColorAdapter.parseColor((String) o); } catch (javax.xml.bind.UnmarshalException e) { throw new EvalError(e.getMessage(), null, null); } } @Override public synchronized HttpURLConnection getTileUrlConnection(int zoom, int tilex, int tiley) throws IOException { HttpURLConnection conn = null; try { String url = getTileUrl(zoom, tilex, tiley); conn = (HttpURLConnection) new URL(url).openConnection(); } catch (IOException e) { throw e; } catch (Exception e) { log.error("", e); throw new IOException(e); } try { i.set("conn", conn); i.eval("addHeaders(conn);"); } catch (EvalError e) { String msg = e.getMessage(); if (!AH_ERROR.equals(msg)) { log.error(e.getClass() + ": " + e.getMessage(), e); throw new IOException(e); } } return conn; } @Override public byte[] getTileData(int zoom, int x, int y, LoadMethod loadMethod) throws IOException, TileException, InterruptedException { if (!ignoreError) return super.getTileData(zoom, x, y, loadMethod); try { return super.getTileData(zoom, x, y, loadMethod); } catch (Exception e) { return null; } } public boolean testCode() throws IOException { return (getTileUrlConnection(minZoom, 0, 0) != null); } public String getTileUrl(int zoom, int tilex, int tiley) { try { return (String) i.eval(String.format("getTileUrl(%d,%d,%d);", zoom, tilex, tiley)); } catch (EvalError e) { log.error(e.getClass() + ": " + e.getMessage(), e); throw new RuntimeException(e); } } @Override public MapSpace getMapSpace() { return mapSpace; } @Override public int getMaxZoom() { return maxZoom; } @Override public int getMinZoom() { return minZoom; } @Override public String getName() { return name; } @Override public TileUpdate getTileUpdate() { return tileUpdate; } public Color getBackgroundColor() { return backgroundColor; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/custom/CustomMapSource.java0000644000175000017500000001467412127544346031714 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.custom; import java.awt.Color; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.IOException; import java.net.HttpURLConnection; import java.net.URL; import javax.imageio.ImageIO; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlList; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlTransient; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import mobac.exceptions.UnrecoverableDownloadException; import mobac.mapsources.MapSourceTools; import mobac.mapsources.mapspace.MercatorPower2MapSpace; import mobac.program.download.TileDownLoader; import mobac.program.interfaces.HttpMapSource; import mobac.program.interfaces.MapSourceListener; import mobac.program.interfaces.MapSpace; import mobac.program.jaxb.ColorAdapter; import mobac.program.model.MapSourceLoaderInfo; import mobac.program.model.TileImageType; import mobac.program.tilestore.TileStore; import mobac.program.tilestore.TileStoreEntry; /** * Custom tile store provider, configurable via settings.xml. */ @XmlRootElement public class CustomMapSource implements HttpMapSource { @XmlElement(nillable = false, defaultValue = "Custom") private String name = "Custom"; @XmlElement(defaultValue = "0") private int minZoom = 0; @XmlElement(required = true) private int maxZoom = 0; @XmlElement(defaultValue = "PNG") protected TileImageType tileType = TileImageType.PNG; @XmlElement(defaultValue = "NONE") private HttpMapSource.TileUpdate tileUpdate; @XmlElement(required = true, nillable = false) protected String url = "http://127.0.0.1/{$x}_{$y}_{$z}"; @XmlElement(defaultValue = "false") private boolean invertYCoordinate = false; @XmlElement(defaultValue = "#000000") @XmlJavaTypeAdapter(ColorAdapter.class) private Color backgroundColor = Color.BLACK; @XmlElement(required = false, defaultValue = "false") private boolean ignoreErrors = false; @XmlElement(required = false, defaultValue = "") @XmlList private String[] serverParts = null; private int currentServerPart = 0; // @XmlElement(required = false, defaultValue = "false") // protected boolean ignoreContentMismatch = false; private MapSourceLoaderInfo loaderInfo = null; /** * Constructor without parameters - required by JAXB */ protected CustomMapSource() { } public CustomMapSource(String name, String url) { this.name = name; this.url = url; } // public boolean ignoreContentMismatch() // { // return ignoreContentMismatch; // } public TileUpdate getTileUpdate() { return tileUpdate; } public int getMaxZoom() { return maxZoom; } public int getMinZoom() { return minZoom; } public String getName() { return name; } public String getStoreName() { return name; } public TileImageType getTileImageType() { return tileType; } public HttpURLConnection getTileUrlConnection(int zoom, int tilex, int tiley) throws IOException { String url = getTileUrl(zoom, tilex, tiley); if (url == null) return null; return (HttpURLConnection) new URL(url).openConnection(); } public String getTileUrl(int zoom, int tilex, int tiley) { if (serverParts == null || serverParts.length == 0) { return MapSourceTools.formatMapUrl(url, zoom, tilex, tiley); } else { currentServerPart = (currentServerPart + 1) % serverParts.length; String serverPart = serverParts[currentServerPart]; return MapSourceTools.formatMapUrl(url, serverPart, zoom, tilex, tiley); } } public byte[] getTileData(int zoom, int x, int y, LoadMethod loadMethod) throws IOException, UnrecoverableDownloadException, InterruptedException { if (invertYCoordinate) y = ((1 << zoom) - y - 1); if (loadMethod == LoadMethod.CACHE) { TileStoreEntry entry = TileStore.getInstance().getTile(x, y, zoom, this); if (entry == null) return null; byte[] data = entry.getData(); if (Thread.currentThread() instanceof MapSourceListener) { ((MapSourceListener) Thread.currentThread()).tileDownloaded(data.length); } return data; } if (ignoreErrors) { try { return TileDownLoader.getImage(x, y, zoom, this); } catch (Exception e) { return null; } } else { return TileDownLoader.getImage(x, y, zoom, this); } } public BufferedImage getTileImage(int zoom, int x, int y, LoadMethod loadMethod) throws IOException, UnrecoverableDownloadException, InterruptedException { byte[] data = getTileData(zoom, x, y, loadMethod); if (data == null) { if (!ignoreErrors) return null; else { int tileSize = this.getMapSpace().getTileSize(); BufferedImage image = new BufferedImage(tileSize, tileSize, BufferedImage.TYPE_4BYTE_ABGR); Graphics g = (Graphics) image.getGraphics(); try { g.setColor(backgroundColor); g.fillRect(0, 0, tileSize, tileSize); } finally { g.dispose(); } return image; } } else { return ImageIO.read(new ByteArrayInputStream(data)); } } @Override public String toString() { return name; } public MapSpace getMapSpace() { return MercatorPower2MapSpace.INSTANCE_256; } public Color getBackgroundColor() { return backgroundColor; } @XmlTransient public MapSourceLoaderInfo getLoaderInfo() { return loaderInfo; } public void setLoaderInfo(MapSourceLoaderInfo loaderInfo) { if (this.loaderInfo != null) throw new RuntimeException("LoaderInfo already set"); this.loaderInfo = loaderInfo; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/custom/package-info.java0000644000175000017500000000064112122526602031122 0ustar paulliupaulliu@javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters({ @javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter( type = mobac.program.model.TileImageType.class, value = mobac.program.jaxb.TileImageTypeAdapter.class ), @javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter( type = java.awt.Color.class, value = mobac.program.jaxb.ColorAdapter.class ) }) package mobac.mapsources.custom;mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/custom/CustomWmsMapSource.java0000644000175000017500000000506512122526602032363 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.custom; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import mobac.mapsources.MapSourceTools; /** * Custom tile store provider for wms map sources, configurable via xml file * * @author oruxman */ @XmlRootElement public class CustomWmsMapSource extends CustomMapSource { /** * tested with 1.1.1, but should work with other versions */ @XmlElement(required = true, name = "version") private String version = "1.1.1"; /** * no spaces allowed, must be replaced with %20 in the url */ @XmlElement(required = true, name = "layers") private String layers = ""; /** * currently only the coordinate system epsg:4326 is supported */ @XmlElement(required = true, name = "coordinatesystem", defaultValue = "EPSG:4326") private String coordinatesystem = "EPSG:4326"; /** * some wms needs more parameters: &EXCEPTIONS=BLANK&Styles= ..... */ @XmlElement(required = false, name = "aditionalparameters") private String aditionalparameters = ""; @Override public String getTileUrl(int zoom, int tilex, int tiley) { double[] coords = MapSourceTools.calculateLatLon(this, zoom, tilex, tiley); String url = this.url + "REQUEST=GetMap" + "&LAYERS=" + layers + "&SRS=" + coordinatesystem + "&VERSION=" + version + "&FORMAT=image/" + tileType.getMimeType() + "&BBOX=" + coords[0] + "," + coords[1] + "," + coords[2] + "," + coords[3] + "&WIDTH=256&HEIGHT=256" + aditionalparameters; return url; } public String getVersion() { return version; } public String getLayers() { return layers; } public String getCoordinatesystem() { return coordinatesystem; } } ././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/custom/CustomMultiLayerMapSource.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/custom/CustomMultiLayerMapSource.ja0000644000175000017500000001135512127544346033366 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.custom; import java.awt.Color; import java.util.ArrayList; import java.util.List; import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlElements; import javax.xml.bind.annotation.XmlList; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlSeeAlso; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import mobac.mapsources.AbstractMultiLayerMapSource; import mobac.program.interfaces.MapSource; import mobac.program.jaxb.ColorAdapter; import mobac.program.model.TileImageType; /** * */ @XmlRootElement @XmlAccessorType(XmlAccessType.PROPERTY) @XmlSeeAlso({ CustomMapSource.class }) public class CustomMultiLayerMapSource extends AbstractMultiLayerMapSource { @XmlElementWrapper(name = "layers") @XmlElements({ @XmlElement(name = "customMapSource", type = CustomMapSource.class), @XmlElement(name = "customWmsMapSource", type = CustomWmsMapSource.class), @XmlElement(name = "mapSource", type = StandardMapSourceLayer.class), @XmlElement(name = "cloudMade", type = CustomCloudMade.class), @XmlElement(name = "localTileSQLite", type = CustomLocalTileSQliteMapSource.class), @XmlElement(name = "localTileFiles", type = CustomLocalTileFilesMapSource.class), @XmlElement(name = "localTileZip", type = CustomLocalTileZipMapSource.class), @XmlElement(name = "localImageFile", type = CustomLocalImageFileMapSource.class)}) protected List layers = new ArrayList(); @XmlList() protected List layersAlpha = new ArrayList(); @XmlElement(defaultValue = "#000000") @XmlJavaTypeAdapter(ColorAdapter.class) protected Color backgroundColor = Color.BLACK; public CustomMultiLayerMapSource() { super(); mapSources = new MapSource[0]; } public TileImageType getTileType() { return tileType; } public void setTileType(TileImageType tileType) { this.tileType = tileType; } protected void afterUnmarshal(Unmarshaller u, Object parent) { mapSources = new MapSource[layers.size()]; layers.toArray(mapSources); initializeValues(); } @XmlElement(name = "name") public String getMLName() { return name; } public void setMLName(String name) { this.name = name; } @Override public Color getBackgroundColor() { return backgroundColor; } @Override protected float getLayerAlpha(int layerIndex) { if (layersAlpha.size() <= layerIndex) return 1.0f; return layersAlpha.get(layerIndex); } // public static void main(String[] args) { // OutputStream os = null; // try { // JAXBContext context = JAXBContext.newInstance(new Class[] { CustomMultiLayerMapSource.class, // CustomMapSource.class }); // // Marshaller marshaller = context.createMarshaller(); // marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); // CustomMultiLayerMapSource ms = new CustomMultiLayerMapSource(); // os = new FileOutputStream(new File("mapsources/Custom multi-layer map source.xml")); // marshaller.marshal(ms, os); // } catch (Exception e) { // e.printStackTrace(); // } finally { // Utilities.closeStream(os); // } // } // public static void main(String[] args) { // try { // JAXBContext context = JAXBContext.newInstance(new Class[] { CustomMultiLayerMapSource.class, // CustomMapSource.class }); // // Unmarshaller unmarshaller = context.createUnmarshaller(); // CustomMultiLayerMapSource ms = (CustomMultiLayerMapSource) unmarshaller.unmarshal(new // File("mapsources/Example custom multi-layer map source.xml")); // System.out.println(ms); // System.out.println(ms.layers); // } catch (Exception e) { // e.printStackTrace(); // } // } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/custom/StandardMapSourceLayer.java0000644000175000017500000000647012122526602033160 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.custom; import java.awt.Color; import java.awt.image.BufferedImage; import java.io.IOException; import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlTransient; import mobac.exceptions.TileException; import mobac.mapsources.MapSourcesManager; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSpace; import mobac.program.model.MapSourceLoaderInfo; import mobac.program.model.TileImageType; @XmlRootElement /** * Wraps an already existing map source so that it can be loaded by name in a custom multi-layer map */ public class StandardMapSourceLayer implements MapSource { protected MapSource mapSource = null; @XmlElement(name = "name") protected String mapSourceName; public MapSource getMapSource() { return mapSource; } protected void afterUnmarshal(Unmarshaller u, Object parent) { mapSource = MapSourcesManager.getInstance().getSourceByName(mapSourceName); if (mapSource == null) throw new RuntimeException("Invalid map source name used: " + mapSourceName); } public int getMaxZoom() { return mapSource.getMaxZoom(); } public int getMinZoom() { return mapSource.getMinZoom(); } public String getName() { return mapSource.getName(); } public byte[] getTileData(int zoom, int x, int y, LoadMethod loadMethod) throws IOException, TileException, InterruptedException { return mapSource.getTileData(zoom, x, y, loadMethod); } public BufferedImage getTileImage(int zoom, int x, int y, LoadMethod loadMethod) throws IOException, TileException, InterruptedException { return mapSource.getTileImage(zoom, x, y, loadMethod); } public TileImageType getTileImageType() { return mapSource.getTileImageType(); } public MapSpace getMapSpace() { return mapSource.getMapSpace(); } public Color getBackgroundColor() { return mapSource.getBackgroundColor(); } @Override public String toString() { return mapSource.toString(); } @Override public int hashCode() { return mapSource.hashCode(); } @XmlTransient public MapSourceLoaderInfo getLoaderInfo() { return mapSource.getLoaderInfo(); } public void setLoaderInfo(MapSourceLoaderInfo loaderInfo) { mapSource.setLoaderInfo(loaderInfo); } @Override public boolean equals(Object obj) { return mapSource.equals(obj); } } ././@LongLink0000000000000000000000000000015300000000000011564 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/custom/CustomLocalImageFileMapSource.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/custom/CustomLocalImageFileMapSourc0000644000175000017500000002214512127544346033335 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.custom; import java.awt.Color; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.JOptionPane; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlTransient; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import mobac.exceptions.TileException; import mobac.gui.mapview.PreviewMap; import mobac.mapsources.mapspace.MapSpaceFactory; import mobac.program.interfaces.FileBasedMapSource; import mobac.program.interfaces.MapSpace; import mobac.program.jaxb.ColorAdapter; import mobac.program.model.MapSourceLoaderInfo; import mobac.program.model.TileImageType; import mobac.utilities.I18nUtils; import org.apache.log4j.Logger; @XmlRootElement(name = "localImageFile") public class CustomLocalImageFileMapSource implements FileBasedMapSource { private static final Logger log = Logger.getLogger(CustomLocalImageFileMapSource.class); private MapSourceLoaderInfo loaderInfo = null; @XmlElement(required = true, nillable = false) private double boxNorth = 90.0; @XmlElement(required = true, nillable = false) private double boxSouth = -90.0; @XmlElement(required = true, nillable = false) private double boxEast = 180.0; @XmlElement(required = true, nillable = false) private double boxWest = -180.0; private MapSpace mapSpace = MapSpaceFactory.getInstance(256, true); private boolean initialized = false; BufferedImage fullImage = null; private TileImageType tileImageType = null; @XmlElement(nillable = false, defaultValue = "CustomImage") private String name = "Custom"; @XmlElement(nillable = false, defaultValue = "0") private int minZoom = PreviewMap.MIN_ZOOM; @XmlElement(nillable = false, defaultValue = "20") private int maxZoom = PreviewMap.MAX_ZOOM; @XmlElement(required = true) private File imageFile = null; @XmlElement(nillable = false, defaultValue = "false") private boolean retinaDisplay = false; // @XmlElement() // private CustomMapSourceType sourceType = CustomMapSourceType.DIR_ZOOM_X_Y; @XmlElement(defaultValue = "false") private boolean invertYCoordinate = false; @XmlElement(defaultValue = "#00000000") @XmlJavaTypeAdapter(ColorAdapter.class) private Color backgroundColor = Color.BLACK; public CustomLocalImageFileMapSource() { super(); } public synchronized void initialize() { if (initialized) return; reinitialize(); } public void reinitialize() { try { if (!imageFile.isFile()) { JOptionPane.showMessageDialog(null, String.format( I18nUtils.localizedStringForKey("msg_environment_invalid_source_folder"), name, imageFile.toString()), I18nUtils .localizedStringForKey("msg_environment_invalid_source_folder_title"), JOptionPane.ERROR_MESSAGE); initialized = true; return; } String[] parts = imageFile.getName().split("\\."); if (parts.length >= 2) { tileImageType = TileImageType.getTileImageType(parts[parts.length - 1]); } else { tileImageType = TileImageType.PNG; } boxWest = Math.min(boxEast, boxWest); boxEast = Math.max(boxEast, boxWest); boxSouth = Math.min(boxNorth, boxSouth); boxNorth = Math.max(boxNorth, boxSouth); } finally { initialized = true; } } public byte[] getTileData(int zoom, int x, int y, LoadMethod loadMethod) throws IOException, TileException, InterruptedException { ByteArrayOutputStream buf = new ByteArrayOutputStream(16000); BufferedImage image = getTileImage(zoom, x, y, loadMethod); if (image == null) return null; ImageIO.write(image, tileImageType.getFileExt(), buf); return buf.toByteArray(); } // integer nearest to zero private int absFloor(double value) { return value > 0 ? (int) Math.floor(value) : (int) Math.ceil(value); } // integer farest from zero private int absCeil(double value) { return value > 0 ? (int) Math.ceil(value) : (int) Math.floor(value); } public BufferedImage getTileImage(int zoom, int x, int y, LoadMethod loadMethod) throws IOException, TileException, InterruptedException { if (!initialized) initialize(); if (log.isTraceEnabled()) log.trace(String.format("Loading tile z=%d x=%d y=%d", zoom, x, y)); BufferedImage image = null; Graphics2D g2 = null; try { if (fullImage == null) { fullImage = ImageIO.read(imageFile); } int imageWidth = fullImage.getWidth(); int imageHeight = fullImage.getHeight(); int tileSize = mapSpace.getTileSize(); double tileWest = mapSpace.cXToLon(x * tileSize, zoom); double tileNorth = mapSpace.cYToLat(y * tileSize, zoom); double tileEast = mapSpace.cXToLon((x + 1) * tileSize, zoom); double tileSouth = mapSpace.cYToLat((y + 1) * tileSize, zoom); double tileWidth = tileEast - tileWest; double tileHeight = tileNorth - tileSouth; // intersects coordinate region double intersectWest = Math.max(tileWest, boxWest); double intersectEast = Math.min(tileEast, boxEast); double intersectNorth = Math.min(tileNorth, boxNorth); double intersectSouth = Math.max(tileSouth, boxSouth); double intersectWidth = intersectEast - intersectWest; double intersectHeight = intersectNorth - intersectSouth; // intersects if (intersectWidth > 0 && intersectHeight > 0) { int graphContextSize = tileSize * (retinaDisplay ? 2 : 1); image = new BufferedImage(graphContextSize, graphContextSize, BufferedImage.TYPE_4BYTE_ABGR); g2 = image.createGraphics(); g2.setColor(getBackgroundColor()); g2.fillRect(0, 0, graphContextSize, graphContextSize); double boxWidth = (boxEast - boxWest); double boxHeight = (boxNorth - boxSouth); // crop parameters double cropWScale = (boxWidth <= 0) ? 0 : (imageWidth / boxWidth); double cropHScale = (boxHeight <= 0) ? 0 : (imageHeight / boxHeight); int cropW = absCeil(intersectWidth * cropWScale); int cropH = absCeil(intersectHeight * cropHScale); int cropX = absFloor((intersectWest - boxWest) * cropWScale); // int cropY = imageHeight - absCeil((boxNorth - intersectNorth) * cropHScale) - cropH; int cropY = absFloor((boxNorth - intersectNorth) * cropHScale); // skip when no valid crop if (cropX < imageWidth && cropY < imageHeight && (cropX + cropW) > 0 && (cropY + cropH) > 0) { // draw rect double drawrectWScale = (tileWidth <= 0) ? 0 : (graphContextSize / tileWidth); double drawrectHScale = (tileHeight <= 0) ? 0 : (graphContextSize / tileHeight); int drawrectW = absCeil(intersectWidth * drawrectWScale); int drawrectH = absCeil(intersectHeight * drawrectHScale); int drawrectX = absFloor((intersectWest - tileWest) * drawrectWScale); // int drawrectY = tileSize - absCeil((tileNorth - intersectNorth) * drawrectHScale) - drawrectH; int drawrectY = absFloor((tileNorth - intersectNorth) * drawrectHScale); // skip when draw rectangle totally draw out of image if (drawrectX < graphContextSize && drawrectY < graphContextSize && (drawrectX + drawrectW) > 1 && (drawrectY + drawrectH) > 1) { g2.drawImage(fullImage, drawrectX, drawrectY, drawrectX + drawrectW, drawrectY + drawrectH, cropX, cropY, cropX + cropW, cropY + cropH, null); } } } } catch (FileNotFoundException e) { log.debug("Map image file not found: " + imageFile.getAbsolutePath()); } finally { if (g2 != null) { g2.dispose(); } } return image; } public TileImageType getTileImageType() { return tileImageType; } public int getMaxZoom() { return maxZoom; } public int getMinZoom() { return minZoom; } public String getName() { return name; } @Override public String toString() { return name; } public MapSpace getMapSpace() { return mapSpace; } public Color getBackgroundColor() { return backgroundColor; } @XmlTransient public MapSourceLoaderInfo getLoaderInfo() { return loaderInfo; } public void setLoaderInfo(MapSourceLoaderInfo loaderInfo) { this.loaderInfo = loaderInfo; } } ././@LongLink0000000000000000000000000000015300000000000011564 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/custom/CustomLocalTileFilesMapSource.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/custom/CustomLocalTileFilesMapSourc0000644000175000017500000002067712127544346033403 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.custom; import java.awt.Color; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileFilter; import java.io.FileNotFoundException; import java.io.FilenameFilter; import java.io.IOException; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.imageio.ImageIO; import javax.swing.JOptionPane; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlTransient; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import mobac.exceptions.TileException; import mobac.gui.mapview.PreviewMap; import mobac.mapsources.MapSourceTools; import mobac.mapsources.mapspace.MapSpaceFactory; import mobac.program.interfaces.FileBasedMapSource; import mobac.program.interfaces.MapSpace; import mobac.program.jaxb.ColorAdapter; import mobac.program.model.MapSourceLoaderInfo; import mobac.program.model.TileImageType; import mobac.utilities.I18nUtils; import mobac.utilities.Utilities; import org.apache.log4j.Logger; @XmlRootElement(name = "localTileFiles") public class CustomLocalTileFilesMapSource implements FileBasedMapSource { private static final Logger log = Logger.getLogger(CustomLocalTileFilesMapSource.class); private MapSourceLoaderInfo loaderInfo = null; private MapSpace mapSpace = MapSpaceFactory.getInstance(256, true); private boolean initialized = false; private String fileSyntax = null; private TileImageType tileImageType = null; @XmlElement(nillable = false, defaultValue = "CustomLocal") private String name = "Custom"; private int minZoom = PreviewMap.MIN_ZOOM; private int maxZoom = PreviewMap.MAX_ZOOM; @XmlElement(required = true) private File sourceFolder = null; @XmlElement() private CustomMapSourceType sourceType = CustomMapSourceType.DIR_ZOOM_X_Y; @XmlElement(defaultValue = "false") private boolean invertYCoordinate = false; @XmlElement(defaultValue = "#000000") @XmlJavaTypeAdapter(ColorAdapter.class) private Color backgroundColor = Color.BLACK; public CustomLocalTileFilesMapSource() { super(); } public synchronized void initialize() { if (initialized) return; reinitialize(); } public void reinitialize() { try { if (!sourceFolder.isDirectory()) { JOptionPane.showMessageDialog(null, String.format(I18nUtils.localizedStringForKey("msg_environment_invalid_source_folder"), name, sourceFolder.toString()), I18nUtils.localizedStringForKey("msg_environment_invalid_source_folder_title"), JOptionPane.ERROR_MESSAGE); initialized = true; return; } switch (sourceType) { case DIR_ZOOM_X_Y: case DIR_ZOOM_Y_X: initializeDirType(); break; case QUADKEY: initializeQuadKeyType(); break; default: throw new RuntimeException("Invalid source type"); } } finally { initialized = true; } } private void initializeDirType() { /* Update zoom levels */ FileFilter ff = new NumericDirFileFilter(); File[] zoomDirs = sourceFolder.listFiles(ff); if (zoomDirs.length < 1) { JOptionPane.showMessageDialog(null, String.format(I18nUtils.localizedStringForKey("msg_environment_invalid_source_folder_zoom"), name ,sourceFolder), I18nUtils.localizedStringForKey("msg_environment_invalid_source_folder_title"), JOptionPane.ERROR_MESSAGE); initialized = true; return; } int min = PreviewMap.MAX_ZOOM; int max = PreviewMap.MIN_ZOOM; for (File file : zoomDirs) { int z = Integer.parseInt(file.getName()); min = Math.min(min, z); max = Math.max(max, z); } minZoom = min; maxZoom = max; for (File zDir : zoomDirs) { for (File xDir : zDir.listFiles(ff)) { try { xDir.listFiles(new FilenameFilter() { String syntax = "%d/%d/%d"; public boolean accept(File dir, String name) { String[] parts = name.split("\\."); if (parts.length < 2 || parts.length > 3) return false; syntax += "." + parts[1]; if (parts.length == 3) syntax += "." + parts[2]; tileImageType = TileImageType.getTileImageType(parts[1]); fileSyntax = syntax; log.debug("Detected file syntax: " + fileSyntax + " tileImageType=" + tileImageType); throw new RuntimeException("break"); } }); } catch (RuntimeException e) { } catch (Exception e) { log.error(e.getMessage()); } return; } } } private void initializeQuadKeyType() { String[] files = sourceFolder.list(); Pattern p = Pattern.compile("([0123]+)\\.(png|gif|jpg)", Pattern.CASE_INSENSITIVE); String fileExt = null; for (String file : files) { Matcher m = p.matcher(file); if (!m.matches()) continue; fileExt = m.group(2); break; } if (fileExt == null) return; // Error no suitable file found fileSyntax = "%s." + fileExt; tileImageType = TileImageType.getTileImageType(fileExt); p = Pattern.compile("([0123]+)\\.(" + fileExt + ")", Pattern.CASE_INSENSITIVE); int min = PreviewMap.MAX_ZOOM; int max = 1; for (String file : files) { Matcher m = p.matcher(file); if (!m.matches()) continue; if (fileSyntax == null) fileSyntax = "%s." + m.group(2); int z = m.group(1).length(); min = Math.min(min, z); max = Math.max(max, z); } minZoom = min; maxZoom = max; } public byte[] getTileData(int zoom, int x, int y, LoadMethod loadMethod) throws IOException, TileException, InterruptedException { if (!initialized) initialize(); if (fileSyntax == null) return null; if (log.isTraceEnabled()) log.trace(String.format("Loading tile z=%d x=%d y=%d", zoom, x, y)); if (invertYCoordinate) y = ((1 << zoom) - y - 1); String fileName; switch (sourceType) { case DIR_ZOOM_X_Y: fileName = String.format(fileSyntax, zoom, x, y); break; case DIR_ZOOM_Y_X: fileName = String.format(fileSyntax, zoom, y, x); break; case QUADKEY: fileName = String.format(fileSyntax, MapSourceTools.encodeQuadTree(zoom, x, y)); break; default: throw new RuntimeException("Invalid source type"); } File file = new File(sourceFolder, fileName); try { return Utilities.getFileBytes(file); } catch (FileNotFoundException e) { log.debug("Map tile file not found: " + file.getAbsolutePath()); return null; } } public BufferedImage getTileImage(int zoom, int x, int y, LoadMethod loadMethod) throws IOException, TileException, InterruptedException { byte[] data = getTileData(zoom, x, y, loadMethod); if (data == null) return null; return ImageIO.read(new ByteArrayInputStream(data)); } public TileImageType getTileImageType() { return tileImageType; } public int getMaxZoom() { return maxZoom; } public int getMinZoom() { return minZoom; } public String getName() { return name; } @Override public String toString() { return name; } public MapSpace getMapSpace() { return mapSpace; } public Color getBackgroundColor() { return backgroundColor; } @XmlTransient public MapSourceLoaderInfo getLoaderInfo() { return loaderInfo; } public void setLoaderInfo(MapSourceLoaderInfo loaderInfo) { this.loaderInfo = loaderInfo; } private static class NumericDirFileFilter implements FileFilter { private Pattern p = Pattern.compile("^\\d+$"); public boolean accept(File f) { if (!f.isDirectory()) return false; return p.matcher(f.getName()).matches(); } } } ././@LongLink0000000000000000000000000000015400000000000011565 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/custom/CustomLocalTileSQliteMapSource.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/custom/CustomLocalTileSQliteMapSour0000644000175000017500000002315512154475750033373 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.custom; import java.awt.Color; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import javax.imageio.ImageIO; import javax.swing.JOptionPane; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlTransient; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import mobac.exceptions.TileException; import mobac.gui.mapview.PreviewMap; import mobac.mapsources.mapspace.MapSpaceFactory; import mobac.program.interfaces.FileBasedMapSource; import mobac.program.interfaces.MapSpace; import mobac.program.jaxb.ColorAdapter; import mobac.program.model.MapSourceLoaderInfo; import mobac.program.model.TileImageType; import mobac.utilities.I18nUtils; import mobac.utilities.Utilities; import mobac.utilities.jdbc.SQLiteLoader; import org.apache.log4j.Logger; /** * * MBTiles input http://mbtiles.org/ * */ @XmlRootElement(name = "localTileSQLite") public class CustomLocalTileSQliteMapSource implements FileBasedMapSource { private static Logger log = Logger.getLogger(CustomLocalTileSQliteMapSource.class); private static enum SQLiteAtlasType { RMaps, MBTiles, BigPlanetTracks, Galileo, NaviComputer, OSMAND }; private MapSourceLoaderInfo loaderInfo = null; private boolean initialized = false; @XmlElement(required = false) private TileImageType tileImageType = null; @XmlElement(nillable = false, defaultValue = "CustomLocalSQLite") private String name = "CustomLocalSQLite"; private int minZoom = PreviewMap.MIN_ZOOM; private int maxZoom = PreviewMap.MAX_ZOOM; @XmlElement(required = true) private File sourceFile = null; @XmlElement(required = true) private SQLiteAtlasType atlasType = null; @XmlElement(defaultValue = "#000000") @XmlJavaTypeAdapter(ColorAdapter.class) private Color backgroundColor = Color.BLACK; private String sqlMaxZoomStatement; private String sqlMinZoomStatement; private String sqlTileStatement; private String sqlTileImageTypeStatement; /** * SQLite connection with database file */ private Connection conn = null; private final MapSpace mapSpace = MapSpaceFactory.getInstance(256, true); public CustomLocalTileSQliteMapSource() { super(); } protected void updateZoomLevelInfo() { Statement statement = null; try { statement = conn.createStatement(); if (statement.execute(sqlMaxZoomStatement)) { ResultSet rs = statement.getResultSet(); if (rs.next()) { maxZoom = rs.getInt(1); } rs.close(); } if (statement.execute(sqlMinZoomStatement)) { ResultSet rs = statement.getResultSet(); if (rs.next()) { minZoom = rs.getInt(1); } rs.close(); } statement.close(); } catch (SQLException e) { log.error("", e); } finally { Utilities.closeStatement(statement); } } public synchronized void initialize() { if (initialized) return; reinitialize(); } public void reinitialize() { if (atlasType == null) { JOptionPane.showMessageDialog(null, String.format(I18nUtils.localizedStringForKey("msg_custom_map_invalid_source_file"), name, sourceFile), I18nUtils.localizedStringForKey("msg_custom_map_invalid_source_file_title"), JOptionPane.ERROR_MESSAGE); initialized = true; return; } if (!sourceFile.isFile()) { JOptionPane.showMessageDialog(null, String.format(I18nUtils.localizedStringForKey("msg_custom_map_invalid_source_sqlitedb"), name, sourceFile), I18nUtils.localizedStringForKey("msg_custom_map_invalid_source_file_title"), JOptionPane.ERROR_MESSAGE); initialized = true; return; } if (!SQLiteLoader.loadSQLiteOrShowError()) { initialized = true; return; } log.debug("Loading SQLite database " + sourceFile); String url = "jdbc:sqlite:" + this.sourceFile; try { conn = DriverManager.getConnection(url); } catch (SQLException e) { JOptionPane.showMessageDialog(null, String.format(I18nUtils.localizedStringForKey("msg_custom_map_source_failed_load_sqlitedb"), name,sourceFile,e.getMessage()), I18nUtils.localizedStringForKey("msg_custom_map_source_failed_load_sqlitedb_title"), JOptionPane.ERROR_MESSAGE); initialized = true; return; } switch (atlasType) { case MBTiles: // DISTINCT works much faster than min(zoom_level) or max(zoom_level) - uses index? sqlMaxZoomStatement = "SELECT DISTINCT zoom_level FROM tiles ORDER BY zoom_level DESC LIMIT 1;"; sqlMinZoomStatement = "SELECT DISTINCT zoom_level FROM tiles ORDER BY zoom_level ASC LIMIT 1;"; sqlTileStatement = "SELECT tile_data from tiles WHERE zoom_level=? AND tile_column=? AND tile_row=?;"; sqlTileImageTypeStatement = "SELECT tile_data from tiles LIMIT 1;"; break; case RMaps: case BigPlanetTracks: case Galileo: case OSMAND: sqlMaxZoomStatement = "SELECT DISTINCT (17 - z) as zoom FROM tiles ORDER BY zoom DESC LIMIT 1;"; sqlMinZoomStatement = "SELECT DISTINCT (17 - z) as zoom FROM tiles ORDER BY zoom ASC LIMIT 1;"; sqlTileStatement = "SELECT image from tiles WHERE z=(17 - ?) AND x=? AND y=?;"; sqlTileImageTypeStatement = "SELECT image from tiles LIMIT 1;"; break; case NaviComputer: sqlMaxZoomStatement = "SELECT DISTINCT zoom FROM Tiles ORDER BY zoom DESC LIMIT 1;"; sqlMinZoomStatement = "SELECT DISTINCT zoom FROM Tiles ORDER BY zoom ASC LIMIT 1;"; sqlTileStatement = "SELECT Tile FROM Tiles LEFT JOIN Tilesdata ON Tiles.id=Tilesdata.id WHERE Zoom=? AND X=? AND Y=?;"; sqlTileImageTypeStatement = "SELECT Tile from Tilesdata LIMIT 1;"; break; } updateZoomLevelInfo(); detectTileImageType(); initialized = true; } protected void detectTileImageType() { if (tileImageType != null) return; // Already specified manually by user Statement statement = null; try { statement = conn.createStatement(); if (statement.execute(sqlTileImageTypeStatement)) { ResultSet rs = statement.getResultSet(); if (rs.next()) tileImageType = Utilities.getImageType(rs.getBytes(1)); rs.close(); } statement.close(); } catch (SQLException e) { log.error("", e); } finally { Utilities.closeStatement(statement); } if (tileImageType == null) throw new RuntimeException("Unable to detect image type of " + sourceFile + ".\n" + "Please specify it manually using entry in map source definition."); } public byte[] getTileData(int zoom, int x, int y, LoadMethod loadMethod) throws IOException, TileException, InterruptedException { if (!initialized) initialize(); PreparedStatement statement = null; try { switch (atlasType) { case MBTiles: y = (1 << zoom) - y - 1; break; default: break; } statement = conn.prepareStatement(sqlTileStatement); statement.setInt(1, zoom); statement.setInt(2, x); statement.setInt(3, y); if (log.isTraceEnabled()) log.trace(String.format("Loading tile z=%d x=%d y=%d", zoom, x, y)); if (statement.execute()) { ResultSet rs = statement.getResultSet(); if (!rs.next()) { if (log.isDebugEnabled()) log.debug(String.format("Tile in database not found: z=%d x=%d y=%d", zoom, x, y)); return null; } byte[] data = rs.getBytes(1); rs.close(); return data; } } catch (SQLException e) { log.error("", e); } finally { Utilities.closeStatement(statement); } return null; } public BufferedImage getTileImage(int zoom, int x, int y, LoadMethod loadMethod) throws IOException, TileException, InterruptedException { byte[] data = getTileData(zoom, x, y, loadMethod); if (data == null) return null; return ImageIO.read(new ByteArrayInputStream(data)); } public TileImageType getTileImageType() { return tileImageType; } public int getMaxZoom() { return maxZoom; } public int getMinZoom() { return minZoom; } public String getName() { return name; } @Override public String toString() { return name; } public MapSpace getMapSpace() { return mapSpace; } public Color getBackgroundColor() { return backgroundColor; } @XmlTransient public MapSourceLoaderInfo getLoaderInfo() { return loaderInfo; } public void setLoaderInfo(MapSourceLoaderInfo loaderInfo) { this.loaderInfo = loaderInfo; } protected void closeConnection() { try { if (conn != null) conn.close(); } catch (SQLException e) { } conn = null; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/custom/CustomCloudMade.java0000644000175000017500000000413312127544346031640 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.custom; import java.lang.reflect.Constructor; import javax.swing.JOptionPane; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import mobac.mapsources.mappacks.openstreetmap.CloudMade; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.WrappedMapSource; import mobac.utilities.I18nUtils; /** * Requires the OpenStreetMap * * */ @XmlRootElement(name = "cloudMade") public class CustomCloudMade implements WrappedMapSource { private static boolean ERROR = false; public static Class CLOUD_MADE_CLASS = null; @XmlElement public String styleID; @XmlElement public String displayName; public MapSource getMapSource() { try { Constructor c = CLOUD_MADE_CLASS.getConstructor(String.class, String.class); return c.newInstance(styleID, displayName); } catch (Exception e) { String errorMsg = I18nUtils.localizedStringForKey("msg_environment_error_load_cloudmade"); if (!ERROR) { JOptionPane.showMessageDialog(null, errorMsg, I18nUtils.localizedStringForKey("Error"), JOptionPane.ERROR_MESSAGE); ERROR = true; } throw new RuntimeException(errorMsg, e); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/custom/CustomMapSourceType.java0000644000175000017500000000172112122526602032531 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.custom; public enum CustomMapSourceType { DIR_ZOOM_X_Y, DIR_ZOOM_Y_X, QUADKEY; } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/AbstractMultiLayerMapSource.java0000644000175000017500000001463112127544346032674 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import javax.imageio.ImageIO; import javax.xml.bind.annotation.XmlTransient; import mobac.exceptions.TileException; import mobac.gui.mapview.PreviewMap; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSpace; import mobac.program.model.MapSourceLoaderInfo; import mobac.program.model.TileImageType; import org.apache.log4j.Logger; public abstract class AbstractMultiLayerMapSource implements MapSource, Iterable { protected Logger log; protected String name = ""; protected TileImageType tileType = TileImageType.PNG; protected MapSource[] mapSources; private int maxZoom; private int minZoom; private MapSpace mapSpace; protected MapSourceLoaderInfo loaderInfo = null; public AbstractMultiLayerMapSource(String name, TileImageType tileImageType) { this(); this.name = name; this.tileType = tileImageType; } protected AbstractMultiLayerMapSource() { log = Logger.getLogger(this.getClass()); } protected void initializeValues() { MapSource refMapSource = mapSources[0]; mapSpace = refMapSource.getMapSpace(); maxZoom = PreviewMap.MAX_ZOOM; minZoom = 0; for (MapSource ms : mapSources) { maxZoom = Math.min(maxZoom, ms.getMaxZoom()); minZoom = Math.max(minZoom, ms.getMinZoom()); if (!ms.getMapSpace().equals(mapSpace)) throw new RuntimeException("Different map spaces used in multi-layer map source"); } } public MapSource[] getLayerMapSources() { return mapSources; } public Color getBackgroundColor() { return Color.BLACK; } public MapSpace getMapSpace() { return mapSpace; } public int getMaxZoom() { return maxZoom; } public int getMinZoom() { return minZoom; } public String getName() { return name; } public String getStoreName() { return null; } public byte[] getTileData(int zoom, int x, int y, LoadMethod loadMethod) throws IOException, InterruptedException, TileException { ByteArrayOutputStream buf = new ByteArrayOutputStream(16000); BufferedImage image = getTileImage(zoom, x, y, loadMethod); if (image == null) return null; // TODO: here can write with compress ImageIO.write(image, tileType.getFileExt(), buf); return buf.toByteArray(); } // public BufferedImage getTileImage(int zoom, int x, int y, LoadMethod loadMethod) throws IOException, // InterruptedException, TileException { // int tileSize = mapSpace.getTileSize(); // BufferedImage image = new BufferedImage(tileSize, tileSize, BufferedImage.TYPE_3BYTE_BGR); // Graphics2D g2 = image.createGraphics(); // try { // g2.setColor(getBackgroundColor()); // g2.fillRect(0, 0, tileSize, tileSize); // boolean used = false; // for (MapSource layerMapSource : mapSources) { // BufferedImage layerImage = layerMapSource.getTileImage(zoom, x, y, loadMethod); // if (layerImage != null) { // log.debug("Multi layer loading: " + layerMapSource + " " + x + " " + y + " " + zoom); // g2.drawImage(layerImage, 0, 0, null); // used = true; // } // } // if (used) // return image; // else // return null; // } finally { // g2.dispose(); // } // } public BufferedImage getTileImage(int zoom, int x, int y, LoadMethod loadMethod) throws IOException, InterruptedException, TileException { // int tileSize = mapSpace.getTileSize(); BufferedImage image = null; Graphics2D g2 = null; try { ArrayList layerImages = new ArrayList(mapSources.length); int maxSize = mapSpace.getTileSize(); for (int i = 0; i < mapSources.length; i++) { MapSource layerMapSource = mapSources[i]; BufferedImage layerImage = layerMapSource.getTileImage(zoom, x, y, loadMethod); if (layerImage != null) { log.debug("Multi layer loading: " + layerMapSource + " " + x + " " + y + " " + zoom); layerImages.add(layerImage); int size = layerImage.getWidth(); if (size > maxSize) { maxSize = size; } } } // optimize for when only one layer exist if (layerImages.size() == 1) { return layerImages.get(0); } else if (layerImages.size() > 1) { image = new BufferedImage(maxSize, maxSize, BufferedImage.TYPE_3BYTE_BGR); g2 = image.createGraphics(); g2.setColor(getBackgroundColor()); g2.fillRect(0, 0, maxSize, maxSize); for (int i = 0; i < layerImages.size(); i++) { BufferedImage layerImage = layerImages.get(i); g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, getLayerAlpha(i))); g2.drawImage(layerImage, 0, 0, maxSize, maxSize, null); } return image; } else { return null; } } finally { if (g2 != null) { g2.dispose(); } } } protected float getLayerAlpha(int layerIndex) { return 1.0f; } public TileImageType getTileImageType() { return tileType; } @Override public String toString() { return getName(); } public Iterator iterator() { return Arrays.asList(mapSources).iterator(); } @XmlTransient public MapSourceLoaderInfo getLoaderInfo() { return loaderInfo; } public void setLoaderInfo(MapSourceLoaderInfo loaderInfo) { if (this.loaderInfo != null) throw new RuntimeException("LoaderInfo already set"); this.loaderInfo = loaderInfo; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mapspace/0000755000175000017500000000000012127006526026214 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mapspace/MapSpaceFactory.java0000644000175000017500000000236712122526602032105 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.mapspace; import mobac.program.interfaces.MapSpace; public class MapSpaceFactory { /** * @param tileSize * @param isSpherical * @return */ public static MapSpace getInstance(int tileSize, boolean isSpherical) { if (isSpherical) return new MercatorPower2MapSpace(tileSize); else return new MercatorPower2MapSpaceEllipsoidal(tileSize); } } ././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mapspace/MercatorPower2MapSpace.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mapspace/MercatorPower2MapSpace.jav0000644000175000017500000001502212127006526033203 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.mapspace; import java.awt.Point; import mobac.gui.mapview.PreviewMap; import mobac.program.interfaces.MapSpace; /** * Mercator projection with a world width and height of 256 * 2zoom pixel. This is the common projection used * by OpenStreetMap and Google. It provides methods to translate coordinates from 'map space' into latitude and * longitude (on the WGS84 ellipsoid) and vice versa. Map space is measured in pixels. The origin of the map space is * the top left corner. The map space origin (0,0) has latitude ~85 and longitude -180 * *

* This is the only implementation that is currently supported by Mobile Atlas Creator. *

*

* DO NOT TRY TO IMPLEMENT YOUR OWN. IT WILL MOST LIKELY NOT WORK! *

* * @see MapSpace */ public class MercatorPower2MapSpace implements MapSpace { public static final double MAX_LAT = 85.05112877980659; public static final double MIN_LAT = -85.05112877980659; protected final int tileSize; /** * Pre-computed values for the world size (height respectively width) in the different zoom levels. */ protected final int[] worldSize; public static final MapSpace INSTANCE_256 = new MercatorPower2MapSpace(256); protected MercatorPower2MapSpace(int tileSize) { this.tileSize = tileSize; worldSize = new int[PreviewMap.MAX_ZOOM + 1]; for (int zoom = 0; zoom < worldSize.length; zoom++) worldSize[zoom] = tileSize * (1 << zoom); } protected double radius(int zoom) { return getMaxPixels(zoom) / (2.0 * Math.PI); } public ProjectionCategory getProjectionCategory() { return ProjectionCategory.SPHERE; } /** * Returns the absolute number of pixels in y or x, defined as: 2zoom * tileSize * * @param zoom * [0..22] (for tileSize = 256) * @return */ public int getMaxPixels(int zoom) { return worldSize[zoom]; } protected int falseNorthing(int aZoomlevel) { return (-1 * getMaxPixels(aZoomlevel) / 2); } /** * Transforms latitude to pixelspace * * @param lat * [-90...90] * @param zoom * [0..22] (for tileSize = 256) * @return [0..2^zoom*tileSize[ * @author Jan Peter Stotz */ public int cLatToY(double lat, int zoom) { lat = Math.max(MIN_LAT, Math.min(MAX_LAT, lat)); double sinLat = Math.sin(Math.toRadians(lat)); double log = Math.log((1.0 + sinLat) / (1.0 - sinLat)); int mp = getMaxPixels(zoom); int y = (int) (mp * (0.5 - (log / (4.0 * Math.PI)))); y = Math.min(y, mp - 1); return y; } /** * Transform longitude to pixelspace * * @param lon * [-180..180] * @param zoom * [0..22] (for tileSize = 256) * @return [0..2^zoom*TILE_SIZE[ * @author Jan Peter Stotz */ public int cLonToX(double lon, int zoom) { int mp = getMaxPixels(zoom); int x = (int) ((mp * (lon + 180l)) / 360l); x = Math.min(x, mp - 1); return x; } /** * Transforms pixel coordinate X to longitude * * @param x * [0..2^zoom * tileSize[ * @param zoom * [0..22] * @return ]-180..180[ * @author Jan Peter Stotz */ public double cXToLon(int x, int zoom) { return ((360d * x) / getMaxPixels(zoom)) - 180.0; } /** * Transforms pixel coordinate Y to latitude * * @param y * [0..2^zoom * tileSize[ * @param zoom * [0..22] * @return [MIN_LAT..MAX_LAT] is about [-85..85] */ public double cYToLat(int y, int zoom) { y += falseNorthing(zoom); double latitude = (Math.PI / 2) - (2 * Math.atan(Math.exp(-1.0 * y / radius(zoom)))); return -1 * Math.toDegrees(latitude); } public int getTileSize() { return tileSize; } public int moveOnLatitude(int startX, int y, int zoom, double angularDist) { y += falseNorthing(zoom); double lat = -1 * ((Math.PI / 2) - (2 * Math.atan(Math.exp(-1.0 * y / radius(zoom))))); double lon = cXToLon(startX, zoom); double sinLat = Math.sin(lat); lon += Math .toDegrees(Math.atan2(Math.sin(angularDist) * Math.cos(lat), Math.cos(angularDist) - sinLat * sinLat)); int newX = cLonToX(lon, zoom); int w = newX - startX; return w; } public double horizontalDistance(int zoom, int y, int xDist) { y = Math.max(y, 0); y = Math.min(y, getMaxPixels(zoom)); double lat = cYToLat(y, zoom); double lon1 = -180.0; double lon2 = cXToLon(xDist, zoom); double dLon = Math.toRadians(lon2 - lon1); double cos_lat = Math.cos(Math.toRadians(lat)); double sin_dLon_2 = Math.sin(dLon) / 2; double a = cos_lat * cos_lat * sin_dLon_2 * sin_dLon_2; return 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); } public int xChangeZoom(int x, int oldZoom, int newZoom) { int zoomDiff = oldZoom - newZoom; return (zoomDiff > 0) ? x >> zoomDiff : x << -zoomDiff; } public int yChangeZoom(int y, int oldZoom, int newZoom) { int zoomDiff = oldZoom - newZoom; return (zoomDiff > 0) ? y >> zoomDiff : y << -zoomDiff; } public Point changeZoom(Point pixelCoordinate, int oldZoom, int newZoom) { int x = xChangeZoom(pixelCoordinate.x, oldZoom, newZoom); int y = yChangeZoom(pixelCoordinate.y, oldZoom, newZoom); return new Point(x, y); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + tileSize; return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; MercatorPower2MapSpace other = (MercatorPower2MapSpace) obj; if (tileSize != other.tileSize) return false; return true; } } ././@LongLink0000000000000000000000000000016100000000000011563 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mapspace/MercatorPower2MapSpaceEllipsoidal.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mapspace/MercatorPower2MapSpaceElli0000644000175000017500000001334412122526602033234 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.mapspace; import mobac.program.interfaces.MapSpace; /** * * Provides support for true Ellipsoidal Mercator projections; * * Based on: * * GeoTools - The Open Source Java GIS Toolkit http://geotools.org * * (C) 1999-2008, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General * Public License as published by the Free Software Foundation; version 2.1 of the License. * * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * This package contains formulas from the PROJ package of USGS. USGS's work is fully acknowledged here. This derived * work has been relicensed under LGPL with Frank Warmerdam's permission. * */ public class MercatorPower2MapSpaceEllipsoidal extends MercatorPower2MapSpace { /** * Difference allowed in iterative computations. */ private static final double ITERATION_TOLERANCE = 1E-10; /** * Maximum number of iterations for iterative computations. */ private static final int MAXIMUM_ITERATIONS = 15; /** * The square of excentricity: e² = (a²-b²)/a² where e is the excentricity, a is the semi * major axis length and b is the semi minor axis length. * * For WGS84 ellipsoid a = 6378137 b = 6356752.3142 */ protected final double excentricitySquared = 0.00669438; /** * Ellipsoid excentricity, equals to sqrt({@link * #excentricitySquared}). Value 0 means that the ellipsoid is spherical. */ protected final double excentricity = Math.sqrt(excentricitySquared); public static final MapSpace INSTANCE_256 = new MercatorPower2MapSpaceEllipsoidal(256); protected MercatorPower2MapSpaceEllipsoidal(int tileSize) { super(tileSize); } @Override public ProjectionCategory getProjectionCategory() { return ProjectionCategory.ELLIPSOID; } /* * (non-Javadoc) * * @see mobac.mapsources.mapspace.MercatorPower2MapSpace#cLatToY(double, int) */ @Override public int cLatToY(double lat, int zoom) { lat = Math.max(MIN_LAT, Math.min(MAX_LAT, lat)); lat = Math.toRadians(lat); lat = -Math.log(tsfn(lat, Math.sin(lat))); int mp = getMaxPixels(zoom); int y = (-1) * (int) (mp * lat / (2 * Math.PI)); y = y - falseNorthing(zoom) - (y > 0 ? -1 : 1); y = Math.min(y, mp - 1); return y; } /* * (non-Javadoc) * * @see mobac.mapsources.mapspace.MercatorPower2MapSpace#cYToLat(int, int) */ @Override public double cYToLat(int y, int zoom) { int y2 = y + falseNorthing(zoom); double latitude = Math.exp(-y2 / radius(zoom)); try { latitude = cphi2(latitude); } catch (Exception e) { // No convergence; try spheric aproximation. return super.cYToLat(y, zoom); } return -1 * Math.toDegrees(latitude); } /** * Iteratively solve equation (7-9) from Snyder. */ private double cphi2(final double ts) throws Exception { final double eccnth = 0.5 * excentricity; double phi = (Math.PI / 2) - 2.0 * Math.atan(ts); for (int i = 0; i < MAXIMUM_ITERATIONS; i++) { final double con = excentricity * Math.sin(phi); final double dphi = (Math.PI / 2) - 2.0 * Math.atan(ts * Math.pow((1 - con) / (1 + con), eccnth)) - phi; phi += dphi; if (Math.abs(dphi) <= ITERATION_TOLERANCE) { return phi; } } // No convergence, wrong parameters. throw new Exception(); } /** * Computes function (15-9) and (9-13) from Snyder. Equivalent to negative of function (7-7). */ private double tsfn(final double phi, double sinphi) { sinphi *= excentricity; /* * NOTE: change sign to get the equivalent of Snyder (7-7). */ return Math.tan(0.5 * (Math.PI / 2 - phi)) / Math.pow((1 - sinphi) / (1 + sinphi), 0.5 * excentricity); } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); long temp; temp = Double.doubleToLongBits(excentricity); result = prime * result + (int) (temp ^ (temp >>> 32)); temp = Double.doubleToLongBits(excentricitySquared); result = prime * result + (int) (temp ^ (temp >>> 32)); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (!super.equals(obj)) return false; if (getClass() != obj.getClass()) return false; MercatorPower2MapSpaceEllipsoidal other = (MercatorPower2MapSpaceEllipsoidal) obj; if (Double.doubleToLongBits(excentricity) != Double.doubleToLongBits(other.excentricity)) return false; if (Double.doubleToLongBits(excentricitySquared) != Double.doubleToLongBits(other.excentricitySquared)) return false; return true; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/MapSourceUrlUpdater.java0000644000175000017500000001043012122526602031167 0ustar paulliupaulliupackage mobac.mapsources; import java.io.IOException; import java.net.HttpURLConnection; import java.net.URL; import java.nio.charset.Charset; import java.util.LinkedList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import mobac.exceptions.MapSourceInitializationException; import mobac.utilities.Utilities; import mobac.utilities.writer.NullPrintWriter; import org.w3c.dom.Document; import org.w3c.dom.NodeList; import org.w3c.tidy.Tidy; public class MapSourceUrlUpdater { public static final String ACCEPT = " text/*, text/html, text/html;level=1"; /** * Loads the web page specified by url, parses it into DOM and extracts the src attribute * of all <img> entities. * * @param url * http or https url * @param regex * @return * @throws IOException */ public static List extractImgSrcList(String url, String regex) throws IOException { LinkedList list = new LinkedList(); URL u = new URL(url); HttpURLConnection conn = (HttpURLConnection) u.openConnection(); conn.addRequestProperty("Accept", ACCEPT); if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) { Utilities.getInputBytes(conn.getInputStream()); throw new IOException("Invalid HTTP response code: " + conn.getResponseCode()); } Tidy tidy = new Tidy(); tidy.setErrout(new NullPrintWriter()); // Suppress error messages Document doc = tidy.parseDOM(conn.getInputStream(), null); XPathFactory factory = XPathFactory.newInstance(); XPath xpath = factory.newXPath(); XPathExpression expr; NodeList nodes; try { expr = xpath.compile("//img[@src]"); nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET); } catch (XPathExpressionException e) { throw new RuntimeException(e); } Pattern p = null; if (regex != null) p = Pattern.compile(regex); for (int i = 0; i < nodes.getLength(); i++) { String imgUrl = nodes.item(i).getAttributes().getNamedItem("src").getNodeValue(); if (imgUrl != null && imgUrl.length() > 0) { if (p != null) { if (!p.matcher(imgUrl).matches()) continue; } list.add(imgUrl); } } return list; } /** * Retrieves the text or HTML document on the specified url, interprets the retrieved data as * {@link String} of {@link Charset} charset and returns this {@link String}. * * @param url * @param charset * @return * @throws IOException */ public static String loadDocument(String url, Charset charset) throws IOException { URL u = new URL(url); HttpURLConnection conn = (HttpURLConnection) u.openConnection(); conn.addRequestProperty("Accept", ACCEPT); byte[] data = Utilities.getInputBytes(conn.getInputStream()); if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) { throw new IOException("Invalid HTTP response code: " + conn.getResponseCode()); } return new String(data, charset); } /** * * @param url * @param charset * @param regex * regex defining one group with will be returned * @return * @throws MapSourceInitializationException */ public static String loadDocumentAndExtractGroup(String url, Charset charset, String regex) throws MapSourceInitializationException { String document; try { document = loadDocument(url, charset); } catch (IOException e) { throw new MapSourceInitializationException("Faile dto retrieve initialization document from url: " + url + "\nError: " + e.getMessage(), e); } Matcher m = Pattern.compile(regex).matcher(document); if (!m.find()) throw new MapSourceInitializationException("pattern not found: " + regex); return m.group(1); } public static void main(String[] args) { try { List imgUrls = extractImgSrcList("http://maps.google.com/?ie=UTF8&ll=0,0&spn=0,0&z=2", "^http://mt\\d\\.google\\.com/.*"); for (String s : imgUrls) System.out.println(s); } catch (Exception e) { e.printStackTrace(); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/loader/0000755000175000017500000000000012127544346025700 5ustar paulliupaulliu././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/loader/BeanShellMapSourceLoader.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/loader/BeanShellMapSourceLoader.jav0000644000175000017500000000305512122526602033176 0ustar paulliupaulliupackage mobac.mapsources.loader; import java.io.File; import javax.swing.JOptionPane; import mobac.mapsources.MapSourcesManager; import mobac.mapsources.custom.BeanShellHttpMapSource; import mobac.program.model.MapSourceLoaderInfo; import mobac.program.model.MapSourceLoaderInfo.LoaderType; import mobac.utilities.file.FileExtFilter; import org.apache.log4j.Logger; public class BeanShellMapSourceLoader { private final Logger log = Logger.getLogger(BeanShellMapSourceLoader.class); private final MapSourcesManager mapSourcesManager; private final File mapSourcesDir; public BeanShellMapSourceLoader(MapSourcesManager mapSourceManager, File mapSourcesDir) { this.mapSourcesManager = mapSourceManager; this.mapSourcesDir = mapSourcesDir; } public void loadBeanShellMapSources() { File[] customMapSourceFiles = mapSourcesDir.listFiles(new FileExtFilter(".bsh")); for (File f : customMapSourceFiles) { try { BeanShellHttpMapSource mapSource = BeanShellHttpMapSource.load(f); log.trace("BeanShell map source loaded: " + mapSource + " from file \"" + f.getName() + "\""); mapSource.setLoaderInfo(new MapSourceLoaderInfo(LoaderType.BSH, f)); mapSourcesManager.addMapSource(mapSource); } catch (Exception e) { String errorMsg = "Failed to load custom BeanShell map source \"" + f.getName() + "\": " + e.getMessage(); log.error(errorMsg, e); JOptionPane.showMessageDialog(null, errorMsg, "Failed to load custom BeanShell map source", JOptionPane.ERROR_MESSAGE); } } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/loader/MapPackManager.java0000644000175000017500000004325712127544346031365 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.loader; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLClassLoader; import java.security.CodeSigner; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; import java.util.Iterator; import java.util.List; import java.util.ServiceLoader; import java.util.jar.Attributes; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.jar.Manifest; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.zip.ZipEntry; import java.util.zip.ZipException; import java.util.zip.ZipFile; import javax.swing.JOptionPane; import mobac.exceptions.MapSourceCreateException; import mobac.exceptions.UnrecoverableDownloadException; import mobac.exceptions.UpdateFailedException; import mobac.mapsources.MapSourcesManager; import mobac.program.Logging; import mobac.program.ProgramInfo; import mobac.program.interfaces.MapSource; import mobac.program.model.MapSourceLoaderInfo; import mobac.program.model.MapSourceLoaderInfo.LoaderType; import mobac.program.model.Settings; import mobac.utilities.GUIExceptionHandler; import mobac.utilities.I18nUtils; import mobac.utilities.Utilities; import mobac.utilities.file.FileExtFilter; import org.apache.commons.codec.binary.Hex; import org.apache.log4j.Level; import org.apache.log4j.Logger; public class MapPackManager { private final Logger log = Logger.getLogger(MapPackManager.class); private final int requiredMapPackVersion; private final File mapPackDir; private final X509Certificate mapPackCert; public MapPackManager(File mapPackDir) throws CertificateException, IOException { this.mapPackDir = mapPackDir; requiredMapPackVersion = Integer.parseInt(System.getProperty("mobac.mappackversion")); CertificateFactory cf = CertificateFactory.getInstance("X.509"); Collection certs = cf.generateCertificates(Utilities .loadResourceAsStream("cert/MapPack.cer")); mapPackCert = (X509Certificate) certs.iterator().next(); } /** * Searches for updated map packs, verifies the signature * * @throws IOException */ public void installUpdates() throws IOException { File[] newMapPacks = mapPackDir.listFiles(new FileExtFilter(".jar.new")); if (newMapPacks == null) throw new IOException("Failed to enumerate installable mappacks"); for (File newMapPack : newMapPacks) { try { testMapPack(newMapPack); String name = newMapPack.getName(); name = name.substring(0, name.length() - 4); // remove ".new" File oldMapPack = new File(mapPackDir, name); if (oldMapPack.isFile()) { // TODO: Check if new map pack file is still compatible // TODO: Check if the downloaded version is newer File oldMapPack2 = new File(mapPackDir, name + ".old"); Utilities.renameFile(oldMapPack, oldMapPack2); } if (!newMapPack.renameTo(oldMapPack)) throw new IOException("Failed to rename file: " + newMapPack); } catch (CertificateException e) { Utilities.deleteFile(newMapPack); log.error("Map pack certificate cerificateion failed (" + newMapPack.getName() + ") installation aborted and file was deleted"); } } } public File[] getAllMapPackFiles() { return mapPackDir.listFiles(new FileExtFilter(".jar")); } public void loadMapPacks(MapSourcesManager mapSourcesManager) throws IOException, CertificateException { File[] mapPacks = getAllMapPackFiles(); for (File mapPackFile : mapPacks) { File oldMapPackFile = new File(mapPackFile.getAbsolutePath() + ".old"); try { loadMapPack(mapPackFile, mapSourcesManager); if (oldMapPackFile.isFile()) Utilities.deleteFile(oldMapPackFile); } catch (MapSourceCreateException e) { if (oldMapPackFile.isFile()) { mapPackFile.deleteOnExit(); File newMapPackFile = new File(mapPackFile.getAbsolutePath() + ".new"); Utilities.renameFile(oldMapPackFile, newMapPackFile); try { JOptionPane.showMessageDialog(null, I18nUtils.localizedStringForKey("msg_update_map_pack_error"), I18nUtils.localizedStringForKey("msg_update_map_pack_error_title"), JOptionPane.INFORMATION_MESSAGE); System.exit(1); } catch (Exception e1) { log.error(e1.getMessage(), e1); } } GUIExceptionHandler.processException(e); } catch (CertificateException e) { throw e; } catch (Exception e) { throw new IOException("Failed to load map pack: " + mapPackFile, e); } } } public void loadMapPack(File mapPackFile, MapSourcesManager mapSourcesManager) throws CertificateException, IOException, MapSourceCreateException { // testMapPack(mapPackFile); URLClassLoader urlCl; URL url = mapPackFile.toURI().toURL(); urlCl = new MapPackClassLoader(url, ClassLoader.getSystemClassLoader()); InputStream manifestIn = urlCl.getResourceAsStream("META-INF/MANIFEST.MF"); String rev = null; if (manifestIn != null) { Manifest mf = new Manifest(manifestIn); rev = mf.getMainAttributes().getValue("MapPackRevision"); manifestIn.close(); if (rev != null) { if ("exported".equals(rev)) { rev = ProgramInfo.getRevisionStr(); } else { rev = Integer.toString(Utilities.parseSVNRevision(rev)); } } mf = null; } MapSourceLoaderInfo loaderInfo = new MapSourceLoaderInfo(LoaderType.MAPPACK, mapPackFile, rev); final Iterator iterator = ServiceLoader.load(MapSource.class, urlCl).iterator(); while (iterator.hasNext()) { try { MapSource ms = iterator.next(); ms.setLoaderInfo(loaderInfo); mapSourcesManager.addMapSource(ms); log.trace("Loaded map source: " + ms.toString() + " (name: " + ms.getName() + ")"); } catch (Error e) { urlCl = null; throw new MapSourceCreateException("Failed to load a map sources from map pack: " + mapPackFile.getName() + " " + e.getMessage(), e); } } } public String downloadMD5SumList() throws IOException, UpdateFailedException { String md5eTag = Settings.getInstance().mapSourcesUpdate.etag; log.debug("Last md5 eTag: " + md5eTag); String updateUrl = System.getProperty("mobac.updateurl"); if (updateUrl == null) throw new RuntimeException("Update url not present"); byte[] data = null; // Proxy p = new Proxy(Type.HTTP, InetSocketAddress.createUnresolved("localhost", 8888)); HttpURLConnection conn = (HttpURLConnection) new URL(updateUrl).openConnection(); conn.setInstanceFollowRedirects(false); if (md5eTag != null) conn.addRequestProperty("If-None-Match", md5eTag); int responseCode = conn.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_NOT_MODIFIED) { log.debug("No newer md5 file available"); return null; } if (responseCode != HttpURLConnection.HTTP_OK) throw new UpdateFailedException("Invalid HTTP response: " + responseCode + " for update url " + conn.getURL()); // Case HTTP_OK InputStream in = conn.getInputStream(); data = Utilities.getInputBytes(in); in.close(); Settings.getInstance().mapSourcesUpdate.etag = conn.getHeaderField("ETag"); log.debug("New md5 file retrieved"); String md5sumList = new String(data); return md5sumList; } /** * Clean up old files (.jar.new and jar.unverified)in mapsources directory * * @throws IOException */ public void cleanMapPackDir() throws IOException { File[] newMapPacks = mapPackDir.listFiles(new FileExtFilter(".jar.new")); for (File newMapPack : newMapPacks) Utilities.deleteFile(newMapPack); File[] unverifiedMapPacks = mapPackDir.listFiles(new FileExtFilter(".jar.unverified")); for (File unverifiedMapPack : unverifiedMapPacks) Utilities.deleteFile(unverifiedMapPack); } /** * Performs on map sources online update * * @return
    *
  • 0: no change in online md5 sum file (based on ETag)
  • *
  • -1: Online md5 file is empty indicationg that this MOBAc versiosn is no longer supported
  • *
  • x>0: Number of updated map packs
  • *
* @throws IOException */ public int updateMapPacks() throws UpdateFailedException, UnrecoverableDownloadException, IOException { String updateBaseUrl = System.getProperty("mobac.updatebaseurl"); if (updateBaseUrl == null) throw new RuntimeException("Update base url not present"); cleanMapPackDir(); String md5sumList = downloadMD5SumList(); if (md5sumList == null) return 0; // no new md5 file available if (md5sumList.length() == 0) return -1; // empty file means - outdated version int updateCount = 0; String[] outdatedMapPacks = searchForOutdatedMapPacks(md5sumList); for (String mapPack : outdatedMapPacks) { log.debug("Updaing map pack: " + mapPack); try { File newMapPackFile = downloadMapPack(updateBaseUrl, mapPack); try { testMapPack(newMapPackFile); } catch (CertificateException e) { // Certificate validation failed log.error(e.getMessage(), e); Utilities.deleteFile(newMapPackFile); continue; } log.debug("Verification of map pack \"" + mapPack + "\" passed successfully"); // Check if the downloaded version is newer int newRev = getMapPackRevision(newMapPackFile); File oldMapPack = new File(mapPackDir, mapPack); int oldRev = -1; if (oldMapPack.isFile()) oldRev = getMapPackRevision(oldMapPack); if (newRev < oldRev) { log.warn("Downloaded map pack was older than existing map pack - ignoring update"); Utilities.deleteFile(newMapPackFile); } else { String name = newMapPackFile.getName(); name = name.replace(".unverified", ".new"); File f = new File(newMapPackFile.getParentFile(), name); // Change file extension Utilities.renameFile(newMapPackFile, f); updateCount++; } } catch (IOException e) { log.error(e.getMessage(), e); } } return updateCount; } public int getMapPackRevision(File mapPackFile) throws ZipException, IOException { ZipFile zip = new ZipFile(mapPackFile); try { ZipEntry entry = zip.getEntry("META-INF/MANIFEST.MF"); if (entry == null) throw new ZipException("Unable to find MANIFEST.MF"); Manifest mf = new Manifest(zip.getInputStream(entry)); Attributes a = mf.getMainAttributes(); String mpv = a.getValue("MapPackRevision").trim(); return Utilities.parseSVNRevision(mpv); } catch (NumberFormatException e) { return -1; } finally { zip.close(); } } public File downloadMapPack(String baseURL, String mapPackFilename) throws IOException { if (!mapPackFilename.endsWith(".jar")) throw new IOException("Invalid map pack filename"); byte[] mapPackData = Utilities.downloadHttpFile(baseURL + mapPackFilename); File newMapPackFile = new File(mapPackDir, mapPackFilename + ".unverified"); FileOutputStream out = new FileOutputStream(newMapPackFile); try { out.write(mapPackData); out.flush(); } finally { Utilities.closeStream(out); } log.debug("New map pack \"" + mapPackFilename + "\" successfully downloaded"); return newMapPackFile; } /** * * @param md5sumList * @return Array of filenames of map packs which are outdated */ public String[] searchForOutdatedMapPacks(String md5sumList) throws UpdateFailedException { ArrayList outdatedMappacks = new ArrayList(); String[] md5s = md5sumList.split("[\\n\\r]+"); Pattern linePattern = Pattern.compile("([0-9a-f]{32}) (mp-[\\w]+\\.jar)"); for (String line : md5s) { line = line.trim(); if (line.length() == 0) continue; Matcher m = linePattern.matcher(line); if (!m.matches()) { throw new UpdateFailedException("Invalid content found in md5 list: \"" + line + "\""); } String md5 = m.group(1); String filename = m.group(2); // Check if there is already an update map pack File mapPackFile = new File(mapPackDir, filename + ".new"); if (!mapPackFile.isFile()) mapPackFile = new File(mapPackDir, filename); if (!mapPackFile.isFile()) { outdatedMappacks.add(filename); log.debug("local map pack file missing: " + filename); continue; } try { String localmd5 = generateMappackMD5(mapPackFile); if (localmd5.equals(md5)) continue; // No change in map pack log.debug("Found outdated map pack: \"" + filename + "\" local md5: " + localmd5 + " remote md5: " + md5); outdatedMappacks.add(filename); } catch (Exception e) { log.error("Failed to generate md5sum of " + mapPackFile, e); } } String[] result = new String[outdatedMappacks.size()]; outdatedMappacks.toArray(result); return result; } /** * Calculate the md5sum on all files in the map pack file (except those in META-INF) and their filenames inclusive * path in the map pack file). * * @param mapPackFile * @return * @throws IOException * @throws NoSuchAlgorithmException */ public String generateMappackMD5(File mapPackFile) throws IOException, NoSuchAlgorithmException { ZipFile zip = new ZipFile(mapPackFile); try { Enumeration entries = zip.entries(); MessageDigest md5Total = MessageDigest.getInstance("MD5"); MessageDigest md5 = MessageDigest.getInstance("MD5"); while (entries.hasMoreElements()) { ZipEntry entry = entries.nextElement(); if (entry.isDirectory()) continue; // Do not hash files from META-INF String name = entry.getName(); if (name.toUpperCase().startsWith("META-INF")) continue; md5.reset(); InputStream in = zip.getInputStream(entry); byte[] data = Utilities.getInputBytes(in); in.close(); // name = name.replaceAll("\\\\", "/"); byte[] digest = md5.digest(data); log.trace("Hashsum " + Hex.encodeHexString(digest) + " includes \"" + name + "\""); md5Total.update(digest); md5Total.update(name.getBytes()); } String md5sum = Hex.encodeHexString(md5Total.digest()); log.trace("md5sum of " + mapPackFile.getName() + ": " + md5sum); return md5sum; } finally { zip.close(); } } /** * Verifies the class file signatures of the specified map pack * * @param mapPackFile * @throws IOException * @throws CertificateException */ public void testMapPack(File mapPackFile) throws IOException, CertificateException { String fileName = mapPackFile.getName(); JarFile jf = new JarFile(mapPackFile, true); try { Enumeration it = jf.entries(); while (it.hasMoreElements()) { JarEntry entry = it.nextElement(); // We verify only class files if (!entry.getName().endsWith(".class")) continue; // directory or other entry // Get the input stream (triggers) the signature verification for the specific class Utilities.readFully(jf.getInputStream(entry)); if (entry.getCodeSigners() == null) throw new CertificateException("Unsigned class file found: " + entry.getName()); CodeSigner signer = entry.getCodeSigners()[0]; List cp = signer.getSignerCertPath().getCertificates(); if (cp.size() > 1) throw new CertificateException("Signature certificate not accepted: " + "certificate path contains more than one certificate"); // Compare the used certificate with the mapPack certificate if (!mapPackCert.equals(cp.get(0))) throw new CertificateException("Signature certificate not accepted: " + "not the MapPack signer certificate"); } Manifest mf = jf.getManifest(); Attributes a = mf.getMainAttributes(); String mpv = a.getValue("MapPackVersion"); if (mpv == null) throw new IOException("MapPackVersion info missing!"); int mapPackVersion = Integer.parseInt(mpv); if (requiredMapPackVersion != mapPackVersion) throw new IOException("This pack \"" + fileName + "\" is not compatible with this MOBAC version."); ZipEntry entry = jf.getEntry("META-INF/services/mobac.program.interfaces.MapSource"); if (entry == null) throw new IOException("MapSources services list is missing in file " + fileName); } finally { jf.close(); } } public static void main(String[] args) { try { Logging.configureConsoleLogging(Level.DEBUG); ProgramInfo.initialize(); MapPackManager mpm = new MapPackManager(new File("mapsources")); // System.out.println(mpm.generateMappackMD5(new File("mapsources/mp-bing.jar"))); mpm.updateMapPacks(); } catch (Exception e) { e.printStackTrace(); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/loader/MapPackClassLoader.java0000644000175000017500000000364412122526602032171 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.loader; import java.net.URL; import java.net.URLClassLoader; /** * Loads all available classes from the map source packages and everything else from the fallback * {@link ClassLoader}. Therefore in difference to the standard parent {@link ClassLoader} concept this implementation * first tries to load the and then asks the fallback whereas usually it is the opposite (first try to load via parent * and only if that fails try to do it self). */ public class MapPackClassLoader extends URLClassLoader { private final ClassLoader fallback; public MapPackClassLoader(URL url, ClassLoader fallback) { this(new URL[] { url }, fallback); } protected MapPackClassLoader(URL[] urls, ClassLoader fallback) { super(urls, null); this.fallback = fallback; } @Override protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { try { return super.loadClass(name, resolve); } catch (ClassNotFoundException e) { return fallback.loadClass(name); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/loader/CustomMapSourceLoader.java0000644000175000017500000001151712122526602032756 0ustar paulliupaulliupackage mobac.mapsources.loader; import java.io.File; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.util.Arrays; import javax.swing.JOptionPane; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; import javax.xml.bind.ValidationEvent; import javax.xml.bind.ValidationEventHandler; import javax.xml.bind.ValidationEventLocator; import mobac.exceptions.MapSourceCreateException; import mobac.mapsources.MapSourcesManager; import mobac.mapsources.custom.CustomCloudMade; import mobac.mapsources.custom.CustomLocalTileFilesMapSource; import mobac.mapsources.custom.CustomLocalTileSQliteMapSource; import mobac.mapsources.custom.CustomLocalTileZipMapSource; import mobac.mapsources.custom.CustomMapSource; import mobac.mapsources.custom.CustomMultiLayerMapSource; import mobac.mapsources.custom.CustomWmsMapSource; import mobac.program.interfaces.FileBasedMapSource; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.WrappedMapSource; import mobac.program.model.MapSourceLoaderInfo; import mobac.program.model.MapSourceLoaderInfo.LoaderType; import mobac.utilities.file.FileExtFilter; import org.apache.log4j.Logger; public class CustomMapSourceLoader implements ValidationEventHandler { private final Logger log = Logger.getLogger(MapPackManager.class); private final MapSourcesManager mapSourcesManager; private final File mapSourcesDir; private final Unmarshaller unmarshaller; public CustomMapSourceLoader(MapSourcesManager mapSourceManager, File mapSourcesDir) { this.mapSourcesManager = mapSourceManager; this.mapSourcesDir = mapSourcesDir; try { Class[] customMapClasses = new Class[] { CustomMapSource.class, CustomWmsMapSource.class, CustomMultiLayerMapSource.class, CustomCloudMade.class, CustomLocalTileFilesMapSource.class, CustomLocalTileZipMapSource.class, CustomLocalTileSQliteMapSource.class }; JAXBContext context = JAXBContext.newInstance(customMapClasses); unmarshaller = context.createUnmarshaller(); unmarshaller.setEventHandler(this); } catch (JAXBException e) { throw new RuntimeException("Unable to create JAXB context for custom map sources", e); } } public void loadCustomMapSources() { File[] customMapSourceFiles = mapSourcesDir.listFiles(new FileExtFilter(".xml")); Arrays.sort(customMapSourceFiles); for (File f : customMapSourceFiles) { try { MapSource customMapSource; Object o = unmarshaller.unmarshal(f); if (o instanceof WrappedMapSource) customMapSource = ((WrappedMapSource) o).getMapSource(); else customMapSource = (MapSource) o; customMapSource.setLoaderInfo(new MapSourceLoaderInfo(LoaderType.XML, f)); if (!(customMapSource instanceof FileBasedMapSource) && customMapSource.getTileImageType() == null) log.warn("A problem occured while loading \"" + f.getName() + "\": tileType is null - some atlas formats will produce an error!"); log.trace("Custom map source loaded: " + customMapSource + " from file \"" + f.getName() + "\""); mapSourcesManager.addMapSource(customMapSource); } catch (Exception e) { log.error("failed to load custom map source \"" + f.getName() + "\": " + e.getMessage(), e); } } } public MapSource loadCustomMapSource(InputStream in) throws MapSourceCreateException, JAXBException { MapSource customMapSource; Object o = unmarshaller.unmarshal(in); if (o instanceof WrappedMapSource) customMapSource = ((WrappedMapSource) o).getMapSource(); else customMapSource = (MapSource) o; customMapSource.setLoaderInfo(new MapSourceLoaderInfo(LoaderType.XML, null)); log.trace("Custom map source loaded: " + customMapSource); return customMapSource; } public boolean handleEvent(ValidationEvent event) { ValidationEventLocator loc = event.getLocator(); String file = loc.getURL().getFile(); try { file = URLDecoder.decode(file, "UTF-8"); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } int lastSlash = file.lastIndexOf('/'); if (lastSlash > 0) file = file.substring(lastSlash + 1); String errorMsg = event.getMessage(); if (errorMsg == null) { Throwable t = event.getLinkedException(); while (t != null && errorMsg == null) { errorMsg = t.getMessage(); t = t.getCause(); } } JOptionPane .showMessageDialog(null, "

Failed to load a custom map

" + errorMsg + "


file: \"" + file + "\"
line/column: " + loc.getLineNumber() + "/" + loc.getColumnNumber() + "

", "Error: custom map loading failed", JOptionPane.ERROR_MESSAGE); log.error(event.toString()); return false; } public static class WrappedMap { } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/loader/EclipseMapPackLoader.java0000644000175000017500000000534412122526602032507 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.loader; import java.io.File; import java.io.IOException; import java.net.URISyntaxException; import mobac.mapsources.MapSourcesManager; import mobac.program.interfaces.MapSource; import mobac.utilities.Charsets; import mobac.utilities.Utilities; import mobac.utilities.file.DirectoryFileFilter; import org.apache.log4j.Logger; /** * For map sources debugging inside eclipse. Allows to load the map sources directly from program class path instead of * the map packs. * */ public class EclipseMapPackLoader { private final Logger log = Logger.getLogger(EclipseMapPackLoader.class); private final MapSourcesManager mapSourcesManager; public EclipseMapPackLoader(MapSourcesManager mapSourcesManager) throws IOException { this.mapSourcesManager = mapSourcesManager; } public boolean loadMapPacks() throws IOException { ClassLoader cl = EclipseMapPackLoader.class.getClassLoader(); boolean success = false; File binDir; try { binDir = new File(cl.getResource(".").toURI()); } catch (URISyntaxException e) { throw new IOException(e); } File mapPackDir = new File(binDir, "mobac/mapsources/mappacks"); if (!mapPackDir.isDirectory()) return false; File[] mapPacks = mapPackDir.listFiles(new DirectoryFileFilter()); for (File d : mapPacks) { File list = new File(d, "mapsources.list"); if (!list.isFile()) continue; String listContent = new String(Utilities.getFileBytes(list), Charsets.UTF_8); String[] classNames = listContent.split("\\s+"); for (String className : classNames) { try { Class clazz = Class.forName(className); MapSource ms = (MapSource) clazz.newInstance(); mapSourcesManager.addMapSource(ms); success = true; } catch (Exception e) { log.error("className: \"" + className + "\"", e); } } } return success; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/MapSourcesManager.java0000644000175000017500000000377712122526602030655 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources; import java.util.Vector; import mobac.program.interfaces.MapSource; public abstract class MapSourcesManager { protected static MapSourcesManager INSTANCE = null; public static MapSourcesManager getInstance() { return INSTANCE; } public abstract void addMapSource(MapSource mapSource); public abstract Vector getAllMapSources(); /** * Returns all {@link MapSource} used implementations that represent a map layer (have a visible result). * Meta-map-sources like multi-layer map sources are ignored. The result does contain each {@link MapSource} only * once (no duplicates). * * @return */ public abstract Vector getAllLayerMapSources(); public abstract Vector getEnabledOrderedMapSources(); public abstract MapSource getDefaultMapSource(); public abstract MapSource getSourceByName(String name); public abstract Vector getDisabledMapSources(); /** * All means all visible map sources to the user plus all layers of multi-layer map sources * * @return */ public abstract Vector getAllAvailableMapSources(); } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/MapSourceTools.java0000644000175000017500000000675712122526602030221 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSpace; /** * Utility methods used by several map sources. */ public class MapSourceTools { protected static final char[] NUM_CHAR = { '0', '1', '2', '3' }; /** * See: http://msdn.microsoft.com/en-us/library/bb259689.aspx * * @param zoom * @param tilex * @param tiley * @return quadtree encoded tile number * */ public static String encodeQuadTree(int zoom, int tilex, int tiley) { char[] tileNum = new char[zoom]; for (int i = zoom - 1; i >= 0; i--) { // Binary encoding using ones for tilex and twos for tiley. if a bit // is set in tilex and tiley we get a three. int num = (tilex % 2) | ((tiley % 2) << 1); tileNum[i] = NUM_CHAR[num]; tilex >>= 1; tiley >>= 1; } return new String(tileNum); } /** * Calculates latitude and longitude of the upper left corner of the specified tile of mapsource * regarding the zoom level specified by zoom. * * @param mapSource * @param zoom * @param tilex * horizontal tile number * @param tiley * vertical tile number * @return double[] {lon_min , lat_min , lon_max , lat_max} */ public static double[] calculateLatLon(MapSource mapSource, int zoom, int tilex, int tiley) { MapSpace mapSpace = mapSource.getMapSpace(); int tileSize = mapSpace.getTileSize(); double[] result = new double[4]; tilex *= tileSize; tiley *= tileSize; result[0] = mapSpace.cXToLon(tilex, zoom); // lon_min result[1] = mapSpace.cYToLat(tiley + tileSize, zoom); // lat_max result[2] = mapSpace.cXToLon(tilex + tileSize, zoom); // lon_min result[3] = mapSpace.cYToLat(tiley, zoom); // lat_max return result; } public static String formatMapUrl(String mapUrl, int zoom, int tilex, int tiley) { String tmp = mapUrl; tmp = tmp.replace("{$x}", Integer.toString(tilex)); tmp = tmp.replace("{$y}", Integer.toString(tiley)); tmp = tmp.replace("{$z}", Integer.toString(zoom)); tmp = tmp.replace("{$q}", MapSourceTools.encodeQuadTree(zoom, tilex, tiley)); return tmp; } public static String formatMapUrl(String mapUrl, int serverNum, int zoom, int tilex, int tiley) { String tmp = mapUrl; tmp = tmp.replace("{$servernum}", Integer.toString(serverNum)); return formatMapUrl(tmp, zoom, tilex, tiley); } public static String formatMapUrl(String mapUrl, String serverPart, int zoom, int tilex, int tiley) { String tmp = mapUrl; tmp = tmp.replace("{$serverpart}", serverPart); return formatMapUrl(tmp, zoom, tilex, tiley); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/impl/0000755000175000017500000000000012122526602025361 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/impl/DebugLocalMapSource.java0000644000175000017500000000247512122526602032054 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.impl; import mobac.program.interfaces.FileBasedMapSource; /** * A {@link FileBasedMapSource} for debugging and testing purposes */ public class DebugLocalMapSource extends DebugMapSource implements FileBasedMapSource { public void initialize() { } public void reinitialize() { } @Override public String getName() { return "DebugLocal"; } @Override public String toString() { return "Debug (local)"; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/impl/SimpleMapSource.java0000644000175000017500000000601612122526602031277 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.impl; import java.awt.Color; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; import javax.imageio.ImageIO; import mobac.exceptions.UnrecoverableDownloadException; import mobac.mapsources.mapspace.MercatorPower2MapSpace; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSpace; import mobac.program.model.MapSourceLoaderInfo; import mobac.program.model.TileImageType; /** * A simple {@link MapSource} implementation serving as fall-back if no other map source is available/can be loaded. */ public class SimpleMapSource implements MapSource { public SimpleMapSource() { } public Color getBackgroundColor() { return Color.WHITE; } public MapSpace getMapSpace() { return MercatorPower2MapSpace.INSTANCE_256; } public int getMaxZoom() { return 2; } public int getMinZoom() { return 0; } public String getName() { return "Simple"; } public byte[] getTileData(int zoom, int x, int y, LoadMethod loadMethod) throws IOException, UnrecoverableDownloadException, InterruptedException { ByteArrayOutputStream buf = new ByteArrayOutputStream(16000); ImageIO.write(getTileImage(zoom, x, y, LoadMethod.DEFAULT), "png", buf); return buf.toByteArray(); } public BufferedImage getTileImage(int zoom, int x, int y, LoadMethod loadMethod) throws IOException, UnrecoverableDownloadException, InterruptedException { BufferedImage image = new BufferedImage(256, 256, BufferedImage.TYPE_3BYTE_BGR); Graphics2D g2 = image.createGraphics(); try { g2.setColor(Color.WHITE); g2.fillRect(0, 0, 255, 255); g2.setColor(Color.BLACK); g2.drawString("No map sources available", 8, 40); return image; } finally { g2.dispose(); } } public TileImageType getTileImageType() { return TileImageType.PNG; } public MapSourceLoaderInfo getLoaderInfo() { return null; } public void setLoaderInfo(MapSourceLoaderInfo loaderInfo) { throw new RuntimeException("LoaderInfo can not be set"); } @Override public String toString() { return ""; } } ././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/impl/DebugTransparentLocalMapSource.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/impl/DebugTransparentLocalMapSource0000644000175000017500000000754412122526602033360 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.impl; import java.awt.Color; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.security.SecureRandom; import javax.imageio.ImageIO; import mobac.exceptions.UnrecoverableDownloadException; import mobac.gui.mapview.PreviewMap; import mobac.mapsources.mapspace.MercatorPower2MapSpace; import mobac.program.interfaces.FileBasedMapSource; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSpace; import mobac.program.model.MapSourceLoaderInfo; import mobac.program.model.TileImageType; /** * A {@link FileBasedMapSource} for debugging and testing purposes */ public class DebugTransparentLocalMapSource implements MapSource, FileBasedMapSource { BufferedImage image = null; byte[] imageData = null; Color backgroundColor = new Color(0, 0, 0, 0); public Color getBackgroundColor() { return backgroundColor; } public MapSpace getMapSpace() { return MercatorPower2MapSpace.INSTANCE_256; } public int getMaxZoom() { return PreviewMap.MAX_ZOOM; } public int getMinZoom() { return 0; } @Override public TileImageType getTileImageType() { return TileImageType.PNG; } public void initialize() { } public void reinitialize() { } @Override public String getName() { return "DebugTransparentLocal"; } @Override public String toString() { return "Debug Transparent (local)"; } public byte[] getTileData(int zoom, int x, int y, LoadMethod loadMethod) throws IOException, UnrecoverableDownloadException, InterruptedException { if (imageData != null) return imageData; synchronized (this) { if (imageData != null) return imageData; ByteArrayOutputStream buf = new ByteArrayOutputStream(16000); BufferedImage image = getTileImage(zoom, x, y, loadMethod); if (image == null) return null; ImageIO.write(image, "png", buf); imageData = buf.toByteArray(); return imageData; } } public BufferedImage getTileImage(int zoom, int x, int y, LoadMethod loadMethod) throws IOException, UnrecoverableDownloadException, InterruptedException { if (image != null) return image; synchronized (this) { if (image != null) return image; BufferedImage image = new BufferedImage(256, 256, BufferedImage.TYPE_INT_ARGB); Graphics2D g2 = image.createGraphics(); SecureRandom rnd = new SecureRandom(); try { for (int i = 0; i < 100; i++) { g2.setColor(new Color(rnd.nextInt())); int x1 = rnd.nextInt(256); int y1 = rnd.nextInt(256); int x2 = rnd.nextInt(256); int y2 = rnd.nextInt(256); g2.drawLine(x1, y1, x2, y2); } g2.setColor(Color.RED); this.image = image; return image; } finally { g2.dispose(); } } } @Override public MapSourceLoaderInfo getLoaderInfo() { return null; } @Override public void setLoaderInfo(MapSourceLoaderInfo loaderInfo) { } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/impl/LocalhostTestSource.java0000644000175000017500000000274712122526602032207 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.impl; import mobac.mapsources.AbstractHttpMapSource; import mobac.program.model.TileImageType; public class LocalhostTestSource extends AbstractHttpMapSource { private String baseUrl; public LocalhostTestSource(String name, TileImageType tileType) { this(name, 80, tileType); } public LocalhostTestSource(String name, int port, TileImageType tileType) { super(name, 0, 22, tileType); baseUrl = "http://127.0.0.1:" + port + "/tile." + tileType + "?"; } public String getTileUrl(int zoom, int tilex, int tiley) { return baseUrl + "x=" + tilex + "&y=" + tiley + "&z=" + zoom; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/impl/DebugMapSource.java0000644000175000017500000001003412122526602031067 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.impl; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.awt.image.IndexColorModel; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.zip.Deflater; import mobac.exceptions.UnrecoverableDownloadException; import mobac.gui.mapview.PreviewMap; import mobac.mapsources.mapspace.MercatorPower2MapSpace; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSpace; import mobac.program.model.MapSourceLoaderInfo; import mobac.program.model.TileImageType; import mobac.utilities.imageio.Png4BitWriter; public class DebugMapSource implements MapSource { private int pngCompressionLevel = Deflater.BEST_SPEED; private static final byte[] COLORS = { 0,// (byte) 0xff, (byte) 0xff, (byte) 0xff, // white (byte) 0xcc, (byte) 0xcc, (byte) 0xcc // light gray }; private static final IndexColorModel COLORMODEL = new IndexColorModel(8, 2, COLORS, 1, false); private Color COLOR_BG = new Color(COLORS[1] & 0xFF, COLORS[2] & 0xFF, COLORS[3] & 0xFF); private Color COLOR_VG = new Color(COLORS[4] & 0xFF, COLORS[5] & 0xFF, COLORS[6] & 0xFF); private static final Font FONT_LARGE = new Font("Sans Serif", Font.BOLD, 30); public DebugMapSource() { } public Color getBackgroundColor() { return Color.BLACK; } public MapSpace getMapSpace() { return MercatorPower2MapSpace.INSTANCE_256; } public int getMaxZoom() { return PreviewMap.MAX_ZOOM; } public int getMinZoom() { return 0; } public String getName() { return "Debug"; } public byte[] getTileData(int zoom, int x, int y, LoadMethod loadMethod) throws IOException, UnrecoverableDownloadException, InterruptedException { ByteArrayOutputStream buf = new ByteArrayOutputStream(16000); // ImageIO.write(getTileImage(zoom, x, y, LoadMethod.DEFAULT), "png", buf); String pngMetaText = String.format("zoom=%d x=%d y=%d", zoom, x, y); Png4BitWriter.writeImage(buf, getTileImage(zoom, x, y, loadMethod), pngCompressionLevel, pngMetaText); return buf.toByteArray(); } public BufferedImage getTileImage(int zoom, int x, int y, LoadMethod loadMethod) throws IOException, UnrecoverableDownloadException, InterruptedException { BufferedImage image = new BufferedImage(256, 256, BufferedImage.TYPE_BYTE_INDEXED, COLORMODEL); Graphics2D g2 = image.createGraphics(); try { g2.setColor(COLOR_BG); g2.fillRect(0, 0, 255, 255); g2.setColor(COLOR_VG); g2.drawRect(0, 0, 255, 255); g2.drawRect(1, 1, 254, 254); g2.drawLine(0, 0, 255, 255); g2.drawLine(255, 0, 0, 255); g2.setFont(FONT_LARGE); g2.drawString("x: " + x, 8, 40); g2.drawString("y: " + y, 8, 75); g2.drawString("z: " + zoom, 8, 110); return image; } finally { g2.dispose(); } } public TileImageType getTileImageType() { return TileImageType.PNG; } public MapSourceLoaderInfo getLoaderInfo() { return null; } public void setLoaderInfo(MapSourceLoaderInfo loaderInfo) { throw new RuntimeException("LoaderInfo can not be set"); } @Override public String toString() { return getName(); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/impl/DebugRandomLocalMapSource.java0000644000175000017500000000753712122526602033221 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.impl; import java.awt.Color; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.security.SecureRandom; import javax.imageio.ImageIO; import mobac.exceptions.UnrecoverableDownloadException; import mobac.gui.mapview.PreviewMap; import mobac.mapsources.mapspace.MercatorPower2MapSpace; import mobac.program.interfaces.FileBasedMapSource; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSpace; import mobac.program.model.MapSourceLoaderInfo; import mobac.program.model.TileImageType; /** * A {@link FileBasedMapSource} for debugging and testing purposes */ public class DebugRandomLocalMapSource implements MapSource, FileBasedMapSource { BufferedImage image = null; byte[] imageData = null; public Color getBackgroundColor() { return Color.BLACK; } public MapSpace getMapSpace() { return MercatorPower2MapSpace.INSTANCE_256; } public int getMaxZoom() { return PreviewMap.MAX_ZOOM; } public int getMinZoom() { return 0; } @Override public TileImageType getTileImageType() { return TileImageType.PNG; } public void initialize() { } public void reinitialize() { } @Override public String getName() { return "DebugRandomLocal"; } @Override public String toString() { return "Debug Random (local)"; } public byte[] getTileData(int zoom, int x, int y, LoadMethod loadMethod) throws IOException, UnrecoverableDownloadException, InterruptedException { if (imageData != null) return imageData; synchronized (this) { if (imageData != null) return imageData; ByteArrayOutputStream buf = new ByteArrayOutputStream(16000); BufferedImage image = getTileImage(zoom, x, y, loadMethod); if (image == null) return null; ImageIO.write(image, "png", buf); imageData = buf.toByteArray(); return imageData; } } public BufferedImage getTileImage(int zoom, int x, int y, LoadMethod loadMethod) throws IOException, UnrecoverableDownloadException, InterruptedException { if (image != null) return image; synchronized (this) { if (image != null) return image; BufferedImage image = new BufferedImage(256, 256, BufferedImage.TYPE_INT_ARGB); Graphics2D g2 = image.createGraphics(); SecureRandom rnd = new SecureRandom(); try { g2.setColor(Color.WHITE); g2.fillRect(0, 0, 255, 255); for (int i = 0; i < 100; i++) { g2.setColor(new Color(rnd.nextInt())); int x1 = rnd.nextInt(256); int y1 = rnd.nextInt(256); int x2 = rnd.nextInt(256); int y2 = rnd.nextInt(256); g2.drawLine(x1, y1, x2, y2); } g2.setColor(Color.RED); this.image = image; return image; } finally { g2.dispose(); } } } @Override public MapSourceLoaderInfo getLoaderInfo() { return null; } @Override public void setLoaderInfo(MapSourceLoaderInfo loaderInfo) { } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/0000755000175000017500000000000012122526602026217 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/openstreetmap/0000755000175000017500000000000012122526602031105 5ustar paulliupaulliu././@LongLink0000000000000000000000000000016000000000000011562 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/openstreetmap/WanderreitkarteAbo.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/openstreetmap/Wanderreitka0000644000175000017500000000406612122526602033456 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.mappacks.openstreetmap; import java.io.IOException; import mobac.exceptions.TileException; import mobac.program.model.Settings; public class WanderreitkarteAbo extends AbstractOsmMapSource { public static final String ABO = "http://abo.wanderreitkarte.de"; public WanderreitkarteAbo() { super("WanderreitkarteAbo"); minZoom = 2; maxZoom = 16; } @Override public byte[] getTileData(int zoom, int x, int y, LoadMethod loadMethod) throws IOException, TileException, InterruptedException { if (loadMethod == LoadMethod.CACHE) return super.getTileData(zoom, x, y, loadMethod); // No multi threaded download possible/allowed // if we don't synchronize here we get a high percentage of errors synchronized (this) { return super.getTileData(zoom, x, y, loadMethod); } } @Override public String getTileUrl(int zoom, int tilex, int tiley) { String ticket = Settings.getInstance().osmHikingTicket; if (ticket != null && ticket.length() > 0) { return ABO + super.getTileUrl(zoom, tilex, tiley) + "/ticket/" + ticket; } else return null; } @Override public String toString() { return "Reit- und Wanderkarte ($Abo)"; } } ././@LongLink0000000000000000000000000000016000000000000011562 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/openstreetmap/OsmPublicTransport.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/openstreetmap/OsmPublicTra0000644000175000017500000000304412122526602033375 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ /** * */ package mobac.mapsources.mappacks.openstreetmap; import mobac.program.interfaces.HttpMapSource; public class OsmPublicTransport extends AbstractOsmMapSource { private static final String PATTERN = "http://tile.memomaps.de/tilegen/%d/%d/%d.png"; public OsmPublicTransport() { super("OSMPublicTransport"); this.maxZoom = 16; this.minZoom = 2; this.tileUpdate = HttpMapSource.TileUpdate.IfNoneMatch; } @Override public String getTileUrl(int zoom, int tilex, int tiley) { String url = String.format(PATTERN, new Object[] { zoom, tilex, tiley }); return url; } @Override public String toString() { return "OpenStreetMap Public Transport"; } }././@LongLink0000000000000000000000000000015000000000000011561 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/openstreetmap/mapsources.listmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/openstreetmap/mapsources.l0000644000175000017500000000073712122526602033452 0ustar paulliupaulliumobac.mapsources.mappacks.openstreetmap.CloudMade mobac.mapsources.mappacks.openstreetmap.Mapnik mobac.mapsources.mappacks.openstreetmap.Hikebikemap mobac.mapsources.mappacks.openstreetmap.OpenPisteMap mobac.mapsources.mappacks.openstreetmap.OpenSeaMap mobac.mapsources.mappacks.openstreetmap.MapQuest mobac.mapsources.mappacks.openstreetmap.Osm4uMaps mobac.mapsources.mappacks.openstreetmap.OsmPublicTransport mobac.mapsources.mappacks.openstreetmap.WanderreitkarteAbo ././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/openstreetmap/Osm4uMaps.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/openstreetmap/Osm4uMaps.ja0000644000175000017500000000253512136206506033261 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.mappacks.openstreetmap; public class Osm4uMaps extends AbstractOsmMapSource { private static String SERVER = "http://4umaps.eu"; public Osm4uMaps() { super("4uMaps"); minZoom = 2; maxZoom = 15; tileUpdate = TileUpdate.IfNoneMatch; } @Override public String getTileUrl(int zoom, int tilex, int tiley) { return SERVER + super.getTileUrl(zoom, tilex, tiley); } @Override public String toString() { return "OpenStreetMap 4UMaps.eu"; } } ././@LongLink0000000000000000000000000000016200000000000011564 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/openstreetmap/AbstractOsmMapSource.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/openstreetmap/AbstractOsmM0000644000175000017500000000361512122526602033374 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.mappacks.openstreetmap; import java.net.HttpURLConnection; import mobac.mapsources.AbstractHttpMapSource; import mobac.program.ProgramInfo; import mobac.program.interfaces.MapSourceTextAttribution; import mobac.program.model.TileImageType; public abstract class AbstractOsmMapSource extends AbstractHttpMapSource implements MapSourceTextAttribution { public AbstractOsmMapSource(String name) { super(name, 0, 18, TileImageType.PNG); } public String getTileUrl(int zoom, int tilex, int tiley) { return "/" + zoom + "/" + tilex + "/" + tiley + ".png"; } public TileImageType getTileImageType() { return TileImageType.PNG; } @Override protected void prepareTileUrlConnection(HttpURLConnection conn) { super.prepareTileUrlConnection(conn); conn.setRequestProperty("User-agent", ProgramInfo.getUserAgent()); } public String getAttributionText() { return "© OpenStreetMap contributors, CC-BY-SA"; } public String getAttributionLinkURL() { return "http://openstreetmap.org"; } }././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/openstreetmap/OpenPisteMap.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/openstreetmap/OpenPisteMap0000644000175000017500000001022712122526602033376 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ /** * */ package mobac.mapsources.mappacks.openstreetmap; import java.io.IOException; import java.net.HttpURLConnection; import mobac.exceptions.DownloadFailedException; import mobac.exceptions.StopAllDownloadsException; import mobac.exceptions.TileException; import mobac.mapsources.AbstractMultiLayerMapSource; import mobac.program.interfaces.HttpMapSource; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSourceTextAttribution; import mobac.program.model.TileImageType; public class OpenPisteMap extends AbstractMultiLayerMapSource implements MapSourceTextAttribution { private static final String BASE = "http://tiles.openpistemap.org/nocontours"; //private static final String CONTOURS = "http://tiles.openpistemap.org/contours-only"; private static final String LAMDSHED = "http://tiles2.openpistemap.org/landshaded"; public OpenPisteMap() { super("OpenPisteMapBCL", TileImageType.PNG); mapSources = new MapSource[] { new Mapnik(), new OpenPisteMapBase(), new OpenPisteMapLandshed()/*, new OpenPisteMapContours()*/ }; initializeValues(); } @Override public String toString() { return "Open Piste Map"; } public String getAttributionText() { return "© OpenStreetMap contributors, CC-BY-SA"; } public String getAttributionLinkURL() { return "http://openstreetmap.org"; } public static abstract class AbstractOpenPisteMap extends AbstractOsmMapSource { public AbstractOpenPisteMap(String name) { super(name); } @Override public byte[] getTileData(int zoom, int x, int y, LoadMethod loadMethod) throws IOException, TileException, InterruptedException { try { return super.getTileData(zoom, x, y, loadMethod); } catch (DownloadFailedException e) { if (e.getHttpResponseCode() == HttpURLConnection.HTTP_FORBIDDEN) { throw new StopAllDownloadsException("Server blocks mass download - aborting map dowload", e); } else throw e; } } } public static class OpenPisteMapBase extends AbstractOpenPisteMap { public OpenPisteMapBase() { super("OpenPisteMap"); maxZoom = 17; tileUpdate = HttpMapSource.TileUpdate.LastModified; } @Override public String toString() { return "Open Piste Contours Layer"; } public String getTileUrl(int zoom, int tilex, int tiley) { return BASE + super.getTileUrl(zoom, tilex, tiley); } } // public static class OpenPisteMapContours extends AbstractOpenPisteMap { // // public OpenPisteMapContours() { // super("OpenPisteMapCont"); // maxZoom = 17; // tileUpdate = HttpMapSource.TileUpdate.LastModified; // } // // @Override // public String toString() { // return "Open Piste Map Base Layer"; // } // // public String getTileUrl(int zoom, int tilex, int tiley) { // return CONTOURS + super.getTileUrl(zoom, tilex, tiley); // } // // } public static class OpenPisteMapLandshed extends AbstractOpenPisteMap { public OpenPisteMapLandshed() { super("OpenPisteMapLandshed"); maxZoom = 17; tileUpdate = HttpMapSource.TileUpdate.LastModified; } @Override public String toString() { return "Open Piste Landshed Layer"; } public String getTileUrl(int zoom, int tilex, int tiley) { return LAMDSHED + super.getTileUrl(zoom, tilex, tiley); } } }mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/openstreetmap/Mapnik.java0000644000175000017500000000367012122526602033175 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.mappacks.openstreetmap; import java.io.IOException; import java.util.concurrent.Semaphore; import mobac.exceptions.TileException; public class Mapnik extends AbstractOsmMapSource { private static final String MAP_MAPNIK = "http://tile.openstreetmap.org"; /** * Maximum of 2 download threads * * @see http://wiki.openstreetmap.org/wiki/Tile_usage_policy */ private static final Semaphore SEM = new Semaphore(2); public Mapnik() { super("Mapnik"); maxZoom = 16; } @Override public byte[] getTileData(int zoom, int x, int y, LoadMethod loadMethod) throws IOException, TileException, InterruptedException { SEM.acquire(); try { return super.getTileData(zoom, x, y, loadMethod); } finally { SEM.release(); } } @Override public String getTileUrl(int zoom, int tilex, int tiley) { return MAP_MAPNIK + super.getTileUrl(zoom, tilex, tiley); } public TileUpdate getTileUpdate() { return TileUpdate.IfNoneMatch; } @Override public String toString() { return "OpenStreetMap Mapnik"; } } ././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/openstreetmap/CloudMade.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/openstreetmap/CloudMade.ja0000644000175000017500000000503012122526602033254 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.mappacks.openstreetmap; import mobac.exceptions.MapSourceInitializationException; import mobac.mapsources.MapSourceUrlUpdater; import mobac.utilities.Charsets; public class CloudMade extends AbstractOsmMapSource { static { // Initialize the custom CludMade loader try { Class c = Class.forName("mobac.mapsources.custom.CustomCloudMade"); c.getField("CLOUD_MADE_CLASS").set(c, CloudMade.class); } catch (Exception e) { } } private static final String INIT_REGEX = "\"api_key\"\\:\"([A-F0-9]+)\""; private String styleID; private String displayName; private String apiKey = ""; private static final String PATTERN = "http://%s.tile.cloudmade.com/%s/%s/256/%d/%d/%d.png"; private static final String[] SERVER = { "a", "b", "c" }; private int SERVER_NUM = 0; public CloudMade(String styleID, String displayName) { super("OSM CloudMade " + styleID); this.displayName = displayName; this.styleID = styleID; this.maxZoom = 18; this.tileUpdate = TileUpdate.IfModifiedSince; } public CloudMade() { this("1", "OpenStreetMap CloudMade Default Style"); } @Override protected void initernalInitialize() throws MapSourceInitializationException { apiKey = MapSourceUrlUpdater.loadDocumentAndExtractGroup("http://maps.cloudmade.com/", Charsets.UTF_8, INIT_REGEX); } @Override public String getTileUrl(int zoom, int tilex, int tiley) { String url = String.format(PATTERN, new Object[] { SERVER[SERVER_NUM], apiKey, styleID, zoom, tilex, tiley }); SERVER_NUM = (SERVER_NUM + 1) % SERVER.length; return url; } @Override public String toString() { return displayName; } } ././@LongLink0000000000000000000000000000015100000000000011562 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/openstreetmap/Hikebikemap.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/openstreetmap/Hikebikemap.0000644000175000017500000000527312122526602033326 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ /** * */ package mobac.mapsources.mappacks.openstreetmap; import java.awt.image.BufferedImage; import java.io.IOException; import mobac.exceptions.TileException; import mobac.mapsources.AbstractHttpMapSource; import mobac.mapsources.AbstractMultiLayerMapSource; import mobac.program.interfaces.HttpMapSource; import mobac.program.interfaces.MapSource; import mobac.program.model.TileImageType; public class Hikebikemap extends AbstractMultiLayerMapSource { public Hikebikemap() { super("OpenStreetMap Hikebikemap.de", TileImageType.PNG); mapSources = new MapSource[] { new HikebikemapBase(), new HikebikemapRelief() }; initializeValues(); } /** * http://hikebikemap.de/ */ public static class HikebikemapBase extends AbstractHttpMapSource { public HikebikemapBase() { super("HikebikemapTiles", 0, 17, TileImageType.PNG, HttpMapSource.TileUpdate.None); } @Override public String toString() { return "OpenStreetMap Hikebikemap Map"; } public String getTileUrl(int zoom, int tilex, int tiley) { return "http://toolserver.org/tiles/hikebike/" + zoom + "/" + tilex + "/" + tiley + ".png"; } } /** * Hill shades / relief * * http://hikebikemap.de/ */ public static class HikebikemapRelief extends AbstractHttpMapSource { public HikebikemapRelief() { super("HikebikemapRelief", 0, 17, TileImageType.PNG, HttpMapSource.TileUpdate.None); } public String getTileUrl(int zoom, int tilex, int tiley) { return "http://toolserver.org/~cmarqu/hill/" + zoom + "/" + tilex + "/" + tiley + ".png"; } @Override public BufferedImage getTileImage(int zoom, int x, int y, LoadMethod loadMethod) throws IOException, TileException, InterruptedException { if (zoom > 16) return null; return super.getTileImage(zoom, x, y, loadMethod); } } }././@LongLink0000000000000000000000000000015000000000000011561 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/openstreetmap/OpenSeaMap.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/openstreetmap/OpenSeaMap.j0000644000175000017500000000736612122526602033264 0ustar paulliupaulliupackage mobac.mapsources.mappacks.openstreetmap; import java.awt.Color; import java.awt.Image; import java.awt.Toolkit; import java.awt.image.BufferedImage; import java.awt.image.FilteredImageSource; import java.awt.image.ImageFilter; import java.awt.image.ImageProducer; import java.awt.image.RGBImageFilter; import java.io.ByteArrayInputStream; import java.io.FileNotFoundException; import java.io.IOException; import mobac.exceptions.TileException; import mobac.exceptions.UnrecoverableDownloadException; import mobac.mapsources.AbstractHttpMapSource; import mobac.mapsources.AbstractMultiLayerMapSource; import mobac.program.Logging; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSourceTextAttribution; import mobac.program.model.TileImageType; import mobac.program.tilestore.TileStore; import mobac.utilities.Utilities; /** * http://openseamap.org/ * @see OpenSeaMapLayer */ public class OpenSeaMap extends AbstractMultiLayerMapSource implements MapSourceTextAttribution { public static final String LAYER_OPENSEA = "http://tiles.openseamap.org/seamark/"; public OpenSeaMap() { super("OpenSeaMap", TileImageType.PNG); mapSources = new MapSource[] { new Mapnik(), new OpenSeaMapLayer() }; initializeValues(); } public String getAttributionText() { return "© OpenStreetMap contributors, CC-BY-SA"; } public String getAttributionLinkURL() { return "http://openstreetmap.org"; } /** * Not working correctly: * * 1. The map is a "sparse map" (only tiles are present that have content - the other are missing)
* 2. The map layer's background is not transparent! */ public static class OpenSeaMapLayer extends AbstractHttpMapSource { public OpenSeaMapLayer() { super("OpenSeaMapLayer", 11, 17, TileImageType.PNG, TileUpdate.LastModified); } public String getTileUrl(int zoom, int tilex, int tiley) { return LAYER_OPENSEA + zoom + "/" + tilex + "/" + tiley + ".png"; } @Override public byte[] getTileData(int zoom, int x, int y, LoadMethod loadMethod) throws IOException, InterruptedException, TileException { byte[] data = super.getTileData(zoom, x, y, loadMethod); if (data != null && data.length == 0) { log.info("loaded non-existing tile"); return null; } return data; } @Override public BufferedImage getTileImage(int zoom, int x, int y, LoadMethod loadMethod) throws IOException, UnrecoverableDownloadException, InterruptedException { try { byte[] data = getTileData(zoom, x, y, loadMethod); if (data == null) { return null; } com.sixlegs.png.PngImage png = new com.sixlegs.png.PngImage(); BufferedImage image = png.read(new ByteArrayInputStream(data), true); return image; } catch (FileNotFoundException e) { TileStore ts = TileStore.getInstance(); ts.putTile(ts.createNewEmptyEntry(x, y, zoom), this); } catch (Exception e) { Logging.LOG.error("Unknown error in OpenSeaMap", e); } return null; } @Override public Color getBackgroundColor() { return Utilities.COLOR_TRANSPARENT; } } public static Image makeColorTransparent(Image im, final Color color) { ImageFilter filter = new RGBImageFilter() { // the color we are looking for... Alpha bits are set to opaque public int markerRGB = color.getRGB() | 0xFF000000; public final int filterRGB(int x, int y, int rgb) { if ((rgb | 0xFF000000) == markerRGB) { // Mark the alpha bits as zero - transparent return 0x00FFFFFF & rgb; } else { // nothing to do return rgb; } } }; ImageProducer ip = new FilteredImageSource(im.getSource(), filter); return Toolkit.getDefaultToolkit().createImage(ip); } }././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/openstreetmap/MapQuest.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/openstreetmap/MapQuest.jav0000644000175000017500000000421012122526602033343 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.mappacks.openstreetmap; import java.io.IOException; import java.util.concurrent.Semaphore; import mobac.exceptions.TileException; import mobac.program.model.TileImageType; public class MapQuest extends AbstractOsmMapSource { private static String[] SERVERS = { "otile1", "otile2", "otile3", "otile4" }; private static int SERVER_NUM = 0; private static final Semaphore SEM = new Semaphore(2); public MapQuest() { super("MapQuest"); minZoom = 0; maxZoom = 18; tileUpdate = TileUpdate.IfModifiedSince; } @Override public byte[] getTileData(int zoom, int x, int y, LoadMethod loadMethod) throws IOException, TileException, InterruptedException { SEM.acquire(); try { return super.getTileData(zoom, x, y, loadMethod); } finally { SEM.release(); } } @Override public TileImageType getTileImageType() { return TileImageType.JPG; } @Override public String getTileUrl(int zoom, int tilex, int tiley) { String server = SERVERS[SERVER_NUM]; SERVER_NUM = (SERVER_NUM + 1) % SERVERS.length; String baseUrl = "http://" + server + ".mqcdn.com/tiles/1.0.0/osm"; return baseUrl + super.getTileUrl(zoom, tilex, tiley); } @Override public String toString() { return "OpenStreetMap MapQuest"; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_europe_east/0000755000175000017500000000000012122526602032075 5ustar paulliupaulliu././@LongLink0000000000000000000000000000015300000000000011564 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_europe_east/UmpWawPl.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_europe_east/UmpWawP0000644000175000017500000000331612122526602033363 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.mappacks.region_europe_east; import mobac.mapsources.AbstractHttpMapSource; import mobac.program.model.TileImageType; /** * Darmowa Mapa Polski dla GPS Garmin - UMP-pcPL (added by "maniek-ols") *

* ump.waw.pl *

*/ public class UmpWawPl extends AbstractHttpMapSource { private static int SERVER_NUM = 0; private static final int MAX_SERVER_NUM = 4; public UmpWawPl() { super("UMP-pcPL", 0, 18, TileImageType.PNG, TileUpdate.LastModified); } public String getTileUrl(int zoom, int tilex, int tiley) { String s = "http://" + SERVER_NUM + ".tiles.ump.waw.pl/ump_tiles/" + zoom + "/" + tilex + "/" + tiley + ".png"; SERVER_NUM = (SERVER_NUM + 1) % MAX_SERVER_NUM; return s; } @Override public String toString() { return getName() + " (Poland only)"; } } ././@LongLink0000000000000000000000000000017000000000000011563 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_europe_east/FreemapSlovakiaHiking.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_europe_east/Freemap0000644000175000017500000000345212122526602033403 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.mappacks.region_europe_east; import mobac.mapsources.AbstractHttpMapSource; import mobac.program.interfaces.MapSourceTextAttribution; import mobac.program.model.TileImageType; /** * http://www.freemap.sk * * @author SourceForge.net user didoa, nickn17 */ public class FreemapSlovakiaHiking extends AbstractHttpMapSource implements MapSourceTextAttribution { public FreemapSlovakiaHiking() { super("FreemapSlovakiaHiking", 6, 16, TileImageType.PNG, TileUpdate.IfModifiedSince); } public String getTileUrl(int zoom, int tilex, int tiley) { return "http://a.freemap.sk/data/layers/presets/T/" + zoom + "/" + tilex + "/" + tiley + ".png"; } @Override public String toString() { return "Freemap Slovakia Hiking"; } public String getAttributionText() { return "© OpenStreetMap contributors, CC-BY-SA"; } public String getAttributionLinkURL() { return "http://openstreetmap.org"; } } ././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_europe_east/mapsources.listmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_europe_east/mapsour0000644000175000017500000000075612122526602033516 0ustar paulliupaulliumobac.mapsources.mappacks.region_europe_east.UmpWawPl mobac.mapsources.mappacks.region_europe_east.FreemapSlovakia mobac.mapsources.mappacks.region_europe_east.FreemapSlovakiaCycling mobac.mapsources.mappacks.region_europe_east.FreemapSlovakiaHiking mobac.mapsources.mappacks.region_europe_east.MoldovaPointMd mobac.mapsources.mappacks.region_europe_east.Turaterkep mobac.mapsources.mappacks.region_europe_east.OSMapaTopo mobac.mapsources.mappacks.region_europe_east.OSMapaTopoContours ././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_europe_east/Turaterkep.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_europe_east/Turater0000644000175000017500000000126412122526602033451 0ustar paulliupaulliupackage mobac.mapsources.mappacks.region_europe_east; import java.awt.Color; import mobac.mapsources.AbstractHttpMapSource; import mobac.program.model.TileImageType; /** * */ public class Turaterkep extends AbstractHttpMapSource { public Turaterkep() { super("Turaterkep256", 7, 15, TileImageType.PNG, TileUpdate.IfModifiedSince); } public String getTileUrl(int zoom, int x, int y) { return "http://a.map.turistautak.hu/tiles/turistautak-domborzattal/" + zoom + "/" + x + "/" + y + ".png"; } @Override public String toString() { return "Turaterkep (Hungary)"; } @Override public Color getBackgroundColor() { return Color.WHITE; } }././@LongLink0000000000000000000000000000016100000000000011563 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_europe_east/MoldovaPointMd.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_europe_east/Moldova0000644000175000017500000000331412122526602033422 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.mappacks.region_europe_east; import mobac.mapsources.AbstractHttpMapSource; import mobac.program.model.TileImageType; /** * Institute of Geodesy Technical Research and Cadastre "INGEOCAD" under Sate Agency of Land * Relations and Cadastre Tiles created by and sourced from point.md * * http://point.md/Map/#x=28.870983&y=47.017756&z=10 * * https://sourceforge.net/tracker/?func=detail&atid=1105497&aid=3321793&group_id=238075 */ public class MoldovaPointMd extends AbstractHttpMapSource { public MoldovaPointMd() { super("MoldovaPointMd", 8, 18, TileImageType.PNG, TileUpdate.None); } public String getTileUrl(int zoom, int x, int y) { return "http://point.md/map/Map/GetTile?path=1/" + zoom + "/" + x + "/" + y + ".png"; } @Override public String toString() { return "Moldova (point.md)"; } } ././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_europe_east/OSMapaTopo.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_europe_east/OSMapaT0000644000175000017500000000351512122526602033270 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.mappacks.region_europe_east; import mobac.mapsources.AbstractHttpMapSource; import mobac.program.interfaces.MapSourceTextAttribution; import mobac.program.model.TileImageType; /** * http://osm.trail.pl/ol.xhtml * http://sourceforge.net/tracker/?func=detail&aid=3379692&group_id=238075&atid=1105497 */ public class OSMapaTopo extends AbstractHttpMapSource implements MapSourceTextAttribution { public OSMapaTopo() { super("OSMapaTopo", 7, 18, TileImageType.PNG, TileUpdate.IfNoneMatch); } public String getTileUrl(int zoom, int x, int y) { return "http://osm.trail.pl/bezpoziomic/" + zoom + "/" + x + "/" + y + ".png"; } @Override public String toString() { return "OSMapa-Topo (Poland)"; } public String getAttributionText() { // http://wiki.openstreetmap.pl/Serwer_kafelk%C3%B3w_TRAIL return "© Data OpenStreetMap, Hosting TRAIL.PL and centuria.pl"; } public String getAttributionLinkURL() { return null; } } ././@LongLink0000000000000000000000000000016200000000000011564 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_europe_east/FreemapSlovakia.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_europe_east/Freemap0000644000175000017500000000343312122526602033402 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.mappacks.region_europe_east; import mobac.mapsources.AbstractHttpMapSource; import mobac.program.interfaces.MapSourceTextAttribution; import mobac.program.model.TileImageType; /** * http://www.freemap.sk * * @author SourceForge.net user didoa, nickn17 */ public class FreemapSlovakia extends AbstractHttpMapSource implements MapSourceTextAttribution { public FreemapSlovakia() { super("FreemapSlovakia", 5, 16, TileImageType.PNG, TileUpdate.IfModifiedSince); } public String getTileUrl(int zoom, int tilex, int tiley) { return "http://a.freemap.sk/data/layers/presets/A/" + zoom + "/" + tilex + "/" + tiley + ".png"; } @Override public String toString() { return "Freemap Slovakia Car Atlas"; } public String getAttributionText() { return "© OpenStreetMap contributors, CC-BY-SA"; } public String getAttributionLinkURL() { return "http://openstreetmap.org"; } } ././@LongLink0000000000000000000000000000016500000000000011567 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_europe_east/OSMapaTopoContours.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_europe_east/OSMapaT0000644000175000017500000000354312122526602033271 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.mappacks.region_europe_east; import mobac.mapsources.AbstractHttpMapSource; import mobac.program.interfaces.MapSourceTextAttribution; import mobac.program.model.TileImageType; /** * http://osm.trail.pl/ol.xhtml * http://sourceforge.net/tracker/?func=detail&aid=3379692&group_id=238075&atid=1105497 */ public class OSMapaTopoContours extends AbstractHttpMapSource implements MapSourceTextAttribution { public OSMapaTopoContours() { super("OSMapaTopoContours", 0, 18, TileImageType.PNG, TileUpdate.IfNoneMatch); } public String getTileUrl(int zoom, int x, int y) { return "http://osm.trail.pl/" + zoom + "/" + x + "/" + y + ".png"; } @Override public String toString() { return "OSMapa-Topo with contours (PL)"; } public String getAttributionText() { // http://wiki.openstreetmap.pl/Serwer_kafelk%C3%B3w_TRAIL return "© Data OpenStreetMap, Hosting TRAIL.PL and centuria.pl"; } public String getAttributionLinkURL() { return null; } } ././@LongLink0000000000000000000000000000017100000000000011564 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_europe_east/FreemapSlovakiaCycling.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_europe_east/Freemap0000644000175000017500000000337112122526602033403 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.mappacks.region_europe_east; import mobac.mapsources.AbstractHttpMapSource; import mobac.program.interfaces.MapSourceTextAttribution; import mobac.program.model.TileImageType; /** * http://www.freemap.sk */ public class FreemapSlovakiaCycling extends AbstractHttpMapSource implements MapSourceTextAttribution { public FreemapSlovakiaCycling() { super("FreemapSlovakiaCyclo", 6, 16, TileImageType.PNG, TileUpdate.IfModifiedSince); } public String getTileUrl(int zoom, int tilex, int tiley) { return "http://a.freemap.sk/data/layers/presets/C/" + zoom + "/" + tilex + "/" + tiley + ".png"; } @Override public String toString() { return "Freemap Slovakia Cycle Map"; } public String getAttributionText() { return "© OpenStreetMap contributors, CC-BY-SA"; } public String getAttributionLinkURL() { return "http://openstreetmap.org"; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_oceania/0000755000175000017500000000000012122526602031161 5ustar paulliupaulliu././@LongLink0000000000000000000000000000015100000000000011562 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_oceania/mapsources.listmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_oceania/mapsources.0000644000175000017500000000006312122526602033342 0ustar paulliupaulliumobac.mapsources.mappacks.region_oceania.NzTopoMaps././@LongLink0000000000000000000000000000015100000000000011562 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_oceania/NzTopoMaps.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_oceania/NzTopoMaps.0000644000175000017500000000453112122526602033237 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.mappacks.region_oceania; import java.net.HttpURLConnection; import mobac.mapsources.AbstractHttpMapSource; import mobac.program.interfaces.MapSourceTextAttribution; import mobac.program.model.TileImageType; /** *
 * New Zealand Topographic Maps produced by Land Information New Zealand (Government Department).
 * http://www.linz.govt.nz/topography/topo-maps/index.aspx 
 * 
 * Licence: Creative Commons Attribution 3.0 New Zealand
 * (http://creativecommons.org/licenses/by/3.0/nz/deed.en) 
 * 
 * Tiles created by and sourced from nztopomaps.com
 * 
* http://www.nztopomaps.com/ */ public class NzTopoMaps extends AbstractHttpMapSource implements MapSourceTextAttribution { public NzTopoMaps() { super("New Zealand Topographic Maps", 6, 15, TileImageType.PNG, TileUpdate.IfNoneMatch); } public String getTileUrl(int zoom, int x, int y) { // nzy = 2^zoom - 1 - y int nzy = (1 << zoom) - 1 - y; return "http://nz1.nztopomaps.com/" + zoom + "/" + x + "/" + nzy + ".png"; } @Override protected void prepareTileUrlConnection(HttpURLConnection conn) { super.prepareTileUrlConnection(conn); conn.addRequestProperty("Referer", "http://m.nztopomaps.com"); } @Override public String toString() { return "nztopomaps.com (New Zealand only)"; } public String getAttributionText() { return "Images sourced from NZTopo database"; } public String getAttributionLinkURL() { return "http://nztopomaps.com"; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_america_north/0000755000175000017500000000000012122526602032375 5ustar paulliupaulliu././@LongLink0000000000000000000000000000016400000000000011566 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_america_north/ChartbundleENRH.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_america_north/Chart0000644000175000017500000000307512122526602033366 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.mappacks.region_america_north; import mobac.mapsources.AbstractHttpMapSource; import mobac.program.model.TileImageType; /** * https://sourceforge.net/tracker/?func=detail&atid=1105497&aid=3376462&group_id=238075 * * http://www.chartbundle.com/charts/ */ public class ChartbundleENRH extends AbstractHttpMapSource { public ChartbundleENRH() { super("cb-enrh", 4, 12, TileImageType.PNG, TileUpdate.None); } @Override public String toString() { return "Chartbundle US Enroute High Charts"; } public String getTileUrl(int zoom, int tilex, int tiley) { return "http://wms.chartbundle.com/tms/v1.0/enrh/" + zoom + "/" + tilex + "/" + tiley + ".png?type=google"; } }././@LongLink0000000000000000000000000000017000000000000011563 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_america_north/USNationalMapRelief.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_america_north/USNat0000644000175000017500000000271212122526602033314 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.mappacks.region_america_north; import mobac.mapsources.AbstractHttpMapSource; import mobac.program.model.TileImageType; /** * Unused */ public class USNationalMapRelief extends AbstractHttpMapSource { public USNationalMapRelief() { super("USGS National Map Relief", 0, 6, TileImageType.JPG, TileUpdate.IfNoneMatch); } private static final String BASE_URL = "http://raster1.nationalmap.gov/ArcGIS/rest/services/TNM_Small_Scale_Shaded_Relief/MapServer/tile/"; public String getTileUrl(int zoom, int x, int y) { return BASE_URL + zoom + "/" + y + "/" + x; } }././@LongLink0000000000000000000000000000016600000000000011570 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_america_north/USNationalMapBase.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_america_north/USNat0000644000175000017500000000361712122526602033321 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.mappacks.region_america_north; import mobac.mapsources.AbstractHttpMapSource; import mobac.program.model.TileImageType; /** * http://viewer.nationalmap.gov/example/services.html */ public class USNationalMapBase extends AbstractHttpMapSource { public USNationalMapBase() { super("USGS National Map Base", 0, 15, TileImageType.JPG, TileUpdate.ETag); } public String getTileUrl(int zoom, int x, int y) { return "http://basemap.nationalmap.gov/ArcGIS/rest/services/USGSTopo/MapServer/tile/" + zoom + "/" + y + "/" + x; } // http://basemap.nationalmap.gov/ArcGIS/rest/services/USGSTopo/MapServer/tile/6/23/11 // http://basemap.nationalmap.gov/ArcGIS/rest/services/USGSImageryOnly/MapServer/tile/4/7/3 // http://basemap.nationalmap.gov/ArcGIS/rest/services/TNM_Vector_Fills_Small/MapServer/tile/4/6/1 // http://basemap.nationalmap.gov/ArcGIS/rest/services/TNM_Vector_Small/MapServer/tile/4/6/2 // http://raster1.nationalmap.gov/ArcGIS/rest/services/TNM_Small_Scale_Shaded_Relief/MapServer/tile/4/7/6 }././@LongLink0000000000000000000000000000015700000000000011570 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_america_north/mapsources.listmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_america_north/mapso0000644000175000017500000000141312122526602033436 0ustar paulliupaulliumobac.mapsources.mappacks.region_america_north.FAA_Aeromaps mobac.mapsources.mappacks.region_america_north.ChartbundleENRA mobac.mapsources.mappacks.region_america_north.ChartbundleENRH mobac.mapsources.mappacks.region_america_north.ChartbundleENRL mobac.mapsources.mappacks.region_america_north.ChartbundleSEC mobac.mapsources.mappacks.region_america_north.ChartbundleTAC mobac.mapsources.mappacks.region_america_north.ChartbundleWAC mobac.mapsources.mappacks.region_america_north.USNationalMapBase mobac.mapsources.mappacks.region_america_north.USNationalMapImagery mobac.mapsources.mappacks.region_america_north.USNationalMapImageryV mobac.mapsources.mappacks.region_america_north.USNationalMapVector mobac.mapsources.mappacks.region_america_north.USNationalMapTopo././@LongLink0000000000000000000000000000016600000000000011570 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_america_north/USNationalMapTopo.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_america_north/USNat0000644000175000017500000000263312122526602033316 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.mappacks.region_america_north; import mobac.mapsources.AbstractHttpMapSource; import mobac.program.model.TileImageType; public class USNationalMapTopo extends AbstractHttpMapSource { public USNationalMapTopo() { super("USGS National Map Topo", 0, 15, TileImageType.JPG, TileUpdate.IfNoneMatch); } private static final String BASE_URL = "http://basemap.nationalmap.gov/ArcGIS/rest/services/USGSTopo/MapServer/tile/"; public String getTileUrl(int zoom, int x, int y) { return BASE_URL + zoom + "/" + y + "/" + x; } }././@LongLink0000000000000000000000000000016400000000000011566 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_america_north/ChartbundleENRA.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_america_north/Chart0000644000175000017500000000306512122526602033365 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.mappacks.region_america_north; import mobac.mapsources.AbstractHttpMapSource; import mobac.program.model.TileImageType; /** * https://sourceforge.net/tracker/?func=detail&atid=1105497&aid=3376462&group_id=238075 * * http://www.chartbundle.com/charts/ */ public class ChartbundleENRA extends AbstractHttpMapSource { public ChartbundleENRA() { super("cb-enra", 4, 13, TileImageType.PNG, TileUpdate.None); } @Override public String toString() { return "Chartbundle US Area Charts"; } public String getTileUrl(int zoom, int tilex, int tiley) { return "http://wms.chartbundle.com/tms/v1.0/enra/" + zoom + "/" + tilex + "/" + tiley + ".png?type=google"; } }././@LongLink0000000000000000000000000000016400000000000011566 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_america_north/ChartbundleENRL.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_america_north/Chart0000644000175000017500000000307412122526602033365 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.mappacks.region_america_north; import mobac.mapsources.AbstractHttpMapSource; import mobac.program.model.TileImageType; /** * https://sourceforge.net/tracker/?func=detail&atid=1105497&aid=3376462&group_id=238075 * * http://www.chartbundle.com/charts/ */ public class ChartbundleENRL extends AbstractHttpMapSource { public ChartbundleENRL() { super("cb-enrl", 4, 13, TileImageType.PNG, TileUpdate.None); } @Override public String toString() { return "Chartbundle US Enroute Low Charts"; } public String getTileUrl(int zoom, int tilex, int tiley) { return "http://wms.chartbundle.com/tms/v1.0/enrl/" + zoom + "/" + tilex + "/" + tiley + ".png?type=google"; } }././@LongLink0000000000000000000000000000016500000000000011567 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_america_north/USNationalMapVFS.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_america_north/USNat0000644000175000017500000000266412122526602033322 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.mappacks.region_america_north; import mobac.mapsources.AbstractHttpMapSource; import mobac.program.model.TileImageType; public class USNationalMapVFS extends AbstractHttpMapSource { public USNationalMapVFS() { super("USGS National Map VectorFills Layer", 0, 13, TileImageType.JPG, TileUpdate.IfNoneMatch); } private static final String BASE_URL = "http://basemap.nationalmap.gov/ArcGIS/rest/services/TNM_Vector_Fills_Small/MapServer/tile/"; public String getTileUrl(int zoom, int x, int y) { return BASE_URL + zoom + "/" + y + "/" + x; } }././@LongLink0000000000000000000000000000016300000000000011565 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_america_north/ChartbundleWAC.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_america_north/Chart0000644000175000017500000000307712122526602033370 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.mappacks.region_america_north; import mobac.mapsources.AbstractHttpMapSource; import mobac.program.model.TileImageType; /** * https://sourceforge.net/tracker/?func=detail&atid=1105497&aid=3376462&group_id=238075 * * http://www.chartbundle.com/charts/ */ public class ChartbundleWAC extends AbstractHttpMapSource { public ChartbundleWAC() { super("cb-wac", 4, 12, TileImageType.PNG, TileUpdate.None); } @Override public String toString() { return "Chartbundle US World Aeronautical Charts"; } public String getTileUrl(int zoom, int tilex, int tiley) { return "http://wms.chartbundle.com/tms/v1.0/wac/" + zoom + "/" + tilex + "/" + tiley + ".png?type=google"; } }././@LongLink0000000000000000000000000000016100000000000011563 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_america_north/FAA_Aeromaps.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_america_north/FAA_A0000644000175000017500000000247412122526602033156 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.mappacks.region_america_north; import mobac.mapsources.AbstractHttpMapSource; import mobac.program.model.TileImageType; public class FAA_Aeromaps extends AbstractHttpMapSource { public FAA_Aeromaps() { super("FAA Sectional Charts", 4, 12, TileImageType.PNG, TileUpdate.LastModified); } public String getTileUrl(int zoom, int tilex, int tiley) { return "http://aeromaps.us/Z" + zoom + "/" + tiley + "/" + tilex + ".png"; } }././@LongLink0000000000000000000000000000016400000000000011566 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_america_north/USNationalMapVS.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_america_north/USNat0000644000175000017500000000264712122526602033323 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.mappacks.region_america_north; import mobac.mapsources.AbstractHttpMapSource; import mobac.program.model.TileImageType; public class USNationalMapVS extends AbstractHttpMapSource { public USNationalMapVS() { super("USGS National Map Vector Layer", 0, 15, TileImageType.PNG, TileUpdate.IfNoneMatch); } private static final String BASE_URL = "http://basemap.nationalmap.gov/ArcGIS/rest/services/TNM_Vector_Small/MapServer/tile/"; public String getTileUrl(int zoom, int x, int y) { return BASE_URL + zoom + "/" + y + "/" + x; } }././@LongLink0000000000000000000000000000017200000000000011565 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_america_north/USNationalMapImageryV.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_america_north/USNat0000644000175000017500000000300312122526602033306 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ /** * */ package mobac.mapsources.mappacks.region_america_north; import java.awt.Color; import mobac.mapsources.AbstractMultiLayerMapSource; import mobac.program.interfaces.MapSource; import mobac.program.model.TileImageType; /** * http://viewer.nationalmap.gov/example/services.html */ public class USNationalMapImageryV extends AbstractMultiLayerMapSource { public USNationalMapImageryV() { super("USGS National Map Satellite+", TileImageType.JPG); mapSources = new MapSource[] { new USNationalMapImagery(), new USNationalMapVS() }; initializeValues(); } @Override public Color getBackgroundColor() { return Color.WHITE; } }././@LongLink0000000000000000000000000000016300000000000011565 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_america_north/ChartbundleTAC.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_america_north/Chart0000644000175000017500000000307212122526602033363 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.mappacks.region_america_north; import mobac.mapsources.AbstractHttpMapSource; import mobac.program.model.TileImageType; /** * https://sourceforge.net/tracker/?func=detail&atid=1105497&aid=3376462&group_id=238075 * * http://www.chartbundle.com/charts/ */ public class ChartbundleTAC extends AbstractHttpMapSource { public ChartbundleTAC() { super("cb-tac", 4, 14, TileImageType.PNG, TileUpdate.None); } @Override public String toString() { return "Chartbundle US Terminal Area Charts"; } public String getTileUrl(int zoom, int tilex, int tiley) { return "http://wms.chartbundle.com/tms/v1.0/tac/" + zoom + "/" + tilex + "/" + tiley + ".png?type=google"; } }././@LongLink0000000000000000000000000000017000000000000011563 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_america_north/USNationalMapVector.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_america_north/USNat0000644000175000017500000000266712122526602033325 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ /** * */ package mobac.mapsources.mappacks.region_america_north; import java.awt.Color; import mobac.mapsources.AbstractMultiLayerMapSource; import mobac.program.interfaces.MapSource; import mobac.program.model.TileImageType; public class USNationalMapVector extends AbstractMultiLayerMapSource { public USNationalMapVector() { super("USGS National Map Vector", TileImageType.PNG); mapSources = new MapSource[] { new USNationalMapVFS(), new USNationalMapVS() }; initializeValues(); } @Override public Color getBackgroundColor() { return Color.WHITE; } }././@LongLink0000000000000000000000000000017100000000000011564 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_america_north/USNationalMapImagery.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_america_north/USNat0000644000175000017500000000276012122526602033317 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.mappacks.region_america_north; import mobac.mapsources.AbstractHttpMapSource; import mobac.program.model.TileImageType; /** * http://viewer.nationalmap.gov/example/services.html */ public class USNationalMapImagery extends AbstractHttpMapSource { public USNationalMapImagery() { super("USGS National Map Satellite", 0, 15, TileImageType.JPG, TileUpdate.IfNoneMatch); } private static final String BASE_URL = " http://basemap.nationalmap.gov/ArcGIS/rest/services/USGSImageryOnly/MapServer/tile/"; public String getTileUrl(int zoom, int x, int y) { return BASE_URL + zoom + "/" + y + "/" + x; } }././@LongLink0000000000000000000000000000016300000000000011565 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_america_north/ChartbundleSEC.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/mappacks/region_america_north/Chart0000644000175000017500000000306612122526602033366 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources.mappacks.region_america_north; import mobac.mapsources.AbstractHttpMapSource; import mobac.program.model.TileImageType; /** * https://sourceforge.net/tracker/?func=detail&atid=1105497&aid=3376462&group_id=238075 * * http://www.chartbundle.com/charts/ */ public class ChartbundleSEC extends AbstractHttpMapSource { public ChartbundleSEC() { super("cb-sec", 4, 13, TileImageType.PNG, TileUpdate.None); } @Override public String toString() { return "Chartbundle US Sectional Charts"; } public String getTileUrl(int zoom, int tilex, int tiley) { return "http://wms.chartbundle.com/tms/v1.0/sec/" + zoom + "/" + tilex + "/" + tiley + ".png?type=google"; } }mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/MapSourcesPropertiesManager.java0000644000175000017500000000503112122526602032713 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.Properties; import mobac.program.model.Settings; import mobac.utilities.Utilities; import org.apache.log4j.Logger; public class MapSourcesPropertiesManager { private static final Logger log = Logger.getLogger(MapSourcesPropertiesManager.class); private static final String FILENAME = "mapsources.properties"; public static final Properties PROPERTIES = new Properties(); private static boolean SHUTDOWN_HOOK_REGISTERED = false; public static void load() { File mapSourcesDir = Settings.getInstance().getMapSourcesDirectory(); File mapSourcesProperties = new File(mapSourcesDir, FILENAME); if (!mapSourcesProperties.isFile()) return; FileInputStream in = null; try { in = new FileInputStream(mapSourcesProperties); PROPERTIES.load(in); } catch (IOException e) { log.error("Failed to load mapsources.properties", e); } finally { Utilities.closeStream(in); } if (!SHUTDOWN_HOOK_REGISTERED) { Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { save(); } }); } } public static void save() { if (PROPERTIES.size() == 0) return; File mapSourcesDir = Settings.getInstance().getMapSourcesDirectory(); File mapSourcesProperties = new File(mapSourcesDir, FILENAME); FileOutputStream out = null; try { out = new FileOutputStream(mapSourcesProperties); PROPERTIES.store(out, ""); } catch (IOException e) { log.error("", e); } finally { Utilities.closeStream(out); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/DefaultMapSourcesManager.java0000644000175000017500000002002712127544346032157 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources; import java.io.File; import java.io.IOException; import java.util.Comparator; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.TreeSet; import java.util.Vector; import javax.swing.JOptionPane; import mobac.mapsources.custom.StandardMapSourceLayer; import mobac.mapsources.impl.DebugLocalMapSource; import mobac.mapsources.impl.DebugMapSource; import mobac.mapsources.impl.DebugRandomLocalMapSource; import mobac.mapsources.impl.DebugTransparentLocalMapSource; import mobac.mapsources.impl.SimpleMapSource; import mobac.mapsources.loader.BeanShellMapSourceLoader; import mobac.mapsources.loader.CustomMapSourceLoader; import mobac.mapsources.loader.EclipseMapPackLoader; import mobac.mapsources.loader.MapPackManager; import mobac.program.interfaces.MapSource; import mobac.program.model.Settings; import mobac.utilities.I18nUtils; import org.apache.log4j.Logger; public class DefaultMapSourcesManager extends MapSourcesManager { private Logger log = Logger.getLogger(DefaultMapSourcesManager.class); /** * All map sources visible to the user independent of it is enabled or disabled */ private LinkedHashMap allMapSources = new LinkedHashMap(50); /** * All means all visible map sources to the user plus all layers of multi-layer map sources */ private HashMap allAvailableMapSources = new HashMap(50); public DefaultMapSourcesManager() { // Check for user specific configuration of mapsources directory } protected void loadMapSources() { try { boolean devMode = Settings.getInstance().devMode; if (devMode) { addMapSource(new DebugMapSource()); addMapSource(new DebugLocalMapSource()); addMapSource(new DebugTransparentLocalMapSource()); addMapSource(new DebugRandomLocalMapSource()); } File mapSourcesDir = Settings.getInstance().getMapSourcesDirectory(); if (mapSourcesDir == null) throw new RuntimeException("Map sources directory is unset"); if (!mapSourcesDir.isDirectory()) { JOptionPane.showMessageDialog(null, String.format(I18nUtils.localizedStringForKey("msg_environment_mapsrc_dir_not_exist"), mapSourcesDir.getAbsolutePath()), I18nUtils.localizedStringForKey("Error"), JOptionPane.ERROR_MESSAGE); return; } try { MapPackManager mpm = new MapPackManager(mapSourcesDir); mpm.installUpdates(); if (!devMode || !loadMapPacksEclipseMode()) { mpm.loadMapPacks(this); } } catch (Exception e) { throw new RuntimeException("Failed to load map packs: " + e.getMessage(), e); } BeanShellMapSourceLoader bsmsl = new BeanShellMapSourceLoader(this, mapSourcesDir); bsmsl.loadBeanShellMapSources(); CustomMapSourceLoader cmsl = new CustomMapSourceLoader(this, mapSourcesDir); cmsl.loadCustomMapSources(); } finally { // If no map sources are available load the simple map source which shows the informative message if (allMapSources.size() == 0) addMapSource(new SimpleMapSource()); } } private boolean loadMapPacksEclipseMode() { EclipseMapPackLoader empl; try { empl = new EclipseMapPackLoader(this); if (!empl.loadMapPacks()) return false; return true; } catch (IOException e) { log.error("Failed to load map packs directly from classpath"); } return false; } public void addMapSource(MapSource mapSource) { if (mapSource instanceof StandardMapSourceLayer) mapSource = ((StandardMapSourceLayer) mapSource).getMapSource(); allAvailableMapSources.put(mapSource.getName(), mapSource); if (mapSource instanceof AbstractMultiLayerMapSource) { for (MapSource lms : ((AbstractMultiLayerMapSource) mapSource)) { if (lms instanceof StandardMapSourceLayer) lms = ((StandardMapSourceLayer) lms).getMapSource(); MapSource old = allAvailableMapSources.put(lms.getName(), lms); if (old != null) { allAvailableMapSources.put(old.getName(), old); if (mapSource.equals(old)) JOptionPane.showMessageDialog(null, "Error: Duplicate map source name found: " + mapSource.getName(), "Duplicate name", JOptionPane.ERROR_MESSAGE); } } } allMapSources.put(mapSource.getName(), mapSource); } public static void initialize() { INSTANCE = new DefaultMapSourcesManager(); ((DefaultMapSourcesManager) INSTANCE).loadMapSources(); } public static void initializeEclipseMapPacksOnly() { INSTANCE = new DefaultMapSourcesManager(); ((DefaultMapSourcesManager) INSTANCE).loadMapPacksEclipseMode(); } @Override public Vector getAllAvailableMapSources() { return new Vector(allMapSources.values()); } @Override public Vector getAllMapSources() { return new Vector(allMapSources.values()); } @Override public Vector getAllLayerMapSources() { Vector all = getAllMapSources(); TreeSet uniqueSources = new TreeSet(new Comparator() { public int compare(MapSource o1, MapSource o2) { return o1.getName().compareTo(o2.getName()); } }); for (MapSource ms : all) { if (ms instanceof AbstractMultiLayerMapSource) { for (MapSource lms : ((AbstractMultiLayerMapSource) ms)) { uniqueSources.add(lms); } } else uniqueSources.add(ms); } Vector result = new Vector(uniqueSources); return result; } @Override public Vector getEnabledOrderedMapSources() { Vector mapSources = new Vector(allMapSources.size()); Vector enabledMapSources = Settings.getInstance().mapSourcesEnabled; TreeSet notEnabledMapSources = new TreeSet(allMapSources.keySet()); notEnabledMapSources.removeAll(enabledMapSources); for (String mapSourceName : enabledMapSources) { MapSource ms = getSourceByName(mapSourceName); if (ms != null) { mapSources.add(ms); } } // remove all disabled map sources so we get those that are neither enabled nor disabled notEnabledMapSources.removeAll(Settings.getInstance().mapSourcesDisabled); for (String mapSourceName : notEnabledMapSources) { MapSource ms = getSourceByName(mapSourceName); if (ms != null) { mapSources.add(ms); } } if (mapSources.size() == 0) mapSources.add(new SimpleMapSource()); return mapSources; } @Override public Vector getDisabledMapSources() { Vector disabledMapSources = Settings.getInstance().mapSourcesDisabled; Vector mapSources = new Vector(disabledMapSources.size()); for (String mapSourceName : disabledMapSources) { MapSource ms = getSourceByName(mapSourceName); if (ms != null) { mapSources.add(ms); } } return mapSources; } @Override public MapSource getDefaultMapSource() { MapSource ms = getSourceByName("MapQuest");// DEFAULT; if (ms != null) return ms; // Fallback: return first return allMapSources.values().iterator().next(); } @Override public MapSource getSourceByName(String name) { return allAvailableMapSources.get(name); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/mapsources/AbstractHttpMapSource.java0000644000175000017500000001450512127544346031524 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.mapsources; import java.awt.Color; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.IOException; import java.net.HttpURLConnection; import java.net.URL; import javax.imageio.ImageIO; import mobac.exceptions.MapSourceInitializationException; import mobac.exceptions.TileException; import mobac.gui.mapview.JMapViewer; import mobac.mapsources.mapspace.MercatorPower2MapSpace; import mobac.program.download.TileDownLoader; import mobac.program.interfaces.HttpMapSource; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSourceListener; import mobac.program.interfaces.MapSpace; import mobac.program.model.MapSourceLoaderInfo; import mobac.program.model.TileImageType; import mobac.program.tilestore.TileStore; import mobac.program.tilestore.TileStoreEntry; import org.apache.log4j.Logger; /** * Abstract base class for map sources. */ public abstract class AbstractHttpMapSource implements HttpMapSource { protected Logger log; private boolean initialized = false; protected String name; protected int minZoom; protected int maxZoom; protected TileImageType tileType; protected HttpMapSource.TileUpdate tileUpdate; protected MapSpace mapSpace = MercatorPower2MapSpace.INSTANCE_256; protected MapSourceLoaderInfo loaderInfo = null; public AbstractHttpMapSource(String name, int minZoom, int maxZoom, TileImageType tileType) { this(name, minZoom, maxZoom, tileType, HttpMapSource.TileUpdate.None); } /** * Do not use - for JAXB only */ protected AbstractHttpMapSource() { } public AbstractHttpMapSource(String name, int minZoom, int maxZoom, TileImageType tileType, HttpMapSource.TileUpdate tileUpdate) { log = Logger.getLogger(this.getClass()); this.name = name; this.minZoom = minZoom; this.maxZoom = Math.min(maxZoom, JMapViewer.MAX_ZOOM); this.tileType = tileType; this.tileUpdate = tileUpdate; } public boolean ignoreContentMismatch() { return false; } public HttpURLConnection getTileUrlConnection(int zoom, int tilex, int tiley) throws IOException { String url = getTileUrl(zoom, tilex, tiley); if (url == null) return null; HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection(); prepareTileUrlConnection(conn); return conn; } protected void prepareTileUrlConnection(HttpURLConnection conn) { // Derived classes may override this method } public abstract String getTileUrl(int zoom, int tilex, int tiley); /** * Can be used to e.g. retrieve the url pattern before the first call */ protected final void initializeHttpMapSource() { if (initialized) return; // Prevent multiple initializations in case of multi-threaded access try { synchronized (this) { if (initialized) // Another thread has already completed initialization while this one was blocked return; initernalInitialize(); initialized = true; log.debug("Map source has been initialized"); } } catch (Exception e) { log.error("Map source initialization failed: " + e.getMessage(), e); // TODO: inform user } initialized = true; } protected void initernalInitialize() throws MapSourceInitializationException { } public byte[] getTileData(int zoom, int x, int y, LoadMethod loadMethod) throws IOException, TileException, InterruptedException { if (loadMethod == LoadMethod.CACHE) { TileStoreEntry entry = TileStore.getInstance().getTile(x, y, zoom, this); if (entry == null) return null; byte[] data = entry.getData(); if (Thread.currentThread() instanceof MapSourceListener) { ((MapSourceListener) Thread.currentThread()).tileDownloaded(data.length); } return data; } else if (loadMethod == LoadMethod.SOURCE) { initializeHttpMapSource(); return TileDownLoader.downloadTileAndUpdateStore(x, y, zoom, this); } else { initializeHttpMapSource(); return TileDownLoader.getImage(x, y, zoom, this); } } public BufferedImage getTileImage(int zoom, int x, int y, LoadMethod loadMethod) throws IOException, TileException, InterruptedException { byte[] data = getTileData(zoom, x, y, loadMethod); if (data == null) return null; return ImageIO.read(new ByteArrayInputStream(data)); } public int getMaxZoom() { return maxZoom; } public int getMinZoom() { return minZoom; } public String getName() { return name; } public String getStoreName() { return name; } @Override public String toString() { return name; } public TileImageType getTileImageType() { return tileType; } public HttpMapSource.TileUpdate getTileUpdate() { return tileUpdate; } public boolean allowFileStore() { return true; } public MapSpace getMapSpace() { return mapSpace; } public Color getBackgroundColor() { return Color.BLACK; } public MapSourceLoaderInfo getLoaderInfo() { return loaderInfo; } public void setLoaderInfo(MapSourceLoaderInfo loaderInfo) { if (this.loaderInfo != null) throw new RuntimeException("LoaderInfo already set"); this.loaderInfo = loaderInfo; } @Override public int hashCode() { return getName().hashCode(); } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (!(obj instanceof MapSource)) return false; MapSource other = (MapSource) obj; return other.getName().equals(getName()); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/0000755000175000017500000000000012134265562023716 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/DirectoryManager.java0000644000175000017500000001605312122526604030017 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.Properties; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.swing.JOptionPane; import mobac.utilities.Utilities; /** * Provides the common directories used within Mobile Atlas Creator: *
    *
  • current directory
  • *
  • program directory
  • *
  • user home directory
  • *
  • user settings directory
  • *
  • temporary directory
  • *
* */ public class DirectoryManager { public static final File currentDir; public static final File programDir; public static final File userHomeDir; public static final File tempDir; public static final File userAppDataDir; public static final File userSettingsDir; public static final File mapSourcesDir; public static final File toolsDir; public static final File atlasProfilesDir; public static final File tileStoreDir; private static Properties dirConfig = null; static { currentDir = new File(System.getProperty("user.dir")); userHomeDir = new File(System.getProperty("user.home")); programDir = getProgramDir(); loadDirectoriesIni(); userAppDataDir = getUserAppDataDir(); tempDir = applyDirConfig("mobac.tmpdir", new File(System.getProperty("java.io.tmpdir"))); mapSourcesDir = applyDirConfig("mobac.mapsourcesdir", new File(programDir, "mapsources")); toolsDir = applyDirConfig("mobac.toolsdir", new File(programDir, "tools")); userSettingsDir = applyDirConfig("mobac.usersettingsdir", programDir); atlasProfilesDir = applyDirConfig("mobac.atlasprofilesdir", currentDir); tileStoreDir = applyDirConfig("mobac.tilestoredir", new File(programDir, "tilestore")); } private static File applyDirConfig(String propertyName, File defaultDir) { if (dirConfig == null) return defaultDir; try { final String dirCfg = dirConfig.getProperty(propertyName); if (dirCfg == null) { return defaultDir; } else { return expandCommandLine(dirCfg); } } catch (Exception e) { Logging.LOG.error("Error reading directory configuration: " + e.getMessage(), e); JOptionPane.showMessageDialog(null, "

Failed to load directory.ini - entry \"" + propertyName + "\":

" + e.getMessage() + "

", "Faile do load directory.ini", JOptionPane.ERROR_MESSAGE); return defaultDir; } } /** * Modified version of * http://stackoverflow.com/questions/2090647/evaluation-of-environment-variables-in-command-run- * by-javas-runtime-exec * * @param cmd * @return */ private static File expandCommandLine(final String cmd) { final Pattern vars = Pattern.compile("[$]\\{(\\S+)\\}"); final Matcher m = vars.matcher(cmd.trim()); final StringBuffer sb = new StringBuffer(cmd.length()); int lastMatchEnd = 0; while (m.find()) { sb.append(cmd.substring(lastMatchEnd, m.start())); final String envVar = m.group(1); String envVal = System.getenv(envVar); if (envVal == null) { File defPath = null; if ("mobac-prog".equalsIgnoreCase(envVar)) defPath = programDir; else if ("home".equalsIgnoreCase(envVar)) defPath = userHomeDir; else if ("XDG_CONFIG_HOME".equalsIgnoreCase(envVar)) defPath = new File(userHomeDir, ".config"); else if ("XDG_CACHE_HOME".equalsIgnoreCase(envVar)) defPath = new File(userHomeDir, ".cache"); else if ("XDG_DATA_HOME".equalsIgnoreCase(envVar)) { File localDataDir = new File(userHomeDir, ".local"); defPath = new File(localDataDir, "share"); } if (defPath != null) envVal = defPath.getAbsolutePath(); } if (envVal == null) sb.append(cmd.substring(m.start(), m.end())); else sb.append(envVal); lastMatchEnd = m.end(); } sb.append(cmd.substring(lastMatchEnd)); return new File(sb.toString()); } public static void initialize() { if (currentDir == null || userAppDataDir == null || tempDir == null || programDir == null) throw new RuntimeException("DirectoryManager failed"); } private static void loadDirectoriesIni() { File dirIniFile = new File(programDir, "directories.ini"); if (!dirIniFile.isFile()) return; dirConfig = new Properties(); FileInputStream in = null; try { in = new FileInputStream(dirIniFile); dirConfig.load(in); } catch (IOException e) { System.err.println("Failed to load " + dirIniFile.getName()); e.printStackTrace(); } finally { Utilities.closeStream(in); } } /** * Returns the directory from which this java program is executed * * @return */ private static File getProgramDir() { File f = null; try { f = Utilities.getClassLocation(DirectoryManager.class); } catch (Exception e) { System.err.println(e.getMessage()); return currentDir; } if ("bin".equals(f.getName())) // remove the bin dir -> this usually // happens only in a development environment return f.getParentFile(); else return f; } /** * Returns the directory where Mobile Atlas Creator saves it's application settings. * * Examples: *
    *
  • English Windows XP:
    * C:\Document and Settings\%username%\Application Data\Mobile Atlas Creator *
  • Vista:
    * C:\Users\%username%\Application Data\Mobile Atlas Creator *
  • Linux:
    * /home/$username$/.mobac
  • *
* * @return */ private static File getUserAppDataDir() { String appData = System.getenv("APPDATA"); if (appData != null) { File appDataDir = new File(appData); if (appDataDir.isDirectory()) { File mobacDataDir = new File(appData, "Mobile Atlas Creator"); if (mobacDataDir.isDirectory() || mobacDataDir.mkdir()) return mobacDataDir; else throw new RuntimeException("Unable to create directory \"" + mobacDataDir.getAbsolutePath() + "\""); } } File userDir = new File(System.getProperty("user.home")); File mobacUserDir = new File(userDir, ".mobac"); if (!mobacUserDir.exists() && !mobacUserDir.mkdir()) throw new RuntimeException("Unable to create directory \"" + mobacUserDir.getAbsolutePath() + "\""); return mobacUserDir; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/JobDispatcher.java0000644000175000017500000001333612122526604027302 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program; import java.io.FileNotFoundException; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import mobac.exceptions.StopAllDownloadsException; import mobac.program.interfaces.MapSourceListener; import mobac.program.tilestore.berkeleydb.DelayedInterruptThread; import org.apache.log4j.Logger; /** * Controls the worker threads that are downloading the map tiles in parallel. Additionally the job queue containing the * unprocessed tile download jobs can be accessed via this class. */ public class JobDispatcher { private static Logger log = Logger.getLogger(JobDispatcher.class); protected int maxJobsInQueue = 100; protected int minJobsInQueue = 50; protected WorkerThread[] workers; protected PauseResumeHandler pauseResumeHandler; protected MapSourceListener mapSourceListener; protected BlockingQueue jobQueue = new LinkedBlockingQueue(); public JobDispatcher(int threadCount, PauseResumeHandler pauseResumeHandler, MapSourceListener mapSourceListener) { this.pauseResumeHandler = pauseResumeHandler; this.mapSourceListener = mapSourceListener; workers = new WorkerThread[threadCount]; for (int i = 0; i < threadCount; i++) workers[i] = new WorkerThread(i); } @Override protected void finalize() throws Throwable { terminateAllWorkerThreads(); super.finalize(); } public void terminateAllWorkerThreads() { cancelOutstandingJobs(); log.trace("Killing all worker threads"); for (int i = 0; i < workers.length; i++) { try { WorkerThread w = workers[i]; if (w != null) { w.interrupt(); } workers[i] = null; } catch (Exception e) { // We don't care about exception here } } } public void cancelOutstandingJobs() { jobQueue.clear(); } /** * Blocks if more than 100 jobs are already scheduled. * * @param job * @throws InterruptedException */ public void addJob(Job job) throws InterruptedException { while (jobQueue.size() > maxJobsInQueue) { Thread.sleep(200); if ((jobQueue.size() < minJobsInQueue) && (maxJobsInQueue < 2000)) { // System and download connection is very fast - we have to // increase the maximum job count in the queue maxJobsInQueue *= 2; minJobsInQueue *= 2; } } jobQueue.put(job); } /** * Adds the job to the job-queue and returns. This method will never block! * * @param job */ public void addErrorJob(Job job) { try { jobQueue.put(job); } catch (InterruptedException e) { // Can never happen with LinkedBlockingQueue } } public int getWaitingJobCount() { return jobQueue.size(); } public static interface Job { public void run(JobDispatcher dispatcher) throws Exception; } public boolean isAtLeastOneWorkerActive() { for (int i = 0; i < workers.length; i++) { WorkerThread w = workers[i]; if (w != null) { if ((!w.idle) && (w.getState() != Thread.State.WAITING)) return true; } } log.debug("All worker threads are idle"); return false; } /** * Each worker thread takes the first job from the job queue and executes it. If the queue is empty the worker * blocks, waiting for the next job. */ protected class WorkerThread extends DelayedInterruptThread implements MapSourceListener { Job job = null; boolean idle = true; private Logger log = Logger.getLogger(WorkerThread.class); public WorkerThread(int threadNum) { super(String.format("WorkerThread %02d", threadNum)); setDaemon(true); start(); } @Override public void run() { try { executeJobs(); } catch (InterruptedException e) { } log.trace("Thread is terminating"); } protected void executeJobs() throws InterruptedException { while (!isInterrupted()) { try { pauseResumeHandler.pauseWait(); idle = true; job = jobQueue.take(); idle = false; } catch (InterruptedException e) { return; } if (job == null) return; try { job.run(JobDispatcher.this); job = null; } catch (InterruptedException e) { } catch (StopAllDownloadsException e) { JobDispatcher.this.terminateAllWorkerThreads(); JobDispatcher.this.cancelOutstandingJobs(); log.warn("All downloads has been stoppened: " + e.getMessage()); return; } catch (FileNotFoundException e) { log.error("Download failed: " + e.getMessage()); } catch (Exception e) { log.error("Unknown error occured while executing the job: ", e); } catch (OutOfMemoryError e) { log.error("", e); Thread.sleep(5000); System.gc(); } } } public void tileDownloaded(int size) { mapSourceListener.tileDownloaded(size); } public void tileLoadedFromCache(int size) { mapSourceListener.tileLoadedFromCache(size); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/jaxb/0000755000175000017500000000000012122526604024634 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/jaxb/BigDecimalAdapter.java0000644000175000017500000000273112122526604030763 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.jaxb; import java.math.BigDecimal; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.text.NumberFormat; import java.util.Locale; import javax.xml.bind.annotation.adapters.XmlAdapter; public class BigDecimalAdapter extends XmlAdapter { NumberFormat df = new DecimalFormat("0.00000",DecimalFormatSymbols.getInstance(Locale.ENGLISH)); @Override public BigDecimal unmarshal(String v) throws Exception { return new BigDecimal(v); } @Override public String marshal(BigDecimal v) throws Exception { return df.format(v); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/jaxb/PolygonAdapter.java0000644000175000017500000000353412122526604030434 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.jaxb; import java.awt.Point; import java.awt.Polygon; import java.util.Vector; import javax.xml.bind.annotation.adapters.XmlAdapter; /** * Required {@link XmlAdapter} implementation for serializing a {@link Polygon} */ public class PolygonAdapter extends XmlAdapter { @Override public PolygonType marshal(Polygon polygon) throws Exception { Vector points = new Vector(polygon.npoints); for (int i = 0; i < polygon.npoints; i++) { Point p = new Point(polygon.xpoints[i], polygon.ypoints[i]); points.add(p); } return new PolygonType(points); } @Override public Polygon unmarshal(PolygonType value) throws Exception { int npoints = value.points.size(); int[] xpoints = new int[npoints]; int[] ypoints = new int[npoints]; for (int i = 0; i < npoints; i++) { Point p = value.points.get(i); xpoints[i] = p.x; ypoints[i] = p.y; } return new Polygon(xpoints, ypoints, npoints); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/jaxb/PaperSizeAdapter.java0000644000175000017500000000413412122526604030704 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.jaxb; import javax.xml.bind.annotation.adapters.XmlAdapter; import mobac.program.model.PaperSize; import mobac.program.model.PaperSize.Format; /** * Required {@link XmlAdapter} implementation for serializing {@link PaperSize} */ public class PaperSizeAdapter extends XmlAdapter { private static final String LANDSCAPE = "_LANDSCAPE", SELECTION = "SELECTION", X = "x"; @Override public PaperSize unmarshal(String value) throws Exception { if (value.equals(SELECTION)) { return null; } if (value.contains(X)) { String split[] = value.split(X); double width = Double.parseDouble(split[0]); double height = Double.parseDouble(split[1]); return new PaperSize(width, height); } boolean landscape = false; if (value.contains(LANDSCAPE)) { value = value.substring(0, value.indexOf(LANDSCAPE)); landscape = true; } Format format = Format.valueOf(value); return new PaperSize(format, landscape); } @Override public String marshal(PaperSize v) throws Exception { if (v == null) { return SELECTION; } if (v.format != null) { return v.format.name() + (v.landscape ? LANDSCAPE : ""); } else { return v.width + X + v.height; } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/jaxb/PointAdapter.java0000644000175000017500000000320512122526604030071 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.jaxb; import java.awt.Point; import javax.xml.bind.UnmarshalException; import javax.xml.bind.annotation.adapters.XmlAdapter; /** * Required {@link XmlAdapter} implementation for serializing a {@link Point} as * the default one creates a {@link StackOverflowError} * */ public class PointAdapter extends XmlAdapter { @Override public String marshal(Point point) throws Exception { return point.x + "/" + point.y; } @Override public Point unmarshal(String value) throws Exception { int i = value.indexOf('/'); if (i < 0) throw new UnmarshalException("Invalid format"); int x = Integer.parseInt(value.substring(0, i).trim()); int y = Integer.parseInt(value.substring(i + 1).trim()); return new Point(x, y); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/jaxb/FontAdapter.java0000644000175000017500000000254712122526604027716 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.jaxb; import java.awt.Font; import javax.xml.bind.annotation.adapters.XmlAdapter; import mobac.gui.dialogs.FontChooser; /** * Required {@link XmlAdapter} implementation for serializing {@link Font} */ public class FontAdapter extends XmlAdapter { @Override public Font unmarshal(String value) throws Exception { return Font.decode(value); } @Override public String marshal(Font font) throws Exception { return FontChooser.encodeFont(font); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/jaxb/MapSourceAdapter.java0000644000175000017500000000254112122526604030700 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.jaxb; import javax.xml.bind.annotation.adapters.XmlAdapter; import mobac.mapsources.MapSourcesManager; import mobac.program.interfaces.MapSource; public class MapSourceAdapter extends XmlAdapter { @Override public String marshal(MapSource mapSource) throws Exception { return mapSource.getName(); } @Override public MapSource unmarshal(String name) throws Exception { return MapSourcesManager.getInstance().getSourceByName(name); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/jaxb/TileImageTypeAdapter.java0000644000175000017500000000243012122526604031501 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.jaxb; import javax.xml.bind.annotation.adapters.XmlAdapter; import mobac.program.model.TileImageType; public class TileImageTypeAdapter extends XmlAdapter { @Override public TileImageType unmarshal(String v) throws Exception { return TileImageType.getTileImageType(v); } @Override public String marshal(TileImageType v) throws Exception { return v.name(); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/jaxb/AtlasOutputFormatAdapter.java0000644000175000017500000000247112122526604032442 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.jaxb; import javax.xml.bind.annotation.adapters.XmlAdapter; import mobac.program.model.AtlasOutputFormat; public class AtlasOutputFormatAdapter extends XmlAdapter { @Override public String marshal(AtlasOutputFormat v) throws Exception { return v.getTypeName(); } @Override public AtlasOutputFormat unmarshal(String v) throws Exception { return AtlasOutputFormat.getFormatByName(v); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/jaxb/PolygonType.java0000644000175000017500000000247512122526604030000 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.jaxb; import java.awt.Point; import java.util.Vector; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; public class PolygonType { @XmlElement(name = "point") @XmlJavaTypeAdapter(PointAdapter.class) public Vector points; protected PolygonType() { points = new Vector(20); } public PolygonType(Vector points) { this.points = points; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/jaxb/ColorAdapter.java0000644000175000017500000000417712122526604030067 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.jaxb; import java.awt.Color; import javax.xml.bind.UnmarshalException; import javax.xml.bind.annotation.adapters.XmlAdapter; public class ColorAdapter extends XmlAdapter { @Override public String marshal(Color color) throws Exception { if (color.getAlpha() == 255) return String.format("#%02x%02x%02x", color.getRed(), color.getGreen(), color.getBlue()); else return String.format("#%02x%02x%02x%02x", color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); } @Override public Color unmarshal(String value) throws Exception { return parseColor(value); } public static Color parseColor(String value) throws UnmarshalException { value = value.trim(); int length = value.length(); if (!value.startsWith("#")) throw new UnmarshalException("Invalid format: does not start with #"); if (length != 7 && length != 9) throw new UnmarshalException("Invalid format: wrong length"); int r = Integer.parseInt(value.substring(1, 3), 16); int g = Integer.parseInt(value.substring(3, 5), 16); int b = Integer.parseInt(value.substring(5, 7), 16); if (length == 7) return new Color(r, g, b); int a = Integer.parseInt(value.substring(7, 9), 16); return new Color(r, g, b, a); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/jaxb/DimensionAdapter.java0000644000175000017500000000326512122526604030733 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.jaxb; import java.awt.Dimension; import javax.xml.bind.UnmarshalException; import javax.xml.bind.annotation.adapters.XmlAdapter; /** * Required {@link XmlAdapter} implementation for serializing a * {@link Dimension} as the default one creates a {@link StackOverflowError} */ public class DimensionAdapter extends XmlAdapter { @Override public String marshal(Dimension dimension) throws Exception { return dimension.width + "/" + dimension.height; } @Override public Dimension unmarshal(String value) throws Exception { int i = value.indexOf('/'); if (i < 0) throw new UnmarshalException("Invalid format"); int width = Integer.parseInt(value.substring(0, i)); int height = Integer.parseInt(value.substring(i + 1)); return new Dimension(width, height); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/tilestore/0000755000175000017500000000000012150552674025731 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/tilestore/berkeleydb/0000755000175000017500000000000012122526606030034 5ustar paulliupaulliu././@LongLink0000000000000000000000000000015400000000000011565 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/tilestore/berkeleydb/BerkeleyDbTileStore.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/tilestore/berkeleydb/BerkeleyDbTileSto0000644000175000017500000004657612122526606033315 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.tilestore.berkeleydb; import java.awt.Point; import java.awt.image.BufferedImage; import java.awt.image.IndexColorModel; import java.awt.image.WritableRaster; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.channels.FileChannel; import java.nio.channels.FileLock; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.TreeMap; import mobac.exceptions.TileStoreException; import mobac.program.interfaces.MapSource; import mobac.program.model.Settings; import mobac.program.tilestore.TileStore; import mobac.program.tilestore.TileStoreEntry; import mobac.program.tilestore.TileStoreInfo; import mobac.program.tilestore.berkeleydb.TileDbEntry.TileDbKey; import mobac.utilities.GUIExceptionHandler; import mobac.utilities.Utilities; import mobac.utilities.file.DeleteFileFilter; import mobac.utilities.file.DirInfoFileFilter; import mobac.utilities.file.DirectoryFileFilter; import com.sleepycat.je.DatabaseException; import com.sleepycat.je.Environment; import com.sleepycat.je.EnvironmentConfig; import com.sleepycat.je.EnvironmentLockedException; import com.sleepycat.persist.EntityCursor; import com.sleepycat.persist.EntityStore; import com.sleepycat.persist.PrimaryIndex; import com.sleepycat.persist.StoreConfig; import com.sleepycat.persist.evolve.Mutations; import com.sleepycat.persist.evolve.Renamer; /** * The new database based tile store implementation. */ public class BerkeleyDbTileStore extends TileStore { /** * Max count of tile stores opened */ private static final int MAX_CONCURRENT_ENVIRONMENTS = 5; private EnvironmentConfig envConfig; private Map tileDbMap; private FileLock tileStoreLock = null; private Mutations mutations; public BerkeleyDbTileStore() throws TileStoreException { super(); acquireTileStoreLock(); tileDbMap = new TreeMap(); envConfig = new EnvironmentConfig(); envConfig.setTransactional(false); envConfig.setLocking(true); envConfig.setExceptionListener(GUIExceptionHandler.getInstance()); envConfig.setAllowCreate(true); envConfig.setSharedCache(true); envConfig.setCachePercent(50); mutations = new Mutations(); String oldPackage1 = "tac.tilestore.berkeleydb"; String oldPackage2 = "tac.program.tilestore.berkeleydb"; String entry = ".TileDbEntry"; String key = ".TileDbEntry$TileDbKey"; mutations.addRenamer(new Renamer(oldPackage1 + entry, 0, TileDbEntry.class.getName())); mutations.addRenamer(new Renamer(oldPackage1 + key, 0, TileDbKey.class.getName())); mutations.addRenamer(new Renamer(oldPackage1 + entry, 1, TileDbEntry.class.getName())); mutations.addRenamer(new Renamer(oldPackage1 + key, 1, TileDbKey.class.getName())); mutations.addRenamer(new Renamer(oldPackage2 + entry, 2, TileDbEntry.class.getName())); mutations.addRenamer(new Renamer(oldPackage2 + key, 2, TileDbKey.class.getName())); // for (Renamer r : mutations.getRenamers()) // log.debug(r.toString()); Runtime.getRuntime().addShutdownHook(new ShutdownThread(true)); } protected void acquireTileStoreLock() throws TileStoreException { try { // Get a file channel for the file File file = new File(tileStoreDir, "lock"); if (!tileStoreDir.isDirectory()) try { Utilities.mkDirs(tileStoreDir); } catch (IOException e) { throw new TileStoreException("Unable to create tile store directory: \"" + tileStoreDir.getPath() + "\""); } FileChannel channel = new RandomAccessFile(file, "rw").getChannel(); // Use the file channel to create a lock on the file. // This method blocks until it can retrieve the lock. // Try acquiring the lock without blocking. This method returns // null or throws an exception if the file is already locked. tileStoreLock = channel.tryLock(); if (tileStoreLock == null) throw new TileStoreException("Unable to obtain tile store lock - " + "another instance of Mobile Atlas Creator is running!"); // // Release the lock // lock.release(); // // // Close the file // channel.close(); } catch (Exception e) { log.error("", e); throw new TileStoreException(e.getMessage(), e.getCause()); } } @Override public TileStoreEntry createNewEntry(int x, int y, int zoom, byte[] data, long timeLastModified, long timeExpires, String eTag) { return new TileDbEntry(x, y, zoom, data, timeLastModified, timeExpires, eTag); } @Override public TileStoreEntry createNewEmptyEntry(int x, int y, int zoom) { long time = System.currentTimeMillis(); long timeExpires = time + Settings.getInstance().tileDefaultExpirationTime; // We set the tile data to an empty array because we can not store null return new TileDbEntry(x, y, zoom, new byte[] {}, time, timeExpires, ""); } private TileDatabase getTileDatabase(MapSource mapSource) throws DatabaseException { TileDatabase db; if (tileDbMap == null) // Tile store has been closed already return null; String storeName = mapSource.getName(); if (storeName == null) return null; synchronized (tileDbMap) { db = tileDbMap.get(storeName); } if (db != null) return db; try { synchronized (tileDbMap) { cleanupDatabases(); db = tileDbMap.get(storeName); if (db == null) { db = new TileDatabase(storeName); db.lastAccess = System.currentTimeMillis(); tileDbMap.put(mapSource.getName(), db); } return db; } } catch (Exception e) { log.error("Error creating tile store db \"" + mapSource.getName() + "\"", e); throw new TileStoreException(e); } } private TileDatabase getTileDatabase(String storeName) throws DatabaseException { TileDatabase db; if (tileDbMap == null) // Tile store has been closed already return null; if (storeName == null) return null; synchronized (tileDbMap) { db = tileDbMap.get(storeName); } if (db != null) return db; try { synchronized (tileDbMap) { cleanupDatabases(); db = tileDbMap.get(storeName); if (db == null) { db = new TileDatabase(storeName); db.lastAccess = System.currentTimeMillis(); tileDbMap.put(storeName, db); } return db; } } catch (Exception e) { log.error("Error creating tile store db \"" + storeName + "\"", e); throw new TileStoreException(e); } } @Override public TileStoreInfo getStoreInfo(String storeName) throws InterruptedException { int tileCount = getNrOfTiles(storeName); long storeSize = getStoreSize(storeName); return new TileStoreInfo(storeSize, tileCount); } @Override public void putTileData(byte[] tileData, int x, int y, int zoom, MapSource mapSource) throws IOException { this.putTileData(tileData, x, y, zoom, mapSource, -1, -1, null); } @Override public void putTileData(byte[] tileData, int x, int y, int zoom, MapSource mapSource, long timeLastModified, long timeExpires, String eTag) throws IOException { TileDbEntry tile = new TileDbEntry(x, y, zoom, tileData, timeLastModified, timeExpires, eTag); TileDatabase db = null; try { if (log.isTraceEnabled()) log.trace("Saved " + mapSource.getName() + " " + tile); db = getTileDatabase(mapSource); if (db != null) db.put(tile); } catch (Exception e) { if (db != null) db.close(); log.error("Faild to write tile to tile store \"" + mapSource.getName() + "\"", e); } } @Override public void putTile(TileStoreEntry tile, MapSource mapSource) { TileDatabase db = null; try { if (log.isTraceEnabled()) log.trace("Saved " + mapSource.getName() + " " + tile); db = getTileDatabase(mapSource); db.put((TileDbEntry) tile); } catch (Exception e) { if (db != null) db.close(); log.error("Faild to write tile to tile store \"" + mapSource.getName() + "\"", e); } } @Override public TileStoreEntry getTile(int x, int y, int zoom, MapSource mapSource) { TileDatabase db = null; try { db = getTileDatabase(mapSource); if (db == null) return null; TileStoreEntry tile = db.get(new TileDbKey(x, y, zoom)); if (log.isTraceEnabled()) { if (tile == null) log.trace("Tile store cache miss: (x,y,z)" + x + "/" + y + "/" + zoom + " " + mapSource.getName()); else log.trace("Loaded " + mapSource.getName() + " " + tile); } return tile; } catch (Exception e) { if (db != null) db.close(); log.error("failed to retrieve tile from tile store \"" + mapSource.getName() + "\"", e); return null; } } public boolean contains(int x, int y, int zoom, MapSource mapSource) { try { return getTileDatabase(mapSource).contains(new TileDbKey(x, y, zoom)); } catch (DatabaseException e) { log.error("", e); return false; } } public void prepareTileStore(MapSource mapSource) { try { getTileDatabase(mapSource); } catch (DatabaseException e) { } } public void clearStore(String storeName) { File databaseDir = getStoreDir(storeName); TileDatabase db; synchronized (tileDbMap) { db = tileDbMap.get(storeName); if (db != null) db.close(false); if (databaseDir.exists()) { DeleteFileFilter dff = new DeleteFileFilter(); databaseDir.listFiles(dff); databaseDir.delete(); log.debug("Tilestore " + storeName + " cleared: " + dff); } tileDbMap.remove(storeName); } } /** * This method returns the amount of tiles in the store of tiles which is specified by the {@link MapSource} object. * * @param mapSourceName * the store to calculate number of tiles in * @return the amount of tiles in the specified store. * @throws InterruptedException */ public int getNrOfTiles(String mapSourceName) throws InterruptedException { try { File storeDir = getStoreDir(mapSourceName); if (!storeDir.isDirectory()) return 0; TileDatabase db = getTileDatabase(mapSourceName); int tileCount = (int) db.entryCount(); db.close(); return tileCount; } catch (DatabaseException e) { log.error("", e); return -1; } } public long getStoreSize(String storeName) throws InterruptedException { File tileStore = getStoreDir(storeName); if (tileStore.exists()) { DirInfoFileFilter diff = new DirInfoFileFilter(); try { tileStore.listFiles(diff); } catch (RuntimeException e) { throw new InterruptedException(); } return diff.getDirSize(); } else { return 0; } } public BufferedImage getCacheCoverage(MapSource mapSource, int zoom, Point tileNumMin, Point tileNumMax) throws InterruptedException { TileDatabase db; try { db = getTileDatabase(mapSource); return db.getCacheCoverage(zoom, tileNumMin, tileNumMax); } catch (DatabaseException e) { log.error("", e); return null; } } protected void cleanupDatabases() { if (tileDbMap.size() < MAX_CONCURRENT_ENVIRONMENTS) return; synchronized (tileDbMap) { List list = new ArrayList(tileDbMap.values()); Collections.sort(list, new Comparator() { public int compare(TileDatabase o1, TileDatabase o2) { if (o1.lastAccess == o2.lastAccess) return 0; return (o1.lastAccess < o2.lastAccess) ? -1 : 1; } }); for (int i = 0; i < list.size() - 2; i++) list.get(i).close(); } } public void closeAll() { Thread t = new ShutdownThread(false); t.start(); try { t.join(); } catch (InterruptedException e) { log.error("", e); } } /** * Returns true if the tile store directory of the specified {@link MapSource} exists. * * @param mapSource * @return */ public boolean storeExists(MapSource mapSource) { File tileStore = getStoreDir(mapSource); return (tileStore.isDirectory()) && (tileStore.exists()); } /** * Returns the directory used for storing the tile database of the {@link MapSource} specified by * mapSource * * @param mapSource * @return */ protected File getStoreDir(MapSource mapSource) { return getStoreDir(mapSource.getName()); } /** * @param mapSourceName * @return directory used for storing the tile database belonging to mapSource */ protected File getStoreDir(String mapSourceName) { return new File(tileStoreDir, "db-" + mapSourceName); } public String[] getAllStoreNames() { File[] dirs = tileStoreDir.listFiles(new DirectoryFileFilter()); ArrayList storeNames = new ArrayList(dirs.length); for (File d : dirs) { String name = d.getName(); if (name.startsWith("db-")) { name = name.substring(3); storeNames.add(name); } } String[] result = new String[storeNames.size()]; storeNames.toArray(result); return result; } private class ShutdownThread extends DelayedInterruptThread { private final boolean shutdown; public ShutdownThread(boolean shutdown) { super("DBShutdown"); this.shutdown = shutdown; } @Override public void run() { log.debug("Closing all tile databases..."); synchronized (tileDbMap) { for (TileDatabase db : tileDbMap.values()) { db.close(false); } tileDbMap.clear(); if (shutdown) { tileDbMap = null; try { tileStoreLock.release(); } catch (IOException e) { log.error("", e); } } } log.debug("All tile databases has been closed"); } } protected class TileDatabase { final String mapSourceName; final Environment env; final EntityStore store; final PrimaryIndex tileIndex; boolean dbClosed = false; long lastAccess; public TileDatabase(String mapSourceName) throws IOException, EnvironmentLockedException, DatabaseException { this(mapSourceName, getStoreDir(mapSourceName)); } public TileDatabase(String mapSourceName, File databaseDirectory) throws IOException, EnvironmentLockedException, DatabaseException { log.debug("Opening tile store db: \"" + databaseDirectory + "\""); File storeDir = databaseDirectory; DelayedInterruptThread t = (DelayedInterruptThread) Thread.currentThread(); try { t.pauseInterrupt(); this.mapSourceName = mapSourceName; lastAccess = System.currentTimeMillis(); Utilities.mkDirs(storeDir); env = new Environment(storeDir, envConfig); StoreConfig storeConfig = new StoreConfig(); storeConfig.setAllowCreate(true); storeConfig.setTransactional(false); storeConfig.setMutations(mutations); store = new EntityStore(env, "TilesEntityStore", storeConfig); tileIndex = store.getPrimaryIndex(TileDbKey.class, TileDbEntry.class); } finally { if (t.interruptedWhilePaused()) close(); t.resumeInterrupt(); } } public boolean isClosed() { return dbClosed; } public long entryCount() throws DatabaseException { return tileIndex.count(); } public void put(TileDbEntry tile) throws DatabaseException { DelayedInterruptThread t = (DelayedInterruptThread) Thread.currentThread(); try { t.pauseInterrupt(); tileIndex.put(tile); } finally { if (t.interruptedWhilePaused()) close(); t.resumeInterrupt(); } } public boolean contains(TileDbKey key) throws DatabaseException { return tileIndex.contains(key); } public TileDbEntry get(TileDbKey key) throws DatabaseException { return tileIndex.get(key); } public PrimaryIndex getTileIndex() { return tileIndex; } public BufferedImage getCacheCoverage(int zoom, Point tileNumMin, Point tileNumMax) throws DatabaseException, InterruptedException { log.debug("Loading cache coverage for region " + tileNumMin + " " + tileNumMax + " of zoom level " + zoom); DelayedInterruptThread t = (DelayedInterruptThread) Thread.currentThread(); int width = tileNumMax.x - tileNumMin.x + 1; int height = tileNumMax.y - tileNumMin.y + 1; byte ff = (byte) 0xFF; byte[] colors = new byte[] { 120, 120, 120, 120, // alpha-gray 10, ff, 0, 120 // alpha-green }; IndexColorModel colorModel = new IndexColorModel(2, 2, colors, 0, true); BufferedImage image = null; try { image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_INDEXED, colorModel); } catch (Throwable e) { log.error("Failed to create coverage image: " + e.toString()); image = null; System.gc(); return null; } WritableRaster raster = image.getRaster(); // We are loading the coverage of the selected area column by column which is much faster than loading the // whole region at once for (int x = tileNumMin.x; x <= tileNumMax.x; x++) { TileDbKey fromKey = new TileDbKey(x, tileNumMin.y, zoom); TileDbKey toKey = new TileDbKey(x, tileNumMax.y, zoom); EntityCursor cursor = tileIndex.keys(fromKey, true, toKey, true); try { TileDbKey key = cursor.next(); while (key != null) { int pixelx = key.x - tileNumMin.x; int pixely = key.y - tileNumMin.y; raster.setSample(pixelx, pixely, 0, 1); key = cursor.next(); if (t.isInterrupted()) { log.debug("Cache coverage loading aborted"); throw new InterruptedException(); } } } finally { cursor.close(); } } return image; } protected void purge() { try { store.sync(); env.cleanLog(); } catch (DatabaseException e) { log.error("database compression failed: ", e); } } public void close() { close(true); } public void close(boolean removeFromMap) { if (dbClosed) return; if (removeFromMap) { synchronized (tileDbMap) { TileDatabase db2 = tileDbMap.get(mapSourceName); if (db2 == this) tileDbMap.remove(mapSourceName); } } DelayedInterruptThread t = (DelayedInterruptThread) Thread.currentThread(); try { t.pauseInterrupt(); try { log.debug("Closing tile store db \"" + mapSourceName + "\""); if (store != null) store.close(); } catch (Exception e) { log.error("", e); } try { env.close(); } catch (Exception e) { log.error("", e); } finally { dbClosed = true; } } finally { if (t.interruptedWhilePaused()) close(); t.resumeInterrupt(); } } @Override protected void finalize() throws Throwable { close(); super.finalize(); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/tilestore/berkeleydb/TileDbEntry.java0000644000175000017500000000673312122526606033075 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.tilestore.berkeleydb; import java.util.Date; import mobac.program.tilestore.TileStoreEntry; import com.sleepycat.persist.model.Entity; import com.sleepycat.persist.model.KeyField; import com.sleepycat.persist.model.Persistent; import com.sleepycat.persist.model.PrimaryKey; @Entity(version = 3) public class TileDbEntry implements TileStoreEntry { @PrimaryKey protected TileDbKey tileKey; private byte[] data; private String eTag = null; private long timeDownloaded; private long timeLastModified; private long timeExpires; protected TileDbEntry() { // required for deserialization } public TileDbEntry(int x, int y, int zoom, byte[] data) { tileKey = new TileDbKey(x, y, zoom); if (data == null) throw new NullPointerException("Tile data can not be null!"); this.data = data; this.timeDownloaded = System.currentTimeMillis(); } public TileDbEntry(int x, int y, int zoom, byte[] data, long timeLastModified, long timeExpires, String eTag) { this(x, y, zoom, data); this.timeLastModified = timeLastModified; this.timeExpires = timeExpires; this.eTag = eTag; } public void update(long timeExpires) { timeDownloaded = System.currentTimeMillis(); this.timeExpires = timeExpires; } public int getX() { return tileKey.x; } public int getY() { return tileKey.y; } public int getZoom() { return tileKey.zoom; } public byte[] getData() { return data; } public String geteTag() { return eTag; } public long getTimeLastModified() { return timeLastModified; } public long getTimeDownloaded() { return timeDownloaded; } public long getTimeExpires() { return timeExpires; } public String shortInfo() { return String.format("Tile z%d/%d/%d", tileKey.zoom, tileKey.x, tileKey.y); } @Override public String toString() { String tlm = (timeLastModified <= 0) ? "-" : new Date(timeLastModified).toString(); String txp = (timeExpires <= 0) ? "-" : new Date(timeExpires).toString(); return String.format("Tile z%d/%d/%d dl[%s] lm[%s] exp[%s] eTag[%s]", tileKey.zoom, tileKey.x, tileKey.y, new Date(timeDownloaded), tlm, txp, eTag); } @Persistent(version = 3) public static class TileDbKey { @KeyField(1) public int zoom; @KeyField(2) public int x; @KeyField(3) public int y; protected TileDbKey() { } public TileDbKey(int x, int y, int zoom) { super(); this.x = x; this.y = y; this.zoom = zoom; } @Override public String toString() { return "[x=" + x + ", y=" + y + ", zoom=" + zoom + "]"; } } } ././@LongLink0000000000000000000000000000015700000000000011570 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/tilestore/berkeleydb/DelayedInterruptThread.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/tilestore/berkeleydb/DelayedInterruptT0000644000175000017500000000464712122526606033402 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.tilestore.berkeleydb; import java.util.concurrent.ThreadFactory; /** * The Berkeley DB has some problems when someone interrupts the thread that is currently performing IO activity. * Therefore before executing any DB we allow to disable the {@link #interrupt()} method via {@link #pauseInterrupt()}. * After the "interrupt sensitive section" {@link #resumeInterrupt()} restores the regular behavior. If the thread has * been interrupted while interrupt was disabled {@link #resumeInterrupt()} catches up this. */ public class DelayedInterruptThread extends Thread { private boolean interruptPaused = false; private boolean interruptedWhilePaused = false; public DelayedInterruptThread(String name) { super(name); } public DelayedInterruptThread(Runnable target) { super(target); } public DelayedInterruptThread(Runnable target, String name) { super(target, name); } @Override public void interrupt() { if (interruptPaused) interruptedWhilePaused = true; else super.interrupt(); } public void pauseInterrupt() { interruptPaused = true; } public void resumeInterrupt() { interruptPaused = false; if (interruptedWhilePaused) this.interrupt(); } public boolean interruptedWhilePaused() { return interruptedWhilePaused; } public static ThreadFactory createThreadFactory() { return new DIThreadFactory(); } private static class DIThreadFactory implements ThreadFactory { public Thread newThread(Runnable r) { return new DelayedInterruptThread(r); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/tilestore/TileStoreEntry.java0000644000175000017500000000365612122526606031535 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.tilestore; public interface TileStoreEntry { public int getX(); public int getY(); public int getZoom(); /** * This function does never return a null value! * * @return tile data */ public byte[] getData(); /** * The time and date in UTC when this map tile has been downloaded * respectively has been checked the last time via HTTP If-None-Match, * If-Modified-Since or a HTTP HEAD request. * * @return Time in UTC */ public long getTimeDownloaded(); public void update(long timeExpires); /** * * @return Last modification time in UTC or 0 if not supported * by the server */ public long getTimeLastModified(); /** * * @return Expiration time in UTC or 0 if not supported by the * server */ public long getTimeExpires(); /** * The eTag contained in the HTTP answer on the last download/check request. * * @return eTag or null if not supported by the server */ public String geteTag(); } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/tilestore/TileStore.java0000644000175000017500000001031712150552674030510 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.tilestore; import java.awt.Point; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.swing.JOptionPane; import mobac.exceptions.TileStoreException; import mobac.program.DirectoryManager; import mobac.program.interfaces.MapSource; import mobac.program.model.Settings; import mobac.program.tilestore.berkeleydb.BerkeleyDbTileStore; import mobac.utilities.I18nUtils; import org.apache.log4j.Logger; public abstract class TileStore { protected static TileStore INSTANCE = null; protected Logger log; protected File tileStoreDir; public static synchronized void initialize() { if (INSTANCE != null) return; try { INSTANCE = new BerkeleyDbTileStore(); } catch (TileStoreException e) { String errMsg = I18nUtils.localizedStringForKey("msg_tile_store_access_conflict"); JOptionPane.showMessageDialog(null, errMsg, I18nUtils.localizedStringForKey("msg_tile_store_access_conflict_title"), JOptionPane.ERROR_MESSAGE); System.exit(1); } } public static TileStore getInstance() { return INSTANCE; } protected TileStore() { log = Logger.getLogger(this.getClass()); String tileStorePath = Settings.getInstance().directories.tileStoreDirectory; if (tileStorePath != null) tileStoreDir = new File(tileStorePath); else tileStoreDir = DirectoryManager.tileStoreDir; log.debug("Tile store path: " + tileStoreDir); } public abstract void putTileData(byte[] tileData, int x, int y, int zoom, MapSource mapSource) throws IOException; public abstract void putTileData(byte[] tileData, int x, int y, int zoom, MapSource mapSource, long timeLastModified, long timeExpires, String eTag) throws IOException; /** * * @param x * @param y * @param zoom * @param mapSource * @return */ public abstract TileStoreEntry getTile(int x, int y, int zoom, MapSource mapSource); public abstract boolean contains(int x, int y, int zoom, MapSource mapSource); public abstract void prepareTileStore(MapSource mapSource); public abstract void clearStore(String storeName); public abstract String[] getAllStoreNames(); /** * Returns true if the tile store directory of the specified {@link MapSource} exists. * * @param mapSource * @return */ public abstract boolean storeExists(MapSource mapSource); /** * * @param mapSourceName * @return * @throws InterruptedException */ public abstract TileStoreInfo getStoreInfo(String mapSourceName) throws InterruptedException; /** * * @param mapSource * @param zoom * @param tileNumMin * @param tileNumMax * @return * @throws InterruptedException */ public abstract BufferedImage getCacheCoverage(MapSource mapSource, int zoom, Point tileNumMin, Point tileNumMax) throws InterruptedException; public abstract void closeAll(); public abstract void putTile(TileStoreEntry tile, MapSource mapSource); public abstract TileStoreEntry createNewEntry(int x, int y, int zoom, byte[] data, long timeLastModified, long timeExpires, String eTag); /** * Creates a new {@link TileStoreEntry} that represents a missing tile in a sparse map source * * @param x * @param y * @param zoom * @return */ public abstract TileStoreEntry createNewEmptyEntry(int x, int y, int zoom); } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/tilestore/TileStoreInfo.java0000644000175000017500000000246612122526606031325 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.tilestore; public class TileStoreInfo { int tileCount; long storeSize; public TileStoreInfo(long storeSize, int tileCount) { super(); this.storeSize = storeSize; this.tileCount = tileCount; } /** * @return Number of tiles stored in the tile store */ public int getTileCount() { return tileCount; } /** * @return store size in bytes */ public long getStoreSize() { return storeSize; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/AtlasThread.java0000644000175000017500000003705212130520256026752 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program; import java.awt.Toolkit; import java.io.File; import java.io.IOException; import javax.swing.JOptionPane; import javax.swing.SwingUtilities; import mobac.exceptions.AtlasTestException; import mobac.exceptions.MapDownloadSkippedException; import mobac.gui.AtlasProgress; import mobac.gui.AtlasProgress.AtlasCreationController; import mobac.program.atlascreators.AtlasCreator; import mobac.program.atlascreators.tileprovider.DownloadedTileProvider; import mobac.program.atlascreators.tileprovider.FilteredMapSourceProvider; import mobac.program.atlascreators.tileprovider.TileProvider; import mobac.program.download.DownloadJobProducerThread; import mobac.program.interfaces.AtlasInterface; import mobac.program.interfaces.DownloadJobListener; import mobac.program.interfaces.DownloadableElement; import mobac.program.interfaces.FileBasedMapSource; import mobac.program.interfaces.LayerInterface; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSource.LoadMethod; import mobac.program.model.AtlasOutputFormat; import mobac.program.model.Settings; import mobac.program.tilestore.TileStore; import mobac.utilities.GUIExceptionHandler; import mobac.utilities.I18nUtils; import mobac.utilities.Utilities; import mobac.utilities.tar.TarIndex; import mobac.utilities.tar.TarIndexedArchive; import org.apache.log4j.Logger; public class AtlasThread extends Thread implements DownloadJobListener, AtlasCreationController { private static final Logger log = Logger.getLogger(AtlasThread.class); private static int threadNum = 0; private File customAtlasDir = null; private boolean quitMobacAfterAtlasCreation = false; private DownloadJobProducerThread djp = null; private JobDispatcher downloadJobDispatcher; private AtlasProgress ap; // The GUI showing the progress private AtlasInterface atlas; private AtlasCreator atlasCreator = null; private PauseResumeHandler pauseResumeHandler; private int activeDownloads = 0; private int jobsCompleted = 0; private int jobsRetryError = 0; private int jobsPermanentError = 0; private int maxDownloadRetries = 1; public AtlasThread(AtlasInterface atlas) throws AtlasTestException { this(atlas, atlas.getOutputFormat().createAtlasCreatorInstance()); } public AtlasThread(AtlasInterface atlas, AtlasCreator atlasCreator) throws AtlasTestException { super("AtlasThread " + getNextThreadNum()); ap = new AtlasProgress(this); this.atlas = atlas; this.atlasCreator = atlasCreator; testAtlas(); TileStore.getInstance().closeAll(); maxDownloadRetries = Settings.getInstance().downloadRetryCount; pauseResumeHandler = new PauseResumeHandler(); } private void testAtlas() throws AtlasTestException { try { for (LayerInterface layer : atlas) { for (MapInterface map : layer) { MapSource mapSource = map.getMapSource(); if (!atlasCreator.testMapSource(mapSource)) throw new AtlasTestException("The selected atlas output format \"" + atlas.getOutputFormat() + "\" does not support the map source \"" + map.getMapSource() + "\""); } } } catch (AtlasTestException e) { throw e; } catch (Exception e) { throw new AtlasTestException(e); } } private static synchronized int getNextThreadNum() { threadNum++; return threadNum; } public void run() { GUIExceptionHandler.registerForCurrentThread(); log.info("Starting creation of " + atlas.getOutputFormat() + " atlas \"" + atlas.getName() + "\""); if (customAtlasDir != null) log.debug("Target directory: " + customAtlasDir); ap.setDownloadControlerListener(this); try { createAtlas(); log.info("Altas creation finished"); if (quitMobacAfterAtlasCreation) System.exit(0); } catch (OutOfMemoryError e) { System.gc(); SwingUtilities.invokeLater(new Runnable() { public void run() { String message = I18nUtils.localizedStringForKey("msg_out_of_memory_head"); int maxMem = Utilities.getJavaMaxHeapMB(); if (maxMem > 0) message += String.format(I18nUtils.localizedStringForKey("msg_out_of_memory_detail"), maxMem); JOptionPane.showMessageDialog(null, message, I18nUtils.localizedStringForKey("msg_out_of_memory_title"), JOptionPane.ERROR_MESSAGE); ap.closeWindow(); } }); log.error("Out of memory: ", e); } catch (InterruptedException e) { SwingUtilities.invokeLater(new Runnable() { public void run() { JOptionPane.showMessageDialog(null, I18nUtils.localizedStringForKey("msg_atlas_download_abort"), I18nUtils.localizedStringForKey("Information"), JOptionPane.INFORMATION_MESSAGE); ap.closeWindow(); } }); log.info("Altas creation was interrupted by user"); } catch (Exception e) { log.error("Altas creation aborted because of an error: ", e); GUIExceptionHandler.showExceptionDialog(e); } System.gc(); if (quitMobacAfterAtlasCreation) { try { Thread.sleep(5000); } catch (InterruptedException e) { } System.exit(1); } } /** * Create atlas: For each map download the tiles and perform atlas/map creation */ protected void createAtlas() throws InterruptedException, IOException { long totalNrOfOnlineTiles = atlas.calculateTilesToDownload(); for (LayerInterface l : atlas) { for (MapInterface m : l) { // Offline map sources are not relevant for the maximum tile limit. if (m.getMapSource() instanceof FileBasedMapSource) totalNrOfOnlineTiles -= m.calculateTilesToDownload(); } } if (totalNrOfOnlineTiles > 500000) { // NumberFormat f = DecimalFormat.getInstance(); JOptionPane.showMessageDialog(null, String.format( I18nUtils.localizedStringForKey("msg_too_many_tiles_msg"), 500000, totalNrOfOnlineTiles), I18nUtils .localizedStringForKey("msg_too_many_tiles_title"), JOptionPane.ERROR_MESSAGE); return; } try { atlasCreator.startAtlasCreation(atlas, customAtlasDir); } catch (AtlasTestException e) { JOptionPane.showMessageDialog(null, e.getMessage(), "Atlas format restriction violated", JOptionPane.ERROR_MESSAGE); return; } ap.initAtlas(atlas); ap.setVisible(true); Settings s = Settings.getInstance(); downloadJobDispatcher = new JobDispatcher(s.downloadThreadCount, pauseResumeHandler, ap); try { for (LayerInterface layer : atlas) { atlasCreator.initLayerCreation(layer); for (MapInterface map : layer) { try { while (!createMap(map)) ; } catch (InterruptedException e) { throw e; // User has aborted } catch (MapDownloadSkippedException e) { // Do nothing and continue with next map } catch (Exception e) { log.error("", e); String[] options = { I18nUtils.localizedStringForKey("Continue"), I18nUtils.localizedStringForKey("Abort"), I18nUtils.localizedStringForKey("dlg_download_show_error_report") }; int a = JOptionPane.showOptionDialog(null, I18nUtils.localizedStringForKey("dlg_download_erro_head") + e.getMessage() + "\n[" + e.getClass().getSimpleName() + "]\n\n", I18nUtils.localizedStringForKey("Error"), 0, JOptionPane.ERROR_MESSAGE, null, options, options[0]); switch (a) { case 2: GUIExceptionHandler.processException(e); case 1: throw new InterruptedException(); } } } atlasCreator.finishLayerCreation(); } } catch (InterruptedException e) { atlasCreator.abortAtlasCreation(); throw e; } catch (Error e) { atlasCreator.abortAtlasCreation(); throw e; } finally { // In case of an abort: Stop create new download jobs if (djp != null) djp.cancel(); downloadJobDispatcher.terminateAllWorkerThreads(); if (!atlasCreator.isAborted()) atlasCreator.finishAtlasCreation(); ap.atlasCreationFinished(); } } /** * * @param map * @return true if map creation process was finished and false if something went wrong and the user decided to retry * map download * @throws Exception */ public boolean createMap(MapInterface map) throws Exception { TarIndex tileIndex = null; TarIndexedArchive tileArchive = null; jobsCompleted = 0; jobsRetryError = 0; jobsPermanentError = 0; ap.initMapDownload(map); if (currentThread().isInterrupted()) throw new InterruptedException(); // Prepare the tile store directory // ts.prepareTileStore(map.getMapSource()); /*** * In this section of code below, tiles for Atlas is being downloaded and saved in the temporary layer tar file * in the system temp directory. **/ int zoom = map.getZoom(); final int tileCount = (int) map.calculateTilesToDownload(); ap.setZoomLevel(zoom); try { tileArchive = null; TileProvider mapTileProvider; if (!(map.getMapSource() instanceof FileBasedMapSource)) { // For online maps we download the tiles first and then start creating the map if // we are sure we got all tiles if (!AtlasOutputFormat.TILESTORE.equals(atlas.getOutputFormat())) { String tempSuffix = "MOBAC_" + atlas.getName() + "_" + zoom + "_"; File tileArchiveFile = File.createTempFile(tempSuffix, ".tar", DirectoryManager.tempDir); // If something goes wrong the temp file only persists until the VM exits tileArchiveFile.deleteOnExit(); log.debug("Writing downloaded tiles to " + tileArchiveFile.getPath()); tileArchive = new TarIndexedArchive(tileArchiveFile, tileCount); } else log.debug("Downloading to tile store only"); djp = new DownloadJobProducerThread(this, downloadJobDispatcher, tileArchive, (DownloadableElement) map); boolean failedMessageAnswered = false; while (djp.isAlive() || (downloadJobDispatcher.getWaitingJobCount() > 0) || downloadJobDispatcher.isAtLeastOneWorkerActive()) { Thread.sleep(500); if (!failedMessageAnswered && (jobsRetryError > 50) && !ap.ignoreDownloadErrors()) { pauseResumeHandler.pause(); String[] answers = new String[] { I18nUtils.localizedStringForKey("Continue"), I18nUtils.localizedStringForKey("Retry"), I18nUtils.localizedStringForKey("Skip"), I18nUtils.localizedStringForKey("Abort") }; int answer = JOptionPane.showOptionDialog(ap, I18nUtils.localizedStringForKey("dlg_download_errors_todo_msg"), I18nUtils.localizedStringForKey("dlg_download_errors_todo"), 0, JOptionPane.QUESTION_MESSAGE, null, answers, answers[0]); failedMessageAnswered = true; switch (answer) { case 0: // Continue pauseResumeHandler.resume(); break; case 1: // Retry djp.cancel(); djp = null; downloadJobDispatcher.cancelOutstandingJobs(); return false; case 2: // Skip downloadJobDispatcher.cancelOutstandingJobs(); throw new MapDownloadSkippedException(); default: // Abort or close dialog downloadJobDispatcher.cancelOutstandingJobs(); downloadJobDispatcher.terminateAllWorkerThreads(); throw new InterruptedException(); } } } djp = null; log.debug("All download jobs has been completed!"); if (tileArchive != null) { tileArchive.writeEndofArchive(); tileArchive.close(); tileIndex = tileArchive.getTarIndex(); if (tileIndex.size() < tileCount && !ap.ignoreDownloadErrors()) { int missing = tileCount - tileIndex.size(); log.debug("Expected tile count: " + tileCount + " downloaded tile count: " + tileIndex.size() + " missing: " + missing); int answer = JOptionPane.showConfirmDialog(ap, String.format( I18nUtils.localizedStringForKey("dlg_download_errors_missing_tile_msg"), missing), I18nUtils.localizedStringForKey("dlg_download_errors_missing_tile"), JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE); if (answer != JOptionPane.YES_OPTION) throw new InterruptedException(); } } downloadJobDispatcher.cancelOutstandingJobs(); log.debug("Starting to create atlas from downloaded tiles"); mapTileProvider = new DownloadedTileProvider(tileIndex, map); } else { // We don't need to download anything. Everything is already stored locally therefore we can just use it mapTileProvider = new FilteredMapSourceProvider(map, LoadMethod.DEFAULT); } atlasCreator.initializeMap(map, mapTileProvider); atlasCreator.createMap(); } catch (Error e) { log.error("Error in createMap: " + e.getMessage(), e); throw e; } finally { if (tileIndex != null) tileIndex.closeAndDelete(); else if (tileArchive != null) tileArchive.delete(); } return true; } public void pauseResumeAtlasCreation() { if (pauseResumeHandler.isPaused()) { log.debug("Atlas creation resumed"); pauseResumeHandler.resume(); } else { log.debug("Atlas creation paused"); pauseResumeHandler.pause(); } } public boolean isPaused() { return pauseResumeHandler.isPaused(); } public PauseResumeHandler getPauseResumeHandler() { return pauseResumeHandler; } /** * Stop listener from {@link AtlasProgress} */ public void abortAtlasCreation() { try { DownloadJobProducerThread djp_ = djp; if (djp_ != null) djp_.cancel(); if (downloadJobDispatcher != null) downloadJobDispatcher.terminateAllWorkerThreads(); pauseResumeHandler.resume(); this.interrupt(); } catch (Exception e) { log.error("Exception thrown in stopDownload()" + e.getMessage()); } } public int getActiveDownloads() { return activeDownloads; } public synchronized void jobStarted() { activeDownloads++; } public void jobFinishedSuccessfully(int bytesDownloaded) { synchronized (this) { ap.incMapDownloadProgress(); activeDownloads--; jobsCompleted++; } ap.updateGUI(); } public void jobFinishedWithError(boolean retry) { synchronized (this) { activeDownloads--; if (retry) jobsRetryError++; else { jobsPermanentError++; ap.incMapDownloadProgress(); } } if (!ap.ignoreDownloadErrors()) Toolkit.getDefaultToolkit().beep(); ap.setErrorCounter(jobsRetryError, jobsPermanentError); ap.updateGUI(); } public int getMaxDownloadRetries() { return maxDownloadRetries; } public AtlasProgress getAtlasProgress() { return ap; } public File getCustomAtlasDir() { return customAtlasDir; } public void setCustomAtlasDir(File customAtlasDir) { this.customAtlasDir = customAtlasDir; } public void setQuitMobacAfterAtlasCreation(boolean quitMobacAfterAtlasCreation) { this.quitMobacAfterAtlasCreation = quitMobacAfterAtlasCreation; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/commandline/0000755000175000017500000000000012130520254026170 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/commandline/CommandLineEmpty.java0000644000175000017500000000235612122526604032254 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.commandline; import mobac.program.interfaces.CommandLineAction; public class CommandLineEmpty implements CommandLineAction { @Override public void runBeforeMainGUI() { } @Override public void runMainGUI() { } @Override public boolean showSplashScreen() { return true; } @Override public boolean showMainGUI() { return true; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/commandline/CreateAtlas.java0000644000175000017500000000543212130520254031227 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.commandline; import java.io.File; import javax.xml.bind.JAXBException; import mobac.program.AtlasThread; import mobac.program.interfaces.AtlasInterface; import mobac.program.interfaces.CommandLineAction; import mobac.program.model.Profile; import mobac.utilities.GUIExceptionHandler; public class CreateAtlas implements CommandLineAction { private final String profileName; private final File outputDir; public CreateAtlas(String profileName) { this(profileName, null); } public CreateAtlas(String profileName, String outputDirectory) { super(); this.profileName = profileName; if (outputDirectory != null) { File dir = new File(outputDirectory); if (dir.isDirectory() || dir.exists()) { System.err.println("Error: Atlas output directory \"" + outputDirectory + "\" already exists."); System.exit(1); } outputDir = dir; } else outputDir = null; } @Override public void runBeforeMainGUI() { try { Profile p = new Profile(profileName); if (!p.exists()) { System.err.println("Profile \"" + profileName + "\" could not be loaded:"); System.err.println("File \"" + p.getFile().getAbsolutePath() + "\" does not exist."); System.exit(1); } AtlasInterface atlas = null; try { atlas = p.load(); } catch (JAXBException e) { System.err.println("Error loading profile \"" + profileName + "\"."); e.printStackTrace(); System.exit(1); } AtlasThread atlasThread = new AtlasThread(atlas); if (outputDir != null) atlasThread.setCustomAtlasDir(outputDir); atlasThread.setQuitMobacAfterAtlasCreation(true); atlasThread.start(); } catch (Exception e) { GUIExceptionHandler.processException(e); } } @Override public void runMainGUI() { } @Override public boolean showSplashScreen() { return false; } @Override public boolean showMainGUI() { return false; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/0000755000175000017500000000000012174511554026564 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/RunGPSAtlas.java0000644000175000017500000001321512122526606031531 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; import java.util.Set; import javax.imageio.ImageIO; import mobac.exceptions.AtlasTestException; import mobac.exceptions.MapCreationException; import mobac.mapsources.mapspace.MercatorPower2MapSpace; import mobac.program.annotations.AtlasCreatorName; import mobac.program.atlascreators.impl.rungps.RunGPSAtlasFile; import mobac.program.atlascreators.tileprovider.ConvertedRawTileProvider; import mobac.program.atlascreators.tileprovider.TileProvider; import mobac.program.interfaces.AtlasInterface; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSource; import mobac.program.model.TileImageFormat; import mobac.program.model.TileImageType; /** * Creates maps using the Run.GPS Trainer atlas format. * * Please note that this atlas format ignores the defined atlas structure. * *

* Run.GPS Atlas format has been designed to support huge collections of maps (2 GB and more) and for very fast access * (using a numeric index at the beginning of an atlas file). The file format can hold integer values, strings and * binary data. The file format is described on this page: http://www.rungps.net/wiki/RunGPSAtlasFormat (full sample * source code is available). *

*/ @AtlasCreatorName(value = "Run.GPS Atlas", type = "RunGPS") public class RunGPSAtlas extends AtlasCreator { protected RunGPSAtlasFile atlasIndex = null; protected Set availableTileList = new HashSet(); protected int minZoom, maxZoom; @Override public boolean testMapSource(MapSource mapSource) { return MercatorPower2MapSpace.INSTANCE_256.equals(mapSource.getMapSpace()); } @Override public void startAtlasCreation(AtlasInterface atlas, File customAtlasDir) throws IOException, InterruptedException, AtlasTestException { super.startAtlasCreation(atlas, customAtlasDir); String atlasName = this.atlas.getName().replace(' ', '_'); atlasIndex = new RunGPSAtlasFile(atlasDir.getPath() + File.separatorChar + atlasName + RunGPSAtlasFile.SUFFIX, true); minZoom = Integer.MAX_VALUE; maxZoom = Integer.MIN_VALUE; } @Override public void abortAtlasCreation() throws IOException { atlasIndex.close(); super.abortAtlasCreation(); } @Override public void finishAtlasCreation() throws IOException, InterruptedException { super.finishAtlasCreation(); // log.debug(atlasIndex.listAll()); // archive data atlasIndex.setValue("/0/0/0", 3L); // file format version atlasIndex.setString("/0/0/1", "Run.GPS Atlas File"); // type atlasIndex.setString("/0/0/2", atlas.getName()); // atlas name atlasIndex.setString("/0/0/3", mapSource.getName()); // map source name atlasIndex.setString("/0/0/4", "Mobile Atlas Creator"); // created by // metadata atlasIndex.setValue("/0/1/1", minZoom); atlasIndex.setValue("/0/1/2", maxZoom); // create file atlasIndex.finishArchive(); atlasIndex.close(); } @Override public void initializeMap(MapInterface map, TileProvider mapTileProvider) { super.initializeMap(map, mapTileProvider); } public void createMap() throws MapCreationException, InterruptedException { if (mapSource.getTileImageType() != TileImageType.PNG) // If the tile image format is not png we have to convert it mapDlTileProvider = new ConvertedRawTileProvider(mapDlTileProvider, TileImageFormat.PNG); createTiles(); } protected void createTiles() throws InterruptedException, MapCreationException { atlasProgress.initMapCreation((xMax - xMin + 1) * (yMax - yMin + 1)); ImageIO.setUseCache(false); String mapName = map.getMapSource().getName().replaceAll(" ", "_"); for (int x = xMin; x <= xMax; x++) { for (int y = yMin; y <= yMax; y++) { checkUserAbort(); atlasProgress.incMapCreationProgress(); try { byte[] sourceTileData = mapDlTileProvider.getTileData(x, y); if (sourceTileData != null) { writeTile(mapName, sourceTileData, x, y, zoom); } } catch (IOException e) { throw new MapCreationException("Error writing tile image: " + e.getMessage(), map, e); } } } } protected boolean writeTile(String cache, byte[] tileData, int x, int y, int zoom) throws IOException { if (zoom < minZoom) minZoom = zoom; if (zoom > maxZoom) maxZoom = zoom; String cacheKey = cache + "-" + zoom + "-" + x + "-" + y; if (availableTileList.contains(cacheKey)) { log.warn("Map tile already in cache: " + cacheKey + " -> ignoring"); return false; } ArrayList hierarchy = new ArrayList(); hierarchy.add(zoom); hierarchy.add(x); hierarchy.add(y); atlasIndex.addData(hierarchy, tileData); return true; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/TrekBuddyTared.java0000644000175000017500000000723712122526604032310 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.util.LinkedList; import java.util.List; import mobac.program.annotations.AtlasCreatorName; import mobac.program.atlascreators.impl.MapTileWriter; import mobac.utilities.Utilities; import mobac.utilities.tar.TarArchive; import mobac.utilities.tar.TarTmiArchive; @AtlasCreatorName(value = "TrekBuddy tared atlas", type = "TaredAtlas") public class TrekBuddyTared extends TrekBuddy { @Override public void finishAtlasCreation() { createAtlasTarArchive("cr"); } private void createAtlasTarArchive(String name) { log.trace("Creating cr.tar for atlas in dir \"" + atlasDir.getPath() + "\""); File[] atlasLayerDirs = Utilities.listSubDirectories(atlasDir); List atlasMapDirs = new LinkedList(); for (File dir : atlasLayerDirs) Utilities.addSubDirectories(atlasMapDirs, dir, 0); TarArchive ta = null; File crFile = new File(atlasDir, name + ".tar"); try { ta = new TarArchive(crFile, atlasDir); ta.writeFileFromData(name + ".tba", "Atlas 1.0\r\n".getBytes()); for (File mapDir : atlasMapDirs) { ta.writeFile(mapDir); File mapFile = new File(mapDir, mapDir.getName() + ".map"); ta.writeFile(mapFile); try { mapFile.delete(); } catch (Exception e) { } } ta.writeEndofArchive(); } catch (IOException e) { log.error("Failed writing tar file \"" + crFile.getPath() + "\"", e); } finally { if (ta != null) ta.close(); } } @Override protected MapTileWriter createMapTileWriter() throws IOException { return new TarTileWriter(); } private class TarTileWriter implements MapTileWriter { TarArchive ta = null; int tileHeight = 256; int tileWidth = 256; public TarTileWriter() { super(); if (parameters != null) { tileHeight = parameters.getHeight(); tileWidth = parameters.getWidth(); } File mapTarFile = new File(mapDir, map.getName() + ".tar"); log.debug("Writing tiles to tared map: " + mapTarFile); try { ta = new TarTmiArchive(mapTarFile, null); ByteArrayOutputStream buf = new ByteArrayOutputStream(8192); writeMapFile(buf); ta.writeFileFromData(map.getName() + ".map", buf.toByteArray()); } catch (IOException e) { log.error("", e); } } public void writeTile(int tilex, int tiley, String imageFormat, byte[] tileData) throws IOException { String tileFileName = String.format(FILENAME_PATTERN, (tilex * tileWidth), (tiley * tileHeight), imageFormat); ta.writeFileFromData("set/" + tileFileName, tileData); } public void finalizeMap() { try { ta.writeEndofArchive(); } catch (IOException e) { log.error("", e); } ta.close(); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/PNGWorldfile.java0000644000175000017500000001140112131416126031710 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.util.Locale; import mobac.exceptions.MapCreationException; import mobac.program.annotations.AtlasCreatorName; import mobac.utilities.Utilities; /** * http://sourceforge.net/p/mobac/feature-requests/136/ */ @AtlasCreatorName("PNG + Worldfile (PNG & PGW)") public class PNGWorldfile extends Glopus { @Override public void createMap() throws MapCreationException, InterruptedException { try { Utilities.mkDir(layerDir); } catch (IOException e) { throw new MapCreationException(map, e); } createTiles(); writeWorldFile(); writeProjectionFile(); } /** * http://en.wikipedia.org/wiki/World_file * *
	 * Format of Worldfile: 
	 * 			   0.000085830078125  (size of pixel in x direction)                              =(east-west)/image width
	 * 			   0.000000000000     (rotation term for row)
	 * 			   0.000000000000     (rotation term for column)
	 * 			   -0.00006612890625  (size of pixel in y direction)                              =-(north-south)/image height
	 * 			   -106.54541         (x coordinate of centre of upper left pixel in map units)   =west
	 * 			   39.622615          (y coordinate of centre of upper left pixel in map units)   =north
	 * 
*/ private void writeWorldFile() throws MapCreationException { FileOutputStream fout = null; try { fout = new FileOutputStream(new File(layerDir, mapName + ".pgw")); OutputStreamWriter mapWriter = new OutputStreamWriter(fout, TEXT_FILE_CHARSET); // MapSpace mapSpace = mapSource.getMapSpace(); double worldSize = 2 * Math.PI * 6378137; double maxTiles = 1 << zoom; double pixelSize = worldSize / (maxTiles * tileSize); mapWriter.write(String.format(Locale.ENGLISH, "%.15f\n", pixelSize)); mapWriter.write("0.0\n"); mapWriter.write("0.0\n"); mapWriter.write(String.format(Locale.ENGLISH, "%.15f\n", -pixelSize)); double xMin1 = worldSize * (xMin / maxTiles - 0.5); double yMax1 = worldSize * (0.5 - yMin / maxTiles); mapWriter.write(String.format(Locale.ENGLISH, "%.7f\n", xMin1 + 0.5 * pixelSize)); mapWriter.write(String.format(Locale.ENGLISH, "%.7f\n", yMax1 - 0.5 * pixelSize)); mapWriter.flush(); mapWriter.close(); } catch (IOException e) { throw new MapCreationException(map, e); } finally { Utilities.closeStream(fout); } } private void writeProjectionFile() throws MapCreationException { FileOutputStream fout = null; try { fout = new FileOutputStream(new File(layerDir, mapName + ".png.aux.xml")); OutputStreamWriter writer = new OutputStreamWriter(fout, TEXT_FILE_CHARSET); writer.write("PROJCS["WGS 84 / Pseudo-Mercator",GEOGCS["WGS 84"," + "DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563," + "AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]]," + "PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]," + "AUTHORITY["EPSG","4326"]]," + "PROJECTION["Mercator_1SP"],PARAMETER["central_meridian",0]," + "PARAMETER["scale_factor",1],PARAMETER["false_easting",0]," + "PARAMETER["false_northing",0],UNIT["metre",1," + "AUTHORITY["EPSG","9001"]]," + "EXTENSION["PROJ4","+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs"]," + "AUTHORITY["EPSG","3857"]]"); writer.flush(); writer.close(); } catch (IOException e) { throw new MapCreationException(map, e); } finally { Utilities.closeStream(fout); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/NaviComputer.java0000644000175000017500000002055712127544344032055 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.io.File; import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.text.SimpleDateFormat; import java.util.Date; import mobac.exceptions.AtlasTestException; import mobac.exceptions.MapCreationException; import mobac.mapsources.mapspace.MercatorPower2MapSpace; import mobac.program.annotations.AtlasCreatorName; import mobac.program.annotations.SupportedParameters; import mobac.program.atlascreators.tileprovider.ConvertedRawTileProvider; import mobac.program.interfaces.AtlasInterface; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.RequiresSQLite; import mobac.program.model.Settings; import mobac.program.model.TileImageParameters.Name; import mobac.utilities.Utilities; import mobac.utilities.jdbc.SQLiteLoader; @AtlasCreatorName("NaviComputer (NMAP)") @SupportedParameters(names = { Name.format }) public class NaviComputer extends AtlasCreator implements RequiresSQLite { private static final String NAVI_TABLES = "CREATE TABLE MapInfo (MapType TEXT, Zoom INTEGER NOT NULL, MinX INTEGER, MaxX INTEGER, MinY INTEGER, MaxY INTEGER);\n" + "CREATE TABLE Tiles (id INTEGER NOT NULL PRIMARY KEY, X INTEGER NOT NULL, Y INTEGER NOT NULL, Zoom INTEGER NOT NULL);\n" + "CREATE TABLE TilesData (id INTEGER NOT NULL PRIMARY KEY CONSTRAINT fk_Tiles_id REFERENCES Tiles(id) ON DELETE CASCADE, Tile BLOB NULL);\n" + "CREATE TRIGGER fkdc_TilesData_id_Tiles_id " + "BEFORE DELETE ON Tiles " + "FOR EACH ROW BEGIN " + "DELETE FROM TilesData WHERE TilesData.id = OLD.id; " + "END;\n" + "CREATE TRIGGER fki_TilesData_id_Tiles_id " + "BEFORE INSERT ON [TilesData] " + "FOR EACH ROW BEGIN " + "SELECT RAISE(ROLLBACK, 'insert on table TilesData violates foreign key constraint fki_TilesData_id_Tiles_id') " + "WHERE (SELECT id FROM Tiles WHERE id = NEW.id) IS NULL; " + "END;\n" + "CREATE TRIGGER fku_TilesData_id_Tiles_id " + "BEFORE UPDATE ON [TilesData] " + "FOR EACH ROW BEGIN " + "SELECT RAISE(ROLLBACK, 'update on table TilesData violates foreign key constraint fku_TilesData_id_Tiles_id') " + "WHERE (SELECT id FROM Tiles WHERE id = NEW.id) IS NULL; " + "END;\n" + "CREATE INDEX IndexOfTiles ON Tiles (X, Y, Zoom);"; private static final String INSERT_TILES = "INSERT INTO Tiles (id,X,Y,Zoom) VALUES (?,?,?,?)"; private static final String INSERT_TILES_DATA = "INSERT INTO TilesData (id,Tile) VALUES (?,?)"; private static final String INSERT_MAP_INFO = "INSERT INTO MapInfo (MapType,Zoom,MinX,MaxX,MinY,MaxY) " + "SELECT ?,Min(Zoom),Min(x),Max(x),Min(y),Max(y) FROM Tiles WHERE Zoom=?;"; private String databaseFile; private int wmsTileCount = 1; private static final int COMMIT_RATE = 100; private int tileCommitCounter = 0; protected Connection conn = null; private PreparedStatement prepTilesData = null, prepTiles = null; @Override public boolean testMapSource(MapSource mapSource) { return MercatorPower2MapSpace.INSTANCE_256.equals(mapSource.getMapSpace()); } @Override protected void testAtlas() throws AtlasTestException { performTest_MaxMapZoom(18); } @Override public void startAtlasCreation(AtlasInterface atlas, File customAtlasDir) throws IOException, AtlasTestException, InterruptedException { if (customAtlasDir == null) customAtlasDir = Settings.getInstance().getAtlasOutputDirectory(); super.startAtlasCreation(atlas, customAtlasDir); databaseFile = getDatabaseFileName(); log.debug("SQLite Database file: " + databaseFile); try { SQLiteLoader.loadSQLite(); } catch (SQLException e) { throw new IOException(SQLiteLoader.getMsgSqliteMissing(), e); } try { Utilities.mkDir(atlasDir); openConnection(); initializeDB(); prepTilesData = conn.prepareStatement(INSERT_TILES_DATA); prepTiles = conn.prepareStatement(INSERT_TILES); } catch (SQLException e) { throw new AtlasTestException("Error creating SQL database \"" + databaseFile + "\": " + e.getMessage(), e); } } @Override public void createMap() throws MapCreationException, InterruptedException { if (parameters != null) mapDlTileProvider = new ConvertedRawTileProvider(mapDlTileProvider, parameters.getFormat()); createTiles(); } private void openConnection() throws SQLException { if (conn == null || conn.isClosed()) { String url = "jdbc:sqlite:/" + this.databaseFile; conn = DriverManager.getConnection(url); } } @Override public void abortAtlasCreation() throws IOException { SQLiteLoader.closeConnection(conn); conn = null; super.abortAtlasCreation(); } @Override public void finishAtlasCreation() throws IOException, InterruptedException { String mapName = mapSource.getName(); try { PreparedStatement prepStat = conn.prepareStatement(INSERT_MAP_INFO); Statement stat = conn.createStatement(); ResultSet rs = stat.executeQuery("SELECT Distinct Zoom From Tiles"); while (rs.next()) { int zoom = rs.getInt(1); prepStat.setString(1, mapName); prepStat.setInt(2, zoom); prepStat.execute(); } conn.commit(); prepStat.close(); } catch (SQLException e) { log.error(e.getMessage()); } finally { SQLiteLoader.closeConnection(conn); conn = null; } super.finishAtlasCreation(); } protected void initializeDB() throws SQLException { Statement stat = conn.createStatement(); String[] sqlList = NAVI_TABLES.split("\\n"); for (String sql : sqlList) stat.addBatch(sql); stat.executeBatch(); stat.close(); log.debug("Database initialization complete: tables, trigges and index created"); } protected void createTiles() throws InterruptedException, MapCreationException { int maxMapProgress = (xMax - xMin + 1) * (yMax - yMin + 1); atlasProgress.initMapCreation(maxMapProgress); try { tileCommitCounter = 0; conn.setAutoCommit(false); Runtime r = Runtime.getRuntime(); for (int x = xMin; x <= xMax; x++) { for (int y = yMin; y <= yMax; y++) { checkUserAbort(); atlasProgress.incMapCreationProgress(); try { byte[] sourceTileData = mapDlTileProvider.getTileData(x, y); if (sourceTileData != null) { tileCommitCounter++; writeTile(wmsTileCount++, x, y, zoom, sourceTileData); long heapAvailable = r.maxMemory() - r.totalMemory() + r.freeMemory(); if (heapAvailable < HEAP_MIN || tileCommitCounter > COMMIT_RATE) { conn.commit(); tileCommitCounter = 0; System.gc(); } } } catch (IOException e) { throw new MapCreationException(map, e); } } } conn.commit(); atlasProgress.setMapCreationProgress(maxMapProgress); } catch (SQLException e) { throw new MapCreationException(map, e); } } protected void writeTile(int id, int x, int y, int z, byte[] tileData) throws SQLException, IOException { prepTiles.setInt(1, id); prepTiles.setInt(2, x); prepTiles.setInt(3, y); prepTiles.setInt(4, z); prepTiles.execute(); prepTilesData.setInt(1, id); prepTilesData.setBytes(2, tileData); prepTilesData.execute(); } protected String getDatabaseFileName() { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd_HHmmss_"); databaseFile = new File(atlasDir, sdf.format(new Date()) + atlas.getName() + ".nmap").getAbsolutePath(); return databaseFile; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/OruxMapsSqlite.java0000644000175000017500000001474612127544344032404 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.io.File; import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Statement; import java.util.Locale; import mobac.exceptions.AtlasTestException; import mobac.exceptions.MapCreationException; import mobac.program.annotations.AtlasCreatorName; import mobac.program.atlascreators.impl.MapTileWriter; import mobac.program.atlascreators.tileprovider.CacheTileProvider; import mobac.program.interfaces.AtlasInterface; import mobac.program.interfaces.LayerInterface; import mobac.program.interfaces.RequiresSQLite; import mobac.utilities.jdbc.SQLiteLoader; /** * Creates maps using the OruxMaps (Android) atlas format. * * @author orux Some code based on BigPlanetSql atlascreator */ @AtlasCreatorName("OruxMaps Sqlite") public class OruxMapsSqlite extends OruxMaps implements RequiresSQLite { private static final String TABLE_TILES_DDL = "CREATE TABLE IF NOT EXISTS tiles (x int, y int, z int, image blob, PRIMARY KEY (x,y,z))"; private static final String INDEX_DDL = "CREATE INDEX IF NOT EXISTS IND on tiles (x,y,z)"; private static final String INSERT_SQL = "INSERT or IGNORE INTO tiles (x,y,z,image) VALUES (?,?,?,?)"; private static final String TABLE_ANDROID_METADATA_DDL = "CREATE TABLE IF NOT EXISTS android_metadata (locale TEXT)"; private static final String DATABASE_FILENAME = "OruxMapsImages.db"; private String databaseFile; private Connection conn = null; private PreparedStatement prepStmt; private StringBuilder otrk2MapsContent; public OruxMapsSqlite() { super(); SQLiteLoader.loadSQLiteOrShowError(); calVersionCode = "3.0"; } /* * (non-Javadoc) * * @see mobac.program.atlascreators.AtlasCreator#startAtlasCreation(mobac.program.interfaces.AtlasInterface) */ @Override public void startAtlasCreation(AtlasInterface atlas, File customAtlasDir) throws AtlasTestException, IOException, InterruptedException { super.startAtlasCreation(atlas, customAtlasDir); try { SQLiteLoader.loadSQLite(); } catch (SQLException e) { throw new AtlasTestException(SQLiteLoader.getMsgSqliteMissing(), e); } } /* * @see mobac.program.atlascreators.AtlasCreator#initLayerCreation(mobac.program .interfaces.LayerInterface) */ @Override public void initLayerCreation(LayerInterface layer) throws IOException { super.initLayerCreation(layer); databaseFile = new File(oruxMapsMainDir, DATABASE_FILENAME).getAbsolutePath(); log.debug("SQLite Database file: " + databaseFile); otrk2MapsContent = new StringBuilder(); try { conn = getConnection(); initializeDB(); conn.close(); } catch (SQLException e) { throw new IOException(e); } } private Connection getConnection() throws SQLException { String url = "jdbc:sqlite:/" + this.databaseFile; Connection conn = DriverManager.getConnection(url); return conn; } private void initializeDB() throws SQLException { Statement stat = conn.createStatement(); stat.executeUpdate(TABLE_TILES_DDL); stat.executeUpdate(INDEX_DDL); stat.executeUpdate(TABLE_ANDROID_METADATA_DDL); stat.executeUpdate("INSERT INTO android_metadata VALUES ('" + Locale.getDefault().toString() + "')"); stat.close(); } @Override public void createMap() throws MapCreationException, InterruptedException { otrk2MapsContent.append(prepareOtrk2File()); try { conn = getConnection(); conn.setAutoCommit(false); prepStmt = conn.prepareStatement(INSERT_SQL); createTiles(); conn.close(); } catch (InterruptedException e) { // User has aborted process return; } catch (MapCreationException e) { throw e; } catch (Exception e) { throw new MapCreationException(map, e); } } @Override protected void createTiles() throws InterruptedException, MapCreationException { CacheTileProvider ctp = new CacheTileProvider(mapDlTileProvider); try { mapDlTileProvider = ctp; MapTileWriter mtw = new OruxMapTileWriterDB(); OruxMapTileBuilder mapTileBuilder = new OruxMapTileBuilder(this, mtw); //customTileCount = mapTileBuilder.getCustomTileCount(); atlasProgress.initMapCreation(mapTileBuilder.getCustomTileCount()); mapTileBuilder.createTiles(); mtw.finalizeMap(); } catch(IOException e){ throw new MapCreationException(map, e); }finally { ctp.cleanup(); } } @Override protected String appendMapContent() { return otrk2MapsContent.toString(); } private class OruxMapTileWriterDB implements MapTileWriter { private static final int MAX_BATCH_SIZE = 1000; private int tileCounter = 0; private Runtime r = Runtime.getRuntime(); public void writeTile(int tilex, int tiley, String tileType, byte[] tileData) throws IOException { try { prepStmt.setInt(1, tilex); prepStmt.setInt(2, tiley); prepStmt.setInt(3, zoom); prepStmt.setBytes(4, tileData); prepStmt.addBatch(); long heapAvailable = r.maxMemory() - r.totalMemory() + r.freeMemory(); tileCounter++; if (heapAvailable < HEAP_MIN || tileCounter > MAX_BATCH_SIZE) { commit(); } } catch (SQLException e) { throw new IOException(e); } } private void commit() throws SQLException { prepStmt.executeBatch(); prepStmt.clearBatch(); atlasProgress.incMapCreationProgress(tileCounter); tileCounter = 0; conn.commit(); System.gc(); } public void finalizeMap() throws IOException { try { commit(); } catch (SQLException e) { throw new IOException(e); } } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/PaperAtlas.java0000644000175000017500000002770712127544344031501 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Insets; import java.awt.Point; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.JComponent; import javax.swing.JPanel; import mobac.exceptions.MapCreationException; import mobac.gui.mapview.ScaleBar; import mobac.gui.mapview.WgsGrid; import mobac.mapsources.mapspace.MercatorPower2MapSpace; import mobac.program.interfaces.LayerInterface; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSpace; import mobac.program.interfaces.MapSpace.ProjectionCategory; import mobac.program.model.Settings; import mobac.program.model.SettingsPaperAtlas; import mobac.program.model.SettingsWgsGrid; import mobac.program.model.UnitSystem; import mobac.utilities.Utilities; public abstract class PaperAtlas extends AtlasCreator { private static final Font PAGE_NUMBER_FONT = new Font(Font.SANS_SERIF, Font.BOLD, 24), LABEL_FONT = new Font( Font.SANS_SERIF, Font.BOLD, 12); private static final Color LABEL_BACKGROUND = new Color(0, 127, 0), LABEL_FOREGROUND = Color.WHITE, IMAGE_BACKGROUND = new Color(0, 0, 0, 0); private static final String UP = " \u2191", DOWN = " \u2193"; protected static class Page { protected final BufferedImage image; protected final int number, width, height; protected Page(int number, BufferedImage image) { this.number = number; this.image = image; this.width = image.getWidth(); this.height = image.getHeight(); } } private final JComponent dummy = new JPanel(); private final WgsGrid wgsGrid; private final int overlap; private final Insets insets = new Insets(0, 0, 0, 0); protected final SettingsPaperAtlas s; private int tileImageScale = 1; private File layerFolder; // base: page Size整数倍区域, // bottom:最底下的不能被page Height整除的区域 // right:最右侧的不能被page Width整除的区域 // corner:右下角区域,不能被page Size整除的部分 private Dimension base, bottom, right, corner; protected PaperAtlas(final boolean usePadding) { s = Settings.getInstance().paperAtlas.clone(); overlap = (int) UnitSystem.pointsToPixels(s.overlap, s.dpi); if (s.wgsEnabled) { SettingsWgsGrid sWgsGrid = Settings.getInstance().wgsGrid.clone(); sWgsGrid.enabled = s.wgsEnabled; sWgsGrid.density = s.wgsDensity; wgsGrid = new WgsGrid(sWgsGrid, dummy); } else { wgsGrid = null; } if (usePadding) { insets.top = (int) UnitSystem.pointsToPixels(s.marginTop, s.dpi); insets.left = (int) UnitSystem.pointsToPixels(s.marginLeft, s.dpi); insets.bottom = (int) UnitSystem.pointsToPixels(s.marginBottom, s.dpi); insets.right = (int) UnitSystem.pointsToPixels(s.marginTop, s.dpi); } if (s.paperSize != null) { double width = s.paperSize.width - s.marginLeft - s.marginRight; double height = s.paperSize.height - s.marginTop - s.marginBottom; width = UnitSystem.pointsToPixels(width, s.dpi); height = UnitSystem.pointsToPixels(height, s.dpi); base = new Dimension((int) width, (int) height); } } @Override public void createMap() throws MapCreationException, InterruptedException { corner = right = bottom = null; tileImageScale = getTileImageScale(); int mapWidth = (xMax - xMin + 1) * tileSize * tileImageScale; int mapHeight = (yMax - yMin + 1) * tileSize * tileImageScale; if (base == null) { base = new Dimension(mapWidth, mapHeight); processPages(1, 1); base = null; } else { // 最后一页少于页宽度的crop百分百的,会裁剪掉,即抛弃。 int sWidth = (mapWidth) % (base.width - overlap); if ((double) sWidth / base.getWidth() * 100d < s.crop) { sWidth = 0; } int sHeight = (mapHeight) % (base.height - overlap); if ((double) sHeight / base.getHeight() * 100d < s.crop) { sHeight = 0; } if (sHeight > 0 && sWidth > 0) { corner = new Dimension(sWidth, sHeight); } if (sWidth > 0) { right = new Dimension(sWidth, base.height); } if (sHeight > 0) { bottom = new Dimension(base.width, sHeight); } int rows = (mapHeight) / (base.height - overlap) + (bottom != null ? 1 : 0); int cols = (mapWidth) / (base.width - overlap) + (right != null ? 1 : 0); processPages(rows, cols); } } protected File getLayerFolder() { return layerFolder; } public void initLayerCreation(LayerInterface layer) throws IOException { super.initLayerCreation(layer); layerFolder = new File(atlasDir, layer.getName()); Utilities.mkDirs(layerFolder); } /** * check first existing image and return its scale. 2 means for retina( 512x512), 1 means normal * * @return */ protected int getTileImageScale() { int tileImageScale = 1; if (mapDlTileProvider == null) { return tileImageScale; } // init tileScale for check if there has retina tile try { // use loop because xMin, xMax may has no data for (int x = xMin; x <= xMax; x++) { for (int y = yMin; y <= yMax; y++) { BufferedImage tile = mapDlTileProvider.getTileImage(x, y); if (tile != null) { tileImageScale = tile.getWidth() / tileSize; break; // skip when get } } } // for invalid tileScale if (tileImageScale != 2) { log.debug("invalid tile Scale for Paper Atlas " + tileImageScale); tileImageScale = 1; } } catch (IOException e) { tileImageScale = 1; } return tileImageScale; } protected abstract void processPage(BufferedImage image, int pageNumber) throws MapCreationException; private void processPages(final int ROWS, final int COLS) throws MapCreationException, InterruptedException { try { atlasProgress.initMapCreation(ROWS * COLS * 2); for (int row = 0; row < ROWS; row++) { for (int col = 0; col < COLS; col++) { log.trace(String.format("cal=%d row=%d", col, row)); // Choose image Dimension size; boolean firstRow = row == 0; boolean lastRow = row + 1 == ROWS; boolean lastCol = col + 1 == COLS; if (corner != null && lastRow && lastCol) { size = new Dimension(corner); } else if (bottom != null && lastRow) { size = new Dimension(bottom); } else if (right != null && lastCol) { size = new Dimension(right); } else { size = new Dimension(base); } // Compute values int pageXMin = col * base.width - col * overlap; int pageYMin = row * base.height - row * overlap; int firstTileX = pageXMin / (tileSize * tileImageScale) + xMin; int firstTileY = pageYMin / (tileSize * tileImageScale) + yMin; int firstTileXOffset = pageXMin % (tileSize * tileImageScale); int firstTileYOffset = pageYMin % (tileSize * tileImageScale); int tilesInCol = (size.height + firstTileYOffset - 1) / (tileSize * tileImageScale) + 1; int tilesInRow = (size.width + firstTileXOffset - 1) / (tileSize * tileImageScale) + 1; // Create image and graphics int imageWidth = size.width + insets.left + insets.right; int imageHeight = size.height + insets.top + insets.bottom; BufferedImage image = Utilities.safeCreateBufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_4BYTE_ABGR); Graphics2D g = image.createGraphics(); g.translate(insets.left, insets.top); g.clipRect(0, 0, size.width, size.height); // Paint image g.setBackground(IMAGE_BACKGROUND); g.clearRect(0, 0, size.width, size.height); g.translate(-firstTileXOffset, -firstTileYOffset); for (int tileRow = 0; tileRow < tilesInCol; tileRow++) { for (int tileCol = 0; tileCol < tilesInRow; tileCol++) { int tileX = firstTileX + tileCol; int tileY = firstTileY + tileRow; int x = tileCol * tileSize * tileImageScale; int y = tileRow * tileSize * tileImageScale; BufferedImage tile = mapDlTileProvider.getTileImage(tileX, tileY); if (tile != null) g.drawImage(tile, x, y, tileSize * tileImageScale, tileSize * tileImageScale, null); } } g.translate(firstTileXOffset, firstTileYOffset); // Paint additions dummy.setSize(size); Point tlc = new Point(firstTileX * tileSize * tileImageScale + firstTileXOffset, firstTileY * tileSize * tileImageScale + firstTileYOffset); if (s.wgsEnabled) wgsGrid.paintWgsGrid(g, mapSource.getMapSpace(), tlc, zoom); if (s.scaleBar) ScaleBar.paintScaleBar(dummy, g, mapSource.getMapSpace(), tlc, zoom); if (s.compass) { Image compassRaw = ImageIO.read(Utilities.loadResourceAsStream("images/compass.png")); Image compass = compassRaw.getScaledInstance(150, 150, Image.SCALE_SMOOTH); g.drawImage(compass, 0, 0, null); } if (s.pageNumbers) { g.setBackground(LABEL_BACKGROUND); g.setColor(LABEL_FOREGROUND); String pageNumber = " " + getPageNumber(row, col, ROWS, COLS) + " "; g.setFont(PAGE_NUMBER_FONT); FontMetrics fontMetrics = g.getFontMetrics(); int fontHeight = fontMetrics.getHeight(); int pageNumberStringWidth = fontMetrics.stringWidth(pageNumber); g.clearRect(0, 0, pageNumberStringWidth, fontHeight); g.drawString(pageNumber, 0, fontHeight - fontMetrics.getDescent()); int centerX = size.width / 2; g.setFont(LABEL_FONT); fontMetrics = g.getFontMetrics(); fontHeight = fontMetrics.getHeight(); if (!firstRow) { String text = UP + getPageNumber(row - 1, col, ROWS, COLS) + " "; int stringWidth = fontMetrics.stringWidth(text); g.clearRect(centerX - stringWidth / 2, 8, stringWidth, fontHeight); g.drawString(text, centerX - stringWidth / 2, 8 + fontHeight - fontMetrics.getDescent()); } if (!lastRow) { String text = DOWN + getPageNumber(row + 1, col, ROWS, COLS) + " "; int stringWidth = fontMetrics.stringWidth(text); g.clearRect(centerX - stringWidth / 2, size.height - 32 - fontHeight, stringWidth, fontHeight); g.drawString(text, centerX - stringWidth / 2, size.height - 32 - fontMetrics.getDescent()); } } g.dispose(); // Process image atlasProgress.incMapCreationProgress(); checkUserAbort(); processPage(image, getPageNumber(row, col, ROWS, COLS)); atlasProgress.incMapCreationProgress(); checkUserAbort(); } } } catch (IOException e) { throw new MapCreationException(map, e); } } private int getPageNumber(int row, int col, int ROWS, int COLS) { return row * COLS + col + 1; } @Override public boolean testMapSource(MapSource mapSource) { MapSpace mapSpace = mapSource.getMapSpace(); ProjectionCategory projection = mapSpace.getProjectionCategory(); return (mapSpace instanceof MercatorPower2MapSpace) && (ProjectionCategory.SPHERE.equals(projection) || ProjectionCategory.ELLIPSOID.equals(projection)); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/AlpineQuestMap.java0000644000175000017500000003357112127544344032331 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Insets; import java.awt.RenderingHints; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.StringWriter; import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.Date; import javax.imageio.ImageIO; import mobac.exceptions.MapCreationException; import mobac.mapsources.mapspace.MercatorPower2MapSpace; import mobac.program.ProgramInfo; import mobac.program.annotations.AtlasCreatorName; import mobac.program.annotations.SupportedParameters; import mobac.program.atlascreators.impl.aqm.FlatPackCreator; import mobac.program.atlascreators.tileprovider.ConvertedRawTileProvider; import mobac.program.atlascreators.tileprovider.TileProvider; import mobac.program.interfaces.LayerInterface; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSpace; import mobac.program.interfaces.MapSpace.ProjectionCategory; import mobac.program.interfaces.TileImageDataWriter; import mobac.program.model.TileImageParameters.Name; import mobac.utilities.I18nUtils; import mobac.utilities.Utilities; import mobac.utilities.stream.ArrayOutputStream; /** * Creates maps using the AlpineQuestMap atlas format (AQM v2 complient). * * AQM format pack tiles in a unique file using the FlatPack format. Supports multi-layers, tile resizing. * * @author Camille */ @AtlasCreatorName("AlpineQuestMap (AQM)") @SupportedParameters(names = { Name.format, Name.height, Name.width }) public class AlpineQuestMap extends AtlasCreator { public static final String AQM_VERSION = "2"; public static final String AQM_HEADER = "V" + AQM_VERSION + "HEADER"; public static final String AQM_LEVEL = "V" + AQM_VERSION + "LEVEL"; public static final String AQM_LEVEL_DELIMITER = "@LEVEL"; public static final String AQM_END_DELIMITER = "#END"; private static final String[] SCALES = new String[] { "1:512 000 000", // 00 "1:256 000 000", // 01 "1:128 000 000", // 02 "1:64 000 000", // 03 "1:32 000 000", // 04 "1:16 000 000", // 05 "1:8 000 000", // 06 "1:4 000 000", // 07 "1:2 000 000", // 08 "1:1 000 000", // 09 "1:512 000", // 10 "1:256 000", // 11 "1:128 000", // 12 "1:64 000", // 13 "1:32 000", // 14 "1:16 000", // 15 "1:8 000", // 16 "1:4 000", // 17 "1:2 000", // 18 "1:1 000", // 19 "1:512", // 20 "1:128", // 21 "1:64", // 22 "1:32", // 23 "1:16", // 24 "1:8", // 25 "1:4", // 26 "1:2", // 27 "1:1" // 28 }; private FlatPackCreator packCreator = null; private File filePack = null; private double xResizeRatio = 1.0; private double yResizeRatio = 1.0; private int lastZoomLevel = 0; @Override public void initLayerCreation(final LayerInterface layer) throws IOException { super.initLayerCreation(layer); if (layer.getMapCount() > 0) { // create the file this.filePack = new File(atlasDir + "/" + layer.getName() + ".AQM"); this.packCreator = new FlatPackCreator(filePack); this.lastZoomLevel = -1; // add map header this.addMapHeader(layer.getMap(0).getMapSource().toString(), layer.getName()); // add level headers for (int i = 0; i < layer.getMapCount(); i++) { // needed to merge splitted maps due to map size (map split not needed by AQM format) Insets bounds = new Insets(layer.getMap(i).getMinTileCoordinate().y, layer.getMap(i) .getMinTileCoordinate().x, layer.getMap(i).getMaxTileCoordinate().y, layer.getMap(i) .getMaxTileCoordinate().x); // loops over all maps with the same level and add the bounds while (((i + 1) < layer.getMapCount()) && (layer.getMap(i).getZoom() == layer.getMap(i + 1).getZoom())) { i++; bounds.top = Math.min(bounds.top, layer.getMap(i).getMinTileCoordinate().y); bounds.left = Math.min(bounds.left, layer.getMap(i).getMinTileCoordinate().x); bounds.bottom = Math.max(bounds.bottom, layer.getMap(i).getMaxTileCoordinate().y); bounds.right = Math.max(bounds.right, layer.getMap(i).getMaxTileCoordinate().x); } this.addLevelHeader(layer.getMap(i), bounds); } } } @Override public void finishLayerCreation() throws IOException { // add end of file delimiter packCreator.add(new byte[0], AQM_END_DELIMITER); packCreator.close(); packCreator = null; super.finishLayerCreation(); } @Override public void abortAtlasCreation() throws IOException { if (packCreator != null) packCreator.close(); packCreator = null; if (filePack != null) Utilities.deleteFile(filePack); filePack = null; super.abortAtlasCreation(); } private final void addMapHeader(final String strID, final String strName) throws IOException { // version of the AQM format (internal use) final String strVersion = AQM_VERSION; // software used to create the map (displayed to user) final String strSoftware = ProgramInfo.getCompleteTitle(); // date of creation (displayed to user) final String strDate = new SimpleDateFormat("yyyy/MM/dd").format(new Date()); // name of the person that created the map (displayed to user) final String strCreator = ""; StringWriter w = new StringWriter(); w.write("[map]\n"); w.write("id = " + strID + "\n"); w.write("name = " + strName + "\n"); w.write("version = " + strVersion + "\n"); w.write("date = " + strDate + "\n"); w.write("creator = " + strCreator + "\n"); w.write("software = " + strSoftware + "\n"); w.write("\n"); w.flush(); w.close(); // add the metadata file into map packCreator.add(w.getBuffer().toString().getBytes(), AQM_HEADER); } private final void addLevelHeader(final MapInterface map, final Insets bounds) throws IOException { final int tileSize = map.getMapSource().getMapSpace().getTileSize(); final int xMin = bounds.left / tileSize; final int xMax = bounds.right / tileSize; final int yMin = bounds.top / tileSize; final int yMax = bounds.bottom / tileSize; // unique identifier for a data source / zoom (internal use) final String strID = new DecimalFormat("00").format(map.getZoom()); // name of this specific map (displayed to user) String strName = map.getLayer().getName(); if (strName == null || strName.length() == 0) strName = I18nUtils.localizedStringForKey("Unnamed"); // scale of the map (displayed to user) String strScale = ""; if (map.getZoom() >= 0 && map.getZoom() < SCALES.length) strScale = SCALES[map.getZoom()]; // source of the map data (displayed to user) final String strDataSource = map.getMapSource().toString(); // copyright of map data (displayed to user) final String strCopyright = map.getMapSource().toString(); // projection of tiles (internal use) final String strProjection = "mercator"; String strGeoid = ""; if (ProjectionCategory.SPHERE.equals(map.getMapSource().getMapSpace().getProjectionCategory())) strGeoid = "sphere"; else if (ProjectionCategory.ELLIPSOID.equals(map.getMapSource().getMapSpace().getProjectionCategory())) strGeoid = "wgs84"; // number of tiles (internal use) final long nbTotalTiles = (256 * Math.round(Math.pow(2, map.getZoom()))) / tileSize; // check resize or resample parameters String strImageFormat = null; Dimension tilesSize = null; if (map.getParameters() != null) { strImageFormat = map.getParameters().getFormat().getFileExt(); tilesSize = map.getParameters().getDimension(); } else { strImageFormat = map.getMapSource().getTileImageType().getFileExt(); tilesSize = map.getTileSize(); } if (strImageFormat != null) strImageFormat = strImageFormat.toUpperCase(); // write metadata StringWriter w = new StringWriter(); w.write("[level]\n"); w.write("id = " + strID + "\n"); w.write("name = " + strName + "\n"); w.write("scale = " + strScale + "\n"); w.write("datasource = " + strDataSource + "\n"); w.write("copyright = " + strCopyright + "\n"); w.write("projection = " + strProjection + "\n"); w.write("geoid = " + strGeoid + "\n"); w.write("xtsize = " + (int) tilesSize.getWidth() + "\n"); w.write("ytsize = " + (int) tilesSize.getHeight() + "\n"); w.write("xtratio = " + (nbTotalTiles / 360.0) + "\n"); w.write("ytratio = " + (nbTotalTiles / 360.0) + "\n"); w.write("xtoffset = " + (nbTotalTiles / 2.0) + "\n"); w.write("ytoffset = " + (nbTotalTiles / 2.0) + "\n"); w.write("xtmin = " + xMin + "\n"); w.write("xtmax = " + xMax + "\n"); w.write("ytmin = " + (nbTotalTiles - yMax) + "\n"); w.write("ytmax = " + (nbTotalTiles - yMin) + "\n"); w.write("background = " + "#FFFFFF" + "\n"); w.write("imgformat = " + strImageFormat + "\n"); w.write("\n"); w.flush(); w.close(); // add the metadata file into map packCreator.add(w.getBuffer().toString().getBytes(), AQM_LEVEL); } @Override public boolean testMapSource(final MapSource mapSource) { MapSpace mapSpace = mapSource.getMapSpace(); return (mapSpace instanceof MercatorPower2MapSpace) && (ProjectionCategory.SPHERE.equals(mapSource.getMapSpace().getProjectionCategory()) || ProjectionCategory.ELLIPSOID .equals(mapSource.getMapSpace().getProjectionCategory())); } @Override public void initializeMap(final MapInterface map, final TileProvider mapTileProvider) { super.initializeMap(map, mapTileProvider); xResizeRatio = 1.0; yResizeRatio = 1.0; if (parameters != null) { int mapTileSize = map.getMapSource().getMapSpace().getTileSize(); if ((parameters.getWidth() != mapTileSize) || (parameters.getHeight() != mapTileSize)) { // handle image re-sampling + image re-sizing xResizeRatio = (double) parameters.getWidth() / (double) mapTileSize; yResizeRatio = (double) parameters.getHeight() / (double) mapTileSize; } else { // handle only image re-sampling mapDlTileProvider = new ConvertedRawTileProvider(mapDlTileProvider, parameters.getFormat()); } } } @Override public void createMap() throws MapCreationException, InterruptedException { try { if (map.getZoom() > lastZoomLevel) { // metadata information at the beginning this.addLevelDelimiter(); this.lastZoomLevel = map.getZoom(); } // add tiles this.addLevelTiles(); } catch (InterruptedException e) { throw e; } catch (Exception e) { throw new MapCreationException(map, e); } } private final void addLevelDelimiter() throws IOException { // add empty level delimiter file packCreator.add(new byte[0], AQM_LEVEL_DELIMITER); } private final void addLevelTiles() throws InterruptedException, MapCreationException { atlasProgress.initMapCreation((xMax - xMin + 1) * (yMax - yMin + 1)); // number of tiles for this zoom level final long nbTotalTiles = (256 * Math.round(Math.pow(2, map.getZoom()))) / tileSize; // tile resizing BufferedImage tileImage = null; Graphics2D graphics = null; ArrayOutputStream buffer = null; TileImageDataWriter writer = null; if ((parameters != null) || (xResizeRatio != 1.0) || (yResizeRatio != 1.0)) { // resize image tileImage = new BufferedImage(parameters.getWidth(), parameters.getHeight(), BufferedImage.TYPE_3BYTE_BGR); // associated graphics with affine transform graphics = tileImage.createGraphics(); graphics.setTransform(AffineTransform.getScaleInstance(xResizeRatio, yResizeRatio)); graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); // image compression writer writer = parameters.getFormat().getDataWriter(); // buffer to store compressed image buffer = new ArrayOutputStream(3 * parameters.getWidth() * parameters.getHeight()); ImageIO.setUseCache(false); writer.initialize(); } for (int x = xMin; x <= xMax; x++) { for (int y = yMin; y <= yMax; y++) { checkUserAbort(); atlasProgress.incMapCreationProgress(); try { // retrieve the tile data (already re-sampled if needed) byte[] sourceTileData = mapDlTileProvider.getTileData(x, y); if (sourceTileData != null) { // there is some data if ((graphics != null) && (buffer != null) && (writer != null)) { // need to resize the tile final BufferedImage tile = ImageIO.read(new ByteArrayInputStream(sourceTileData)); graphics.drawImage(tile, 0, 0, null); buffer.reset(); writer.processImage(tileImage, buffer); sourceTileData = buffer.toByteArray(); if (sourceTileData == null) throw new MapCreationException("Image resizing failed.", map); } packCreator.add(sourceTileData, "" + x + "_" + (nbTotalTiles - y)); // y tiles count began by // bottom in AQM } } catch (IOException e) { throw new MapCreationException("Error writing tile image: " + e.getMessage(), map, e); } } } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/TwoNavRMAP.java0000644000175000017500000004753312174511554031341 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ /* * add to mobac.program.model.AtlasOutputFormat.java * * import mobac.program.atlascreators.TwoNavRmap; * TwoNavRMAP("TwoNav (RMAP)", TwoNavRmap.class), // * */ package mobac.program.atlascreators; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import java.awt.image.AffineTransformOp; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; import java.text.DecimalFormat; import java.text.NumberFormat; import java.util.Locale; import javax.imageio.ImageIO; import mobac.exceptions.AtlasTestException; import mobac.exceptions.MapCreationException; import mobac.mapsources.mapspace.MercatorPower2MapSpace; import mobac.program.annotations.AtlasCreatorName; import mobac.program.annotations.SupportedParameters; import mobac.program.atlascreators.tileprovider.ConvertedRawTileProvider; import mobac.program.interfaces.LayerInterface; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSpace; import mobac.program.interfaces.MapSpace.ProjectionCategory; import mobac.program.interfaces.TileImageDataWriter; import mobac.program.model.TileImageFormat; import mobac.program.model.TileImageParameters.Name; import mobac.program.model.TileImageType; import mobac.program.tiledatawriter.TileImageJpegDataWriter; import mobac.utilities.Utilities; import org.apache.log4j.Level; /** * * Creates one RMAP file per layer. * * @author Luka Logar * @author r_x * */ @AtlasCreatorName(value = "TwoNav (RMAP)") @SupportedParameters(names = { Name.format }) public class TwoNavRMAP extends AtlasCreator { private RmapFile rmapFile = null; private class ZoomLevel { private int index = 0; private long offset = 0; private int width = 0; private int height = 0; private int xTiles = 0; private int yTiles = 0; private long jpegOffsets[][] = null; private int zoom = 0; private boolean dl = false; private void writeHeader() throws IOException { if (offset == 0) { offset = rmapFile.getFilePointer(); } else { rmapFile.seek(offset); } log.trace(String.format("Writing ZoomLevel %d (%dx%d pixels, %dx%d tiles) header at offset %d", index, width, height, xTiles, yTiles, offset)); rmapFile.writeIntI(width); rmapFile.writeIntI(-height); rmapFile.writeIntI(xTiles); rmapFile.writeIntI(yTiles); if (jpegOffsets == null) { jpegOffsets = new long[xTiles][yTiles]; } for (int y = 0; y < yTiles; y++) { for (int x = 0; x < xTiles; x++) { rmapFile.writeLongI(jpegOffsets[x][y]); } } } private BufferedImage loadJpegAtOffset(long offset) throws IOException { if (offset == 0) { throw new IOException("offset == 0"); } rmapFile.seek(offset); int TagId = rmapFile.readIntI(); if (TagId != 7) { throw new IOException("TagId != 7"); } int TagLen = rmapFile.readIntI(); byte[] jpegImageBuf = new byte[TagLen]; rmapFile.readFully(jpegImageBuf); ByteArrayInputStream input = new ByteArrayInputStream(jpegImageBuf); return ImageIO.read(input); } private byte[] getTileData(TileImageDataWriter writer, ZoomLevel source, int x, int y) throws IOException { log.trace(String.format("Shrinking jpegs (%d,%d,%d - %d,%d,%d)", source.index, x, y, source.index, (x + 1 < source.xTiles) ? x + 1 : x, (y + 1 < source.yTiles) ? y + 1 : y)); BufferedImage bi11 = loadJpegAtOffset(source.jpegOffsets[x][y]); BufferedImage bi21 = (x + 1 < source.xTiles) ? loadJpegAtOffset(source.jpegOffsets[x + 1][y]) : null; BufferedImage bi12 = (y + 1 < source.yTiles) ? loadJpegAtOffset(source.jpegOffsets[x][y + 1]) : null; BufferedImage bi22 = (x + 1 < source.xTiles) && (y + 1 < source.yTiles) ? loadJpegAtOffset(source.jpegOffsets[x + 1][y + 1]) : null; int biWidth = bi11.getWidth() + (bi21 != null ? bi21.getWidth() : 0); int biHeight = bi11.getHeight() + (bi12 != null ? bi12.getHeight() : 0); BufferedImage bi = new BufferedImage(biWidth, biHeight, BufferedImage.TYPE_3BYTE_BGR); Graphics2D g = bi.createGraphics(); g.drawImage(bi11, 0, 0, null); if (bi21 != null) { g.drawImage(bi21, bi11.getWidth(), 0, null); } if (bi12 != null) { g.drawImage(bi12, 0, bi11.getHeight(), null); } if (bi22 != null) { g.drawImage(bi22, bi11.getWidth(), bi11.getHeight(), null); } AffineTransformOp op = new AffineTransformOp(new AffineTransform(0.5, 0, 0, 0.5, 0, 0), AffineTransformOp.TYPE_BILINEAR); BufferedImage biOut = new BufferedImage(biWidth / 2, biHeight / 2, BufferedImage.TYPE_3BYTE_BGR); op.filter(bi, biOut); ByteArrayOutputStream buffer = new ByteArrayOutputStream(biOut.getWidth() * biOut.getHeight() * 4); writer.processImage(biOut, buffer); g.dispose(); return buffer.toByteArray(); } private void shrinkFrom(ZoomLevel source) { try { TileImageDataWriter writer = new TileImageJpegDataWriter(0.9); writer.initialize(); writeHeader(); atlasProgress.initMapCreation(xTiles * yTiles); for (int x = 0; x < xTiles; x++) { for (int y = 0; y < yTiles; y++) { checkUserAbort(); atlasProgress.incMapCreationProgress(); jpegOffsets[x][y] = rmapFile.getFilePointer(); byte[] tileData = getTileData(writer, source, 2 * x, 2 * y); rmapFile.seek(jpegOffsets[x][y]); log.trace(String.format("Writing shrunken jpeg (%d,%d,%d) at offset %d", index, x, y, jpegOffsets[x][y])); rmapFile.writeIntI(7); rmapFile.writeIntI(tileData.length); rmapFile.write(tileData); tileData = null; } } } catch (Exception e) { log.error("Failed generating ZoomLevel " + index + ": " + e.getMessage()); } } } private class RmapFile extends RandomAccessFile { private String name = ""; private int width = 0; private int height = 0; private int tileWidth = 0; private int tileHeight = 0; private double longitudeMin = 0; private double longitudeMax = 0; private double latitudeMin = 0; private double latitudeMax = 0; private long mapDataOffset = 0; private ZoomLevel zoomLevels[] = null; private RmapFile(File file) throws FileNotFoundException { super(file, "rw"); this.name = file.getName(); } private int readIntI() throws IOException { int ch1 = this.read(); int ch2 = this.read(); int ch3 = this.read(); int ch4 = this.read(); if ((ch1 | ch2 | ch3 | ch4) < 0) { throw new IOException(); } return ((ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0)); } private void writeIntI(int i) throws IOException { write((i >>> 0) & 0xFF); write((i >>> 8) & 0xFF); write((i >>> 16) & 0xFF); write((i >>> 24) & 0xFF); } private void writeLongI(long l) throws IOException { write((int) (l >>> 0) & 0xFF); write((int) (l >>> 8) & 0xFF); write((int) (l >>> 16) & 0xFF); write((int) (l >>> 24) & 0xFF); write((int) (l >>> 32) & 0xFF); write((int) (l >>> 40) & 0xFF); write((int) (l >>> 48) & 0xFF); write((int) (l >>> 56) & 0xFF); } private void writeHeader() throws IOException { log.trace("Writing rmap header"); if (zoomLevels == null) { throw new IOException("zoomLevels == null"); } seek(0); write("CompeGPSRasterImage".getBytes()); writeIntI(10); writeIntI(7); writeIntI(0); writeIntI(width); writeIntI(-height); writeIntI(24); writeIntI(1); writeIntI(tileWidth); writeIntI(tileHeight); writeLongI(mapDataOffset); writeIntI(0); writeIntI(zoomLevels.length); for (int n = 0; n < zoomLevels.length; n++) { writeLongI(zoomLevels[n].offset); } } private void writeMapInfo() throws IOException { if (mapDataOffset == 0) { mapDataOffset = getFilePointer(); } else { seek(mapDataOffset); } log.trace("Writing MAP data at offset %d" + mapDataOffset); StringBuffer sbMap = new StringBuffer(); sbMap.append("CompeGPS MAP File\r\n"); sbMap.append("
\r\n"); sbMap.append("Version=2\r\n"); sbMap.append("VerCompeGPS=MOBAC\r\n"); sbMap.append("Projection=2,Mercator,\r\n"); sbMap.append("Coordinates=1\r\n"); sbMap.append("Datum=WGS 84\r\n"); sbMap.append("
\r\n"); sbMap.append("\r\n"); sbMap.append("Bitmap=" + name + "\r\n"); sbMap.append("BitsPerPixel=0\r\n"); sbMap.append(String.format("BitmapWidth=%d\r\n", width)); sbMap.append(String.format("BitmapHeight=%d\r\n", height)); sbMap.append("Type=10\r\n"); sbMap.append("\r\n"); sbMap.append("\r\n"); String pointLine = "P%d=%d,%d,A,%s,%s\r\n"; DecimalFormat df = (DecimalFormat) NumberFormat.getNumberInstance(Locale.US); df.applyPattern("#0.00000000"); sbMap.append(String.format(pointLine, 0, 0, 0, df.format(longitudeMin), df.format(latitudeMax))); sbMap.append(String.format(pointLine, 1, width - 1, 0, df.format(longitudeMax), df.format(latitudeMax))); sbMap.append(String.format(pointLine, 2, width - 1, height - 1, df.format(longitudeMax), df.format(latitudeMin))); sbMap.append(String.format(pointLine, 3, 0, height - 1, df.format(longitudeMin), df.format(latitudeMin))); sbMap.append("\r\n"); sbMap.append("\r\n"); String polyLine = "M%d=%d,%d\r\n"; sbMap.append(String.format(polyLine, 0, 0, 0)); sbMap.append(String.format(polyLine, 1, width, 0)); sbMap.append(String.format(polyLine, 2, width, height)); sbMap.append(String.format(polyLine, 3, 0, height)); sbMap.append("\r\n"); writeIntI(1); writeIntI(sbMap.length()); write(sbMap.toString().getBytes()); } } // ************************************************************ public TwoNavRMAP() { super(); log.setLevel(Level.TRACE); } @Override protected void testAtlas() throws AtlasTestException { for (LayerInterface layer : atlas) { MapInterface map0 = layer.getMap(0); MapSpace mapSpace0 = map0.getMapSource().getMapSpace(); double longitudeMin = mapSpace0.cXToLon(map0.getMinTileCoordinate().x, map0.getZoom()); double longitudeMax = mapSpace0.cXToLon(map0.getMaxTileCoordinate().x + 1, map0.getZoom()); double latitudeMin = mapSpace0.cYToLat(map0.getMaxTileCoordinate().y + 1, map0.getZoom()); double latitudeMax = mapSpace0.cYToLat(map0.getMinTileCoordinate().y, map0.getZoom()); for (int n = 1; n < layer.getMapCount(); n++) { MapInterface mapN = layer.getMap(n); MapSpace mapSpaceN = mapN.getMapSource().getMapSpace(); double longitudeMinN = mapSpaceN.cXToLon(mapN.getMinTileCoordinate().x, mapN.getZoom()); double longitudeMaxN = mapSpaceN.cXToLon(mapN.getMaxTileCoordinate().x + 1, mapN.getZoom()); double latitudeMinN = mapSpaceN.cYToLat(mapN.getMaxTileCoordinate().y + 1, mapN.getZoom()); double latitudeMaxN = mapSpaceN.cYToLat(mapN.getMinTileCoordinate().y, mapN.getZoom()); if ((longitudeMin != longitudeMinN) || (longitudeMax != longitudeMaxN) || (latitudeMin != latitudeMinN) || (latitudeMax != latitudeMaxN)) { throw new AtlasTestException("All maps in one layer have to cover the same area!\n" + "Use grid zoom on the lowest zoom level to get an acceptable result."); } for (int m = 0; m < layer.getMapCount(); m++) { if ((mapN.getZoom() == layer.getMap(m).getZoom()) && (m != n)) { throw new AtlasTestException("Several maps with the same zoom level within the same layer " + "are not supported!"); } } } } } public boolean testMapSource(MapSource mapSource) { MapSpace mapSpace = mapSource.getMapSpace(); return (mapSpace instanceof MercatorPower2MapSpace && ProjectionCategory.SPHERE.equals(mapSpace .getProjectionCategory())); } @Override public void initLayerCreation(LayerInterface layer) throws IOException { if (rmapFile != null) throw new RuntimeException("Layer mismatch - last layer has not been finished correctly!"); super.initLayerCreation(layer); // Logging.configureConsoleLogging(org.apache.log4j.Level.ALL, new SimpleLayout()); rmapFile = new RmapFile(new File(atlasDir, layer.getName() + ".rmap")); int DefaultMap = 0; rmapFile.width = 0; rmapFile.height = 0; for (int n = 0; n < layer.getMapCount(); n++) { int width = layer.getMap(n).getMaxTileCoordinate().x - layer.getMap(n).getMinTileCoordinate().x + 1; int height = layer.getMap(n).getMaxTileCoordinate().y - layer.getMap(n).getMinTileCoordinate().y + 1; if ((width > rmapFile.width) || (height > rmapFile.height)) { rmapFile.width = width; rmapFile.height = height; DefaultMap = n; } } log.trace("rmap width = " + rmapFile.width); log.trace("rmap height = " + rmapFile.height); rmapFile.tileWidth = layer.getMap(DefaultMap).getTileSize().width; rmapFile.tileHeight = layer.getMap(DefaultMap).getTileSize().height; log.trace("rmap tileWidth = " + rmapFile.tileWidth); log.trace("rmap tileHeight = " + rmapFile.tileHeight); MapSpace mapSpace = layer.getMap(DefaultMap).getMapSource().getMapSpace(); rmapFile.longitudeMin = mapSpace.cXToLon(layer.getMap(DefaultMap).getMinTileCoordinate().x, layer.getMap(DefaultMap).getZoom()); rmapFile.longitudeMax = mapSpace.cXToLon(layer.getMap(DefaultMap).getMaxTileCoordinate().x, layer.getMap(DefaultMap).getZoom()); rmapFile.latitudeMin = mapSpace.cYToLat(layer.getMap(DefaultMap).getMaxTileCoordinate().y, layer.getMap(DefaultMap).getZoom()); rmapFile.latitudeMax = mapSpace.cYToLat(layer.getMap(DefaultMap).getMinTileCoordinate().y, layer.getMap(DefaultMap).getZoom()); log.trace("rmap longitudeMin = " + rmapFile.longitudeMin); log.trace("rmap longitudeMax = " + rmapFile.longitudeMax); log.trace("rmap latitudeMin = " + rmapFile.latitudeMin); log.trace("rmap latitudeMax = " + rmapFile.latitudeMax); double width = rmapFile.width; double height = rmapFile.height; int count = 1; while ((width >= 256.0) || (height >= 256.0)) { width = Math.ceil(width / 2.0); height = Math.ceil(height / 2.0); count++; } log.trace("rmap zoomLevels count = " + count); rmapFile.zoomLevels = new ZoomLevel[count]; width = rmapFile.width; height = rmapFile.height; for (int n = 0; n < rmapFile.zoomLevels.length; n++) { rmapFile.zoomLevels[n] = new ZoomLevel(); rmapFile.zoomLevels[n].index = n; rmapFile.zoomLevels[n].width = (int) Math.round(width); rmapFile.zoomLevels[n].height = (int) Math.round(height); rmapFile.zoomLevels[n].xTiles = (int) Math.ceil((double) rmapFile.zoomLevels[n].width / (double) rmapFile.tileWidth); rmapFile.zoomLevels[n].yTiles = (int) Math.ceil((double) rmapFile.zoomLevels[n].height / (double) rmapFile.tileHeight); rmapFile.zoomLevels[n].jpegOffsets = new long[rmapFile.zoomLevels[n].xTiles][rmapFile.zoomLevels[n].yTiles]; rmapFile.zoomLevels[n].zoom = layer.getMap(DefaultMap).getZoom() - n; rmapFile.zoomLevels[n].dl = false; for (int m = 0; m < layer.getMapCount(); m++) { if ((rmapFile.zoomLevels[n].zoom == layer.getMap(m).getZoom())) { rmapFile.zoomLevels[n].dl = true; } } width = Math.ceil(width / 2.0); height = Math.ceil(height / 2.0); } for (int n = 0; n < rmapFile.zoomLevels.length; n++) { log.trace(String.format("zoomLevels[%d] zoom=%d %dx%d pixels, %dx%d tiles %s", rmapFile.zoomLevels[n].index, rmapFile.zoomLevels[n].zoom, rmapFile.zoomLevels[n].width, rmapFile.zoomLevels[n].height, rmapFile.zoomLevels[n].xTiles, rmapFile.zoomLevels[n].yTiles, rmapFile.zoomLevels[n].dl == false ? "calc" : "dl")); } rmapFile.writeHeader(); } public void createMap() throws MapCreationException, InterruptedException { try { int index; for (index = 0; index < rmapFile.zoomLevels.length; index++) { if (rmapFile.zoomLevels[index].zoom == map.getZoom()) { break; } } if (index == rmapFile.zoomLevels.length) { throw new MapCreationException("Map not found in the zoomLevels list", map); } try { rmapFile.zoomLevels[index].writeHeader(); } catch (IOException e) { throw new MapCreationException("rmapFile.zoomLevels[Index].writeHeader() failed: " + e.getMessage(), map, e); } int tilex = 0; int tiley = 0; atlasProgress.initMapCreation((xMax - xMin + 1) * (yMax - yMin + 1)); if ((map.getMapSource().getTileImageType() != TileImageType.JPG) || (map.getParameters() != null)) { // Tiles have to be converted to jpeg format TileImageFormat imageFormat = TileImageFormat.JPEG90; if (map.getParameters() != null) imageFormat = map.getParameters().getFormat(); mapDlTileProvider = new ConvertedRawTileProvider(mapDlTileProvider, imageFormat); } ImageIO.setUseCache(false); byte[] emptyTileData = Utilities.createEmptyTileData(mapSource); for (int x = xMin; x <= xMax; x++) { tiley = 0; for (int y = yMin; y <= yMax; y++) { checkUserAbort(); atlasProgress.incMapCreationProgress(); try { // Remember offset to tile rmapFile.zoomLevels[index].jpegOffsets[tilex][tiley] = rmapFile.getFilePointer(); byte[] sourceTileData = mapDlTileProvider.getTileData(x, y); if (sourceTileData != null) { rmapFile.writeIntI(7); rmapFile.writeIntI(sourceTileData.length); rmapFile.write(sourceTileData); } else { log.trace(String.format("Tile x=%d y=%d not found in tile archive - creating default", tilex, tiley)); rmapFile.writeIntI(7); rmapFile.writeIntI(emptyTileData.length); rmapFile.write(emptyTileData); } } catch (IOException e) { throw new MapCreationException("Error writing tile image: " + e.getMessage(), map, e); } tiley++; } tilex++; } } catch (MapCreationException e) { throw e; } catch (Exception e) { throw new MapCreationException(map, e); } } @Override public void abortAtlasCreation() throws IOException { try { rmapFile.setLength(0); } finally { Utilities.closeFile(rmapFile); } super.abortAtlasCreation(); } @Override public void finishLayerCreation() throws IOException { try { for (int n = 0; n < rmapFile.zoomLevels.length; n++) { if (rmapFile.zoomLevels[n].offset == 0) { if (n == 0) { throw new IOException("Missing top level map"); } rmapFile.zoomLevels[n].shrinkFrom(rmapFile.zoomLevels[n - 1]); } } rmapFile.writeMapInfo(); rmapFile.writeHeader(); for (int n = 0; n < rmapFile.zoomLevels.length; n++) { rmapFile.zoomLevels[n].writeHeader(); } rmapFile.close(); } catch (IOException e) { log.error("Failed writing rmap file \"" + rmapFile.name + "\": " + e.getMessage(), e); abortAtlasCreation(); throw e; } rmapFile = null; super.finishLayerCreation(); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/GoogleEarthOverlay.java0000644000175000017500000002042412122526606033170 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.text.NumberFormat; import java.util.zip.ZipOutputStream; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.TransformerFactoryConfigurationError; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import mobac.exceptions.MapCreationException; import mobac.program.annotations.AtlasCreatorName; import mobac.program.atlascreators.tileprovider.TileProvider; import mobac.program.interfaces.LayerInterface; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSpace; import mobac.program.interfaces.TileImageDataWriter; import mobac.program.tiledatawriter.TileImageJpegDataWriter; import mobac.utilities.Utilities; import mobac.utilities.stream.ZipStoreOutputStream; import org.w3c.dom.Document; import org.w3c.dom.Element; @AtlasCreatorName(value = "Google Earth Overlay (KMZ)", type = "GoogleEarthRasterOverlay") public class GoogleEarthOverlay extends AbstractPlainImage { protected File mapDir; protected String cleanedMapName; protected File kmzFile = null; protected ZipStoreOutputStream kmzOutputStream = null; private Document kmlDoc = null; private Element groundOverlayRoot = null; @Override public void initLayerCreation(LayerInterface layer) throws IOException { super.initLayerCreation(layer); Utilities.mkDirs(atlasDir); kmzFile = new File(atlasDir, layer.getName() + ".kmz"); kmzOutputStream = new ZipStoreOutputStream(kmzFile); kmzOutputStream.setMethod(ZipOutputStream.STORED); try { if (layer.getMapCount() <= 1) initKmlDoc(null); else initKmlDoc(layer.getName()); } catch (ParserConfigurationException e) { throw new IOException(e); } } @Override public void finishLayerCreation() throws IOException { try { writeKmlToZip(); } catch (Exception e) { throw new IOException(e); } Utilities.closeStream(kmzOutputStream); kmzOutputStream = null; kmzFile = null; super.finishLayerCreation(); } @Override public void abortAtlasCreation() throws IOException { Utilities.closeStream(kmzOutputStream); kmzOutputStream = null; kmzFile = null; super.abortAtlasCreation(); } @Override public void initializeMap(MapInterface map, TileProvider mapTileProvider) { super.initializeMap(map, mapTileProvider); mapDir = new File(atlasDir, map.getLayer().getName()); cleanedMapName = map.getName(); cleanedMapName = cleanedMapName.replaceAll("[[^\\p{Alnum}-_]]+", "_"); cleanedMapName = cleanedMapName.replaceAll("_{2,}", "_"); if (cleanedMapName.endsWith("_")) cleanedMapName = cleanedMapName.substring(0, cleanedMapName.length() - 1); if (cleanedMapName.startsWith("_")) cleanedMapName = cleanedMapName.substring(1, cleanedMapName.length()); } protected int getBufferedImageType() { return BufferedImage.TYPE_3BYTE_BGR; } protected void writeTileImage(BufferedImage tileImage) throws MapCreationException { TileImageDataWriter writer; if (parameters != null) { writer = parameters.getFormat().getDataWriter(); } else writer = new TileImageJpegDataWriter(0.9); writer.initialize(); try { int initialBufferSize = tileImage.getWidth() * tileImage.getHeight() / 4; ByteArrayOutputStream buf = new ByteArrayOutputStream(initialBufferSize); writer.processImage(tileImage, buf); String imageFileName = "files/" + cleanedMapName + "." + writer.getType(); kmzOutputStream.writeStoredEntry(imageFileName, buf.toByteArray()); addMapToKmz(imageFileName); } catch (Exception e) { throw new MapCreationException(map, e); } } protected void addMapToKmz(String imageFileName) throws ParserConfigurationException, TransformerFactoryConfigurationError, TransformerException, IOException { int startX = xMin * tileSize; int endX = (xMax + 1) * tileSize; int startY = yMin * tileSize; int endY = (yMax + 1) * tileSize; addKmlEntry(map.getName(), imageFileName, startX, startY, endX - startX, endY - startY); } private void initKmlDoc(String folderName) throws ParserConfigurationException { DocumentBuilder builder; builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); kmlDoc = builder.newDocument(); Element kml = kmlDoc.createElementNS("http://www.opengis.net/kml/2.2", "kml"); kmlDoc.appendChild(kml); groundOverlayRoot = kml; if (folderName != null) { groundOverlayRoot = kmlDoc.createElement("Folder"); kml.appendChild(groundOverlayRoot); Element name = kmlDoc.createElement("name"); name.setTextContent(folderName); Element open = kmlDoc.createElement("open"); open.setTextContent("1"); groundOverlayRoot.appendChild(name); groundOverlayRoot.appendChild(open); } } private void addKmlEntry(String imageName, String imageFileName, int startX, int startY, int width, int height) { Element go = kmlDoc.createElement("GroundOverlay"); Element name = kmlDoc.createElement("name"); Element ico = kmlDoc.createElement("Icon"); Element href = kmlDoc.createElement("href"); Element drawOrder = kmlDoc.createElement("drawOrder"); Element latLonBox = kmlDoc.createElement("LatLonBox"); Element north = kmlDoc.createElement("north"); Element south = kmlDoc.createElement("south"); Element east = kmlDoc.createElement("east"); Element west = kmlDoc.createElement("west"); Element rotation = kmlDoc.createElement("rotation"); name.setTextContent(imageName); href.setTextContent(imageFileName); drawOrder.setTextContent("0"); MapSpace mapSpace = mapSource.getMapSpace(); NumberFormat df = Utilities.FORMAT_6_DEC_ENG; String longitudeMin = df.format(mapSpace.cXToLon(startX, zoom)); String longitudeMax = df.format(mapSpace.cXToLon(startX + width, zoom)); String latitudeMin = df.format(mapSpace.cYToLat(startY + height, zoom)); String latitudeMax = df.format(mapSpace.cYToLat(startY, zoom)); north.setTextContent(latitudeMax); south.setTextContent(latitudeMin); west.setTextContent(longitudeMin); east.setTextContent(longitudeMax); rotation.setTextContent("0.0"); groundOverlayRoot.appendChild(go); go.appendChild(name); go.appendChild(ico); go.appendChild(latLonBox); ico.appendChild(href); ico.appendChild(drawOrder); latLonBox.appendChild(north); latLonBox.appendChild(south); latLonBox.appendChild(east); latLonBox.appendChild(west); latLonBox.appendChild(rotation); } private void writeKmlToZip() throws TransformerFactoryConfigurationError, TransformerException, IOException { Transformer serializer; serializer = TransformerFactory.newInstance().newTransformer(); serializer.setOutputProperty(OutputKeys.INDENT, "yes"); serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); ByteArrayOutputStream bos = new ByteArrayOutputStream(16000); serializer.transform(new DOMSource(kmlDoc), new StreamResult(bos)); kmzOutputStream.writeStoredEntry("doc.kml", bos.toByteArray()); kmlDoc = null; groundOverlayRoot = null; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/SportsTracker.java0000644000175000017500000001157612122526606032244 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import javax.imageio.ImageIO; import mobac.exceptions.MapCreationException; import mobac.mapsources.mapspace.MercatorPower2MapSpace; import mobac.program.annotations.AtlasCreatorName; import mobac.program.annotations.SupportedParameters; import mobac.program.atlascreators.impl.MapTileWriter; import mobac.program.atlascreators.tileprovider.ConvertedRawTileProvider; import mobac.program.atlascreators.tileprovider.TileProvider; import mobac.program.interfaces.LayerInterface; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSource; import mobac.program.model.TileImageParameters; import mobac.program.model.TileImageParameters.Name; import mobac.utilities.Utilities; /** * [Nokia] Sports Tracker * * */ @AtlasCreatorName(value = "Sports Tracker", type = "NST") @SupportedParameters(names = { Name.format }) public class SportsTracker extends AtlasCreator { protected File mapDir = null; protected MapTileWriter mapTileWriter = null; protected String tileType = null; @Override public boolean testMapSource(MapSource mapSource) { return MercatorPower2MapSpace.INSTANCE_256.equals(mapSource.getMapSpace()); } @Override public void initLayerCreation(LayerInterface layer) throws IOException { super.initLayerCreation(layer); mapDir = new File(atlasDir, layer.getName()); } @Override public void initializeMap(MapInterface map, TileProvider mapTileProvider) { super.initializeMap(map, mapTileProvider); tileType = map.getMapSource().getTileImageType().getFileExt(); TileImageParameters param = map.getParameters(); if (param != null) { mapDlTileProvider = new ConvertedRawTileProvider(mapDlTileProvider, param.getFormat()); tileType = param.getFormat().getFileExt(); } } public void createMap() throws MapCreationException, InterruptedException { // This means there should not be any resizing of the tiles. createTiles(); } protected void createTiles() throws InterruptedException, MapCreationException { atlasProgress.initMapCreation((xMax - xMin + 1) * (yMax - yMin + 1)); ImageIO.setUseCache(false); for (int x = xMin; x <= xMax; x++) { for (int y = yMin; y <= yMax; y++) { checkUserAbort(); atlasProgress.incMapCreationProgress(); try { byte[] sourceTileData = mapDlTileProvider.getTileData(x, y); if (sourceTileData != null) writeTile(x, y, sourceTileData); } catch (IOException e) { throw new MapCreationException("Error writing tile image: " + e.getMessage(), map, e); } } } } public void writeTile(int tilex, int tiley, byte[] tileData) throws IOException { String tileName = getTileName(zoom, tilex, tiley); int count = tileName.length(); int dirCount = count / 3; if ((count % 3 == 0) & (dirCount > 0)) dirCount--; File tileDir = mapDir; for (int i = 0; i < dirCount; i++) { int start = i * 3; String dirName = tileName.substring(start, start + 3); tileDir = new File(tileDir, dirName); } // File extension needs to be jpg (requested by telemaxx) // see https://sourceforge.net/tracker/?func=detail&atid=1105497&aid=3066161&group_id=238075 String fileName = tileName + ".jpg"; File file = new File(tileDir, fileName); writeTile(file, tileData); } protected void writeTile(File file, byte[] tileData) throws IOException { Utilities.mkDirs(file.getParentFile()); FileOutputStream out = new FileOutputStream(file); try { out.write(tileData); } finally { Utilities.closeStream(out); } } protected static final char[] NUM_CHAR = { 'q', 'r', 't', 's' }; public static String getTileName(int zoom, int tilex, int tiley) { char[] tileNum = new char[zoom + 1]; tileNum[0] = 't'; for (int i = zoom; i > 0; i--) { int num = (tilex % 2) | ((tiley % 2) << 1); tileNum[i] = NUM_CHAR[num]; tilex >>= 1; tiley >>= 1; } return new String(tileNum); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/GCLive.java0000644000175000017500000002416712122526604030545 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.util.ArrayList; import java.util.Collections; import javax.imageio.ImageIO; import mobac.exceptions.AtlasTestException; import mobac.exceptions.MapCreationException; import mobac.mapsources.mapspace.MercatorPower2MapSpace; import mobac.program.annotations.AtlasCreatorName; import mobac.program.annotations.SupportedParameters; import mobac.program.atlascreators.impl.MapTileWriter; import mobac.program.atlascreators.tileprovider.ConvertedRawTileProvider; import mobac.program.atlascreators.tileprovider.TileProvider; import mobac.program.interfaces.LayerInterface; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSource; import mobac.program.model.TileImageParameters.Name; import mobac.utilities.Utilities; /** * File format documentation * *
 * ===
 * === Reengineering of the Geocaching Live Tile Database ===
 * ===
 * 
 * index file:
 * ===========
 * 
 * 16 Bytes Header:
 * ----------------
 * 
 * 00 00 00 0A		Highest index used currently for the data files. Index is incremented starting with 0.
 * 00 00 4E 20		Max. number of tiles index. Current max. number is 20000.
 * 00 00 01 4D		Number of tile entries (16 bytes) indexed.
 * 00 01 0C FF		Size of the data file with the currently used highest index.
 * 
 * 16 Bytes per tile:
 * ------------------
 * 
 * 00 00			Inverse zoom level = 17 - Z. 
 * 01 0E 16			Number of the X tile.
 * 00 B1 0E			Number of the Y tile.
 * 00 00 50 92		Start offset of the PNG data in the data file.
 * 00 9D 6 			Size of the PNG data.
 *        0 01		Index of the data file which contains the PNG data.
 * 
 * The tiles are sorted starting by zoom level 17 (INVZ = 0).
 * 
 * data file:
 * ----------
 * 
 * Max. 32 PNGs concated directly together.
 * 
 * 
 * [0] - [x] directories:
 * ----------------------
 * 
 * Max. 32 data files per directory. The data files are named from 'data0' to 'dataN'.
 * 
*/ @AtlasCreatorName("Geocaching Live offline map") @SupportedParameters(names = { Name.format }) public class GCLive extends AtlasCreator { private static final int MAX_TILES = 65535; private MapTileWriter mapTileWriter = null; @Override public boolean testMapSource(MapSource mapSource) { return MercatorPower2MapSpace.INSTANCE_256.equals(mapSource.getMapSpace()); } @Override protected void testAtlas() throws AtlasTestException { long tileCount = 0; for (LayerInterface layer : atlas) { for (MapInterface map : layer) { // We can not use map.calculateTilesToDownload() because be need the full tile count not the sparse int tileSize_t = 256; // Everything else is not allowed int xMin_t = map.getMinTileCoordinate().x / tileSize_t; int xMax_t = map.getMaxTileCoordinate().x / tileSize_t; int yMin_t = map.getMinTileCoordinate().y / tileSize_t; int yMax_t = map.getMaxTileCoordinate().y / tileSize_t; tileCount += (xMax_t - xMin_t + 1) * (yMax_t - yMin_t + 1); } // Check for max tile count <= 65535 if (tileCount > MAX_TILES) throw new AtlasTestException("Tile count too high in layer " + layer.getName() + "\n - please select smaller/fewer areas"); } } @Override public void initLayerCreation(LayerInterface layer) throws IOException { super.initLayerCreation(layer); mapTileWriter = new GCLiveWriter(new File(atlasDir, layer.getName())); } @Override public void finishLayerCreation() throws IOException { mapTileWriter.finalizeMap(); mapTileWriter = null; super.finishLayerCreation(); } @Override public void abortAtlasCreation() throws IOException { mapTileWriter.finalizeMap(); mapTileWriter = null; super.abortAtlasCreation(); } @Override public void initializeMap(MapInterface map, TileProvider mapTileProvider) { super.initializeMap(map, mapTileProvider); if (parameters != null) { mapDlTileProvider = new ConvertedRawTileProvider(mapDlTileProvider, parameters.getFormat()); } } @Override public void createMap() throws MapCreationException, InterruptedException { createTiles(); } protected void createTiles() throws InterruptedException, MapCreationException { atlasProgress.initMapCreation((xMax - xMin + 1) * (yMax - yMin + 1)); ImageIO.setUseCache(false); //byte[] emptyTileData = Utilities.createEmptyTileData(mapSource); for (int x = xMin; x <= xMax; x++) { for (int y = yMin; y <= yMax; y++) { checkUserAbort(); atlasProgress.incMapCreationProgress(); try { byte[] sourceTileData = mapDlTileProvider.getTileData(x, y); if (sourceTileData != null) mapTileWriter.writeTile(x, y, null, sourceTileData); // else // mapTileWriter.writeTile(x, y, null, emptyTileData); } catch (IOException e) { throw new MapCreationException("Error writing tile image: " + e.getMessage(), map, e); } } } } protected class GCLiveWriter implements MapTileWriter { private File mapDir; private int dataDirCounter = 0; private int dataFileCounter = 0; private int imageCounter = 0; private RandomAccessFile currentDataFile; private ArrayList headerEntries; public GCLiveWriter(File mapDir) throws IOException { super(); this.mapDir = mapDir; Utilities.mkDir(mapDir); headerEntries = new ArrayList(MAX_TILES); prepareDataFile(); } private void prepareDataFile() throws IOException { if (currentDataFile != null) Utilities.closeFile(currentDataFile); currentDataFile = null; File dataDir = new File(mapDir, Integer.toString(dataDirCounter)); Utilities.mkDir(dataDir); File dataFile = new File(dataDir, "data" + Integer.toString(dataFileCounter)); currentDataFile = new RandomAccessFile(dataFile, "rw"); imageCounter = 0; } public void writeTile(int tilex, int tiley, String tileType, byte[] tileData) throws IOException { imageCounter++; if (imageCounter >= 32) { dataFileCounter++; if (dataFileCounter % 32 == 0) { dataDirCounter++; if (dataDirCounter >= 32) throw new RuntimeException("Maximum number of tiles exceeded"); } prepareDataFile(); } long offset = currentDataFile.getFilePointer(); currentDataFile.write(tileData); int len = tileData.length; GCHeaderEntry header = new GCHeaderEntry(zoom, tilex, tiley, dataFileCounter, (int) offset, len); headerEntries.add(header); } public void finalizeMap() throws IOException { int dataPos = (int) currentDataFile.getFilePointer(); Utilities.closeFile(currentDataFile); Collections.sort(headerEntries); RandomAccessFile indexFile; indexFile = new RandomAccessFile(new File(mapDir, "index"), "rw"); // Write index header (first 16 bytes) indexFile.seek(0); int dataFileIndex = dataDirCounter * 32 + dataFileCounter; indexFile.writeInt(dataFileIndex); // Highest index used currently for the data files. Index is incremented // starting with 0. indexFile.writeInt(headerEntries.size()); // Max. number of tiles index. Current max. number is 20000. indexFile.writeInt(headerEntries.size()); // Number of tile entries (16 bytes) indexed. indexFile.writeInt(dataPos); // Size of the data file with the currently used highest index. for (GCHeaderEntry entry : headerEntries) { entry.writeHeader(indexFile); System.out.println(entry); } headerEntries = null; Utilities.closeFile(indexFile); } } public static class GCHeaderEntry implements Comparable { public final int zoom; public final int tilex; public final int tiley; public final int dataFileIndex; public final int offset; public final int len; public GCHeaderEntry(int zoom, int tilex, int tiley, int dataFileIndex, int offset, int len) { super(); this.zoom = zoom; this.tilex = tilex; this.tiley = tiley; this.dataFileIndex = dataFileIndex; this.offset = offset; this.len = len; } public void writeHeader(RandomAccessFile file) throws IOException { file.writeShort((short) (17 - zoom)); file.write((tilex >> 16) & 0xFF); file.write((tilex >> 8) & 0xFF); file.write(tilex & 0xFF); file.write((tiley >> 16) & 0xFF); file.write((tiley >> 8) & 0xFF); file.write(tiley & 0xFF); file.writeInt(offset); int tmp = (len << 4); tmp = tmp | ((dataFileIndex >> 8) & 0x0F); file.write((tmp >> 16) & 0xFF); file.write((tmp >> 8) & 0xFF); file.write(tmp & 0xFF); file.write(dataFileIndex & 0xFF); } public int compareTo(GCHeaderEntry o) { if (zoom > o.zoom) return -1; if (zoom < o.zoom) return 1; if (tilex > o.tilex) return 1; if (tilex < o.tilex) return -1; if (tiley > o.tiley) return 1; if (tiley < o.tiley) return -1; return 0; } @Override public String toString() { return "GCHeaderEntry [zoom=" + zoom + ", tilex=" + tilex + ", tiley=" + tiley + ", dataFileIndex=" + dataFileIndex + ", offset=" + offset + ", len=" + len + "]"; } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/Maverick.java0000644000175000017500000000236512122526604031171 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import mobac.program.annotations.AtlasCreatorName; /** * Creates maps using the Maverick atlas format * (Android application). */ @AtlasCreatorName("Maverick atlas format") public class Maverick extends OSMTracker { public Maverick() { super(); tileFileNamePattern += ".tile"; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/CacheBox.java0000644000175000017500000002145112122526606031103 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import javax.imageio.ImageIO; import mobac.exceptions.AtlasTestException; import mobac.exceptions.MapCreationException; import mobac.mapsources.mapspace.MercatorPower2MapSpace; import mobac.program.annotations.AtlasCreatorName; import mobac.program.annotations.SupportedParameters; import mobac.program.atlascreators.tileprovider.ConvertedRawTileProvider; import mobac.program.atlascreators.tileprovider.TileProvider; import mobac.program.interfaces.LayerInterface; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSource; import mobac.program.model.TileImageParameters; import mobac.program.model.TileImageParameters.Name; import mobac.utilities.Utilities; @AtlasCreatorName("CacheBox (PACK)") @SupportedParameters(names = { Name.format }) public class CacheBox extends AtlasCreator { private File packFile = null; private RandomAccessFile packRaFile = null; private MapInfo[] mapInfos; private int nextMapOffsetIndex = 0; private MapInfo activeMapInfo; @Override protected void testAtlas() throws AtlasTestException { for (LayerInterface layer : atlas) { if (layer.getMapCount() == 0) throw new AtlasTestException("Empty layers are not allowed", layer); Class mapSourceClass = layer.getMap(0).getMapSource().getClass(); for (MapInterface map : layer) { if (!mapSourceClass.equals(map.getMapSource().getClass())) throw new AtlasTestException( "Different map sources are not allowed within one layer", map); } } } @Override public void finishAtlasCreation() throws IOException { } @Override public void initLayerCreation(LayerInterface layer) throws IOException { nextMapOffsetIndex = 0; packFile = new File(atlasDir, layer.getName() + ".pack"); if (packFile.exists()) Utilities.deleteFile(packFile); packRaFile = new RandomAccessFile(packFile, "rw"); /* * We use the mapsource name as layer name. See feature request #2987674 * for details. */ writeString(layer.getMap(0).getMapSource().getName(), 32); // layer // name writeString(layer.getName(), 128); // layer friendly name writeString("", 256); // layer url - unused writeLong(0); // int64 ticks int mapCount = layer.getMapCount(); writeInt(mapCount); // int32 number of bounding boxes / maps long offset = 32 + 128 + 256 + 8 + 4 + 8; // = 436 offset += mapCount * 28; mapInfos = new MapInfo[mapCount + 1]; int i = 0; for (MapInterface map : layer) { // For each map: int minX = map.getMinTileCoordinate().x / 256; int minY = map.getMinTileCoordinate().y / 256; int maxX = map.getMaxTileCoordinate().x / 256; int maxY = map.getMaxTileCoordinate().y / 256; int tilesInMap = (maxX - minX + 1) * (maxY - minY + 1); writeInt(map.getZoom()); // int32 zoom writeInt(minX); // int32 minX writeInt(maxX); // int32 maxX writeInt(minY); // int32 minY writeInt(maxY); // int32 maxY writeLong(offset); // int64 offset to mapIndexTable mapInfos[i++] = new MapInfo(map, offset, tilesInMap, minX, minY, maxX, maxY); log.trace(String.format("Offset to index table [%d]: 0x%X", i, offset)); offset += tilesInMap * 8; } // We need to keep the offset to the last index table // -> required for index table finalization. mapInfos[i] = new MapInfo(null, offset, 0, 0, 0, 0, 0); log.trace(String.format("End of bounding boxes table: 0x%X", packRaFile.getFilePointer())); packRaFile.seek(offset); log.trace(String.format("Start of tile data: 0x%X", packRaFile.getFilePointer())); } @Override public void initializeMap(MapInterface map, TileProvider mapTileProvider) { super.initializeMap(map, mapTileProvider); TileImageParameters param = map.getParameters(); if (param != null) mapDlTileProvider = new ConvertedRawTileProvider(mapDlTileProvider, param.getFormat()); activeMapInfo = mapInfos[nextMapOffsetIndex++]; if (!activeMapInfo.map.equals(map)) throw new RuntimeException("Map does not match offset info!"); // Just to make sure we use the xy values from mapInfo xMin = activeMapInfo.minX; xMax = activeMapInfo.maxX; yMin = activeMapInfo.minY; yMax = activeMapInfo.maxY; } @Override public void createMap() throws MapCreationException, InterruptedException { createTiles(); } protected void createTiles() throws InterruptedException, MapCreationException { atlasProgress.initMapCreation((xMax - xMin + 1) * (yMax - yMin + 1)); ImageIO.setUseCache(false); int offsetIndex = 0; long[] offsets = new long[activeMapInfo.tileCount]; try { for (int y = yMin; y <= yMax; y++) { for (int x = xMin; x <= xMax; x++) { checkUserAbort(); atlasProgress.incMapCreationProgress(); byte[] sourceTileData = mapDlTileProvider.getTileData(x, y); offsets[offsetIndex++] = packRaFile.getFilePointer(); if (sourceTileData != null) { packRaFile.write(sourceTileData); } } } long pos = packRaFile.getFilePointer(); // Write the offsets of all tiles in this map to the correspondent // offset index table // Due to a bug in CacheBox we have to subtract 8 from the offset packRaFile.seek(activeMapInfo.indexTableOffset - 8); for (long tileoffset : offsets) writeLong(tileoffset); packRaFile.seek(pos); } catch (IOException e) { throw new MapCreationException(map, e); } } @Override public void finishLayerCreation() throws IOException { long tableOffset = mapInfos[mapInfos.length - 1].indexTableOffset; long offset = packRaFile.getFilePointer(); // Due to a bug in CacheBox we have to subtract 8 from the offset packRaFile.seek(tableOffset - 8); // write the offset to the end of the file (after the last image) // required by CacheBox for length calculation of the last tile packRaFile.writeLong(swapLong(offset)); mapInfos = null; packFile = null; packRaFile.close(); packRaFile = null; } @Override public void abortAtlasCreation() throws IOException { mapInfos = null; Utilities.closeFile(packRaFile); packRaFile = null; if (packFile != null) Utilities.deleteFile(packFile); packFile = null; } @Override public boolean testMapSource(MapSource mapSource) { return MercatorPower2MapSpace.INSTANCE_256.equals(mapSource.getMapSpace()); } private void writeString(String text, int length) throws IOException { byte[] buf = new byte[length]; byte[] asciiBytes = text.getBytes("ASCII"); System.arraycopy(asciiBytes, 0, buf, 0, Math.min(length, asciiBytes.length)); for (int i = asciiBytes.length; i < length; i++) buf[i] = ' '; packRaFile.write(buf); } private void writeInt(int v) throws IOException { packRaFile.writeInt(swapInt(v)); } private void writeLong(long v) throws IOException { packRaFile.writeLong(swapLong(v)); } public final static int swapInt(int v) { return (v >>> 24) | (v << 24) | ((v << 8) & 0x00FF0000) | ((v >> 8) & 0x0000FF00); } public final static long swapLong(long v) { long b1 = (v >> 0) & 0xff; long b2 = (v >> 8) & 0xff; long b3 = (v >> 16) & 0xff; long b4 = (v >> 24) & 0xff; long b5 = (v >> 32) & 0xff; long b6 = (v >> 40) & 0xff; long b7 = (v >> 48) & 0xff; long b8 = (v >> 56) & 0xff; return b1 << 56 | b2 << 48 | b3 << 40 | b4 << 32 | b5 << 24 | b6 << 16 | b7 << 8 | b8 << 0; } private class MapInfo { final MapInterface map; final long indexTableOffset; final int tileCount; final int minX; final int minY; final int maxX; final int maxY; public MapInfo(MapInterface map, long indexOffset, int tileCount, int minX, int minY, int maxX, int maxY) { super(); this.map = map; this.indexTableOffset = indexOffset; this.tileCount = tileCount; this.minX = minX; this.maxX = maxX; this.minY = minY; this.maxY = maxY; } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/GpsSportsTracker.java0000644000175000017500000000665412122526604032715 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import javax.imageio.ImageIO; import mobac.exceptions.MapCreationException; import mobac.mapsources.mapspace.MercatorPower2MapSpace; import mobac.program.annotations.AtlasCreatorName; import mobac.program.atlascreators.tileprovider.ConvertedRawTileProvider; import mobac.program.atlascreators.tileprovider.TileProvider; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSource; import mobac.program.model.TileImageFormat; import mobac.program.model.TileImageType; import mobac.utilities.Utilities; /** * Derived from {@link MobileTrailExplorer} */ @AtlasCreatorName("GPS Sports Tracker") public class GpsSportsTracker extends AtlasCreator { private File mapDir = null; protected String appendFileExt = ""; @Override public boolean testMapSource(MapSource mapSource) { return MercatorPower2MapSpace.INSTANCE_256.equals(mapSource.getMapSpace()); } @Override public void initializeMap(MapInterface map, TileProvider mapTileProvider) { super.initializeMap(map, mapTileProvider); String mapName = map.getMapSource().getName().replaceAll(" ", "_"); mapDir = new File(atlasDir, mapName); } public void createMap() throws MapCreationException, InterruptedException { try { Utilities.mkDir(mapDir); } catch (IOException e1) { throw new MapCreationException(map, e1); } if (mapSource.getTileImageType() != TileImageType.PNG) // If the tile image format is not png we have to convert it mapDlTileProvider = new ConvertedRawTileProvider(mapDlTileProvider, TileImageFormat.PNG); createTiles(); } protected void createTiles() throws InterruptedException, MapCreationException { atlasProgress.initMapCreation((xMax - xMin + 1) * (yMax - yMin + 1)); ImageIO.setUseCache(false); for (int x = xMin; x <= xMax; x++) { for (int y = yMin; y <= yMax; y++) { checkUserAbort(); atlasProgress.incMapCreationProgress(); try { String tileFileName = map.getZoom() + "_" + x + "_" + y + ".png"; byte[] sourceTileData = mapDlTileProvider.getTileData(x, y); if (sourceTileData != null) { File f = new File(mapDir, tileFileName); FileOutputStream out = new FileOutputStream(f); try { out.write(sourceTileData); } finally { Utilities.closeStream(out); } } } catch (IOException e) { throw new MapCreationException("Error writing tile image: " + e.getMessage(), map, e); } } } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/GlopusMapFile.java0000644000175000017500000001630012122526606032133 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.nio.charset.Charset; import java.util.LinkedList; import mobac.exceptions.MapCreationException; import mobac.program.annotations.AtlasCreatorName; import mobac.program.atlascreators.impl.MapTileWriter; import mobac.program.interfaces.LayerInterface; import mobac.program.interfaces.MapSpace; import mobac.utilities.GUIExceptionHandler; import mobac.utilities.Utilities; import mobac.utilities.stream.LittleEndianOutputStream; /** * General structure of an GMF file (Little Endian) * *
 * DWORD Version // 0xff000002
 * DWORD cnt // Number of tiles in the file
 * 
 * for each tile: 
 *   DWORD len;         // number of characters in tile name
 *   wchar_t name[len]  // map/tile name in UTF_16LE
 *   DWORD filepos      // offset where image data starts in this file
 *   DWORD width        // tile width in pixel
 *   DWORD height       // tile height in pixel
 *   DWORD cntCalPoints // calibration point count (usually 2 or 4)
 *   for each tile calibration point
 *     DWORD x      // calibration point x position in tile
 *     DWORD y      // calibration point y position in tile
 *     double dLong // longitude of calibration point
 *     double dLat  // latitude of calibration point
 * END OF FILE HEADER
 * Afterwards the tile image data follows as specified by each filepos 
 * offset.
 * 
* */ @AtlasCreatorName(value = "Glopus Map File (GMF)", type = "Gmf") public class GlopusMapFile extends TrekBuddy { @Override public void initLayerCreation(LayerInterface layer) throws IOException { super.initLayerCreation(layer); mapTileWriter = new GlopusTileWriter(layer); } @Override public void finishLayerCreation() throws IOException { mapTileWriter.finalizeMap(); mapTileWriter = null; super.finishLayerCreation(); } @Override public void createMap() throws MapCreationException, InterruptedException { try { ((GlopusTileWriter) mapTileWriter).initMap(); // Select the tile creator instance based on whether tile image // parameters has been set or not if (parameters != null) createCustomTiles(); else createTiles(); } catch (MapCreationException e) { throw e; } catch (InterruptedException e) { throw e; } catch (Exception e) { throw new MapCreationException(map, e); } } @Override public void createAtlasTbaFile(String name) { } @Override public void abortAtlasCreation() throws IOException { mapTileWriter = null; super.abortAtlasCreation(); } private class GlopusTileWriter implements MapTileWriter { final LayerInterface layer; LinkedList tiles; int xCoordStart; int yCoordStart; int tileHeight = 256; int tileWidth = 256; int zoom; MapSpace mapSpace; String tileType; public GlopusTileWriter(LayerInterface layer) { super(); this.layer = layer; tiles = new LinkedList(); } public void initMap() { if (parameters != null) { tileHeight = parameters.getHeight(); tileWidth = parameters.getWidth(); } zoom = map.getZoom(); mapSpace = mapSource.getMapSpace(); xCoordStart = GlopusMapFile.this.xMin * mapSpace.getTileSize(); yCoordStart = GlopusMapFile.this.yMin * mapSpace.getTileSize(); } public void writeTile(int tilex, int tiley, String tileType, byte[] tileData) throws IOException { this.tileType = tileType; int xCooord = xCoordStart + tilex * tileWidth; int yCooord = yCoordStart + tiley * tileHeight; double calWLon = mapSpace.cXToLon(xCooord, zoom); double calNLat = mapSpace.cYToLat(yCooord, zoom); double calELon = mapSpace.cXToLon(xCooord + tileWidth, zoom); double calSLat = mapSpace.cYToLat(yCooord + tileHeight, zoom); GlopusTile gt = new GlopusTile(tileData, calNLat, calWLon, calSLat, calELon); tiles.add(gt); } public void finalizeMap() { File gmfFile = new File(atlasDir, layer.getName() + ".gmf"); FileOutputStream fout = null; try { int count = tiles.size(); int offset = 8 + count * ( // 20 // nameLength, offset and calibration point count, // tile height & width + (12 * 2) // name bytes + (4 * 24) // four calibration points ); fout = new FileOutputStream(gmfFile); LittleEndianOutputStream out = new LittleEndianOutputStream(new BufferedOutputStream(fout, 16384)); out.writeInt((int) 0xff000002); out.writeInt(count); int mapNumber = 0; Charset charset = Charset.forName("UTF-16LE"); for (GlopusTile gt : tiles) { String mapName = String.format("%08d.%s", mapNumber++, tileType); byte[] nameBytes = mapName.getBytes(charset); out.writeInt(mapName.length());// Name length out.write(nameBytes); out.writeInt(offset); out.writeInt(tileWidth); out.writeInt(tileHeight); out.writeInt(4); // number of calibration points out.writeInt(0); out.writeInt(0); out.writeDouble(gt.calWLon); out.writeDouble(gt.calNLat); out.writeInt(tileHeight); out.writeInt(tileWidth); out.writeDouble(gt.calELon); out.writeDouble(gt.calSLat); out.writeInt(tileHeight); out.writeInt(0); out.writeDouble(gt.calELon); out.writeDouble(gt.calNLat); out.writeInt(0); out.writeInt(tileWidth); out.writeDouble(gt.calWLon); out.writeDouble(gt.calSLat); if (log.isTraceEnabled()) log.trace(String.format("Offset %f %f %f %f \"%s\": 0x%x", gt.calWLon, gt.calNLat, gt.calELon, gt.calELon, mapName, offset)); offset += gt.data.length; } out.flush(); out = null; for (GlopusTile gt : tiles) { fout.write(gt.data); } fout.flush(); } catch (IOException e) { GUIExceptionHandler.showExceptionDialog(e); } finally { Utilities.closeStream(fout); } } } private static class GlopusTile { byte[] data; double calNLat; double calWLon; double calSLat; double calELon; public GlopusTile(byte[] data, double calNLat, double calWLon, double calSLat, double calELon) { super(); this.data = data; this.calNLat = calNLat; this.calWLon = calWLon; this.calSLat = calSLat; this.calELon = calELon; } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/TTQV.java0000644000175000017500000001257312122526606030232 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.text.DecimalFormat; import java.text.NumberFormat; import java.util.Locale; import mobac.exceptions.MapCreationException; import mobac.program.ProgramInfo; import mobac.program.annotations.AtlasCreatorName; import mobac.program.atlascreators.tileprovider.TileProvider; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSpace; import mobac.utilities.Utilities; /** * Touratech QV */ @AtlasCreatorName(value = "Touratech QV", type = "Ttqv") public class TTQV extends Ozi { @Override public void initializeMap(MapInterface map, TileProvider mapTileProvider) { super.initializeMap(map, mapTileProvider); } @Override public void createMap() throws MapCreationException, InterruptedException { try { Utilities.mkDir(layerDir); } catch (IOException e1) { throw new MapCreationException(map, e1); } createTiles(); writeCalFile(); } private void writeCalFile() throws MapCreationException { FileOutputStream fout = null; try { fout = new FileOutputStream(new File(layerDir, mapName + "_png.cal")); OutputStreamWriter mapWriter = new OutputStreamWriter(fout, TEXT_FILE_CHARSET); MapSpace mapSpace = mapSource.getMapSpace(); double longitudeMin = mapSpace.cXToLon(xMin * tileSize, zoom); double longitudeMax = mapSpace.cXToLon((xMax + 1) * tileSize, zoom); double latitudeMin = mapSpace.cYToLat((yMax + 1) * tileSize, zoom); double latitudeMax = mapSpace.cYToLat(yMin * tileSize, zoom); int width = (xMax - xMin + 1) * tileSize; int height = (yMax - yMin + 1) * tileSize; double scale = ((latitudeMax - latitudeMin) * (longitudeMax - longitudeMin)) / (width * height); String nsowLine = "%s = 6 = %2.6f\r\n"; String cLine = "c%d_%s = 7 = %2.6f\r\n"; mapWriter.write("; Calibration File for QV Map\r\n"); mapWriter.write("; generated by " + ProgramInfo.getCompleteTitle() + "\r\n"); mapWriter.write("name = 10 = " + mapName + ".png\r\n"); mapWriter.write("fname = 10 = " + mapName + ".png\r\n"); mapWriter.write(String.format(Locale.ENGLISH, nsowLine, "nord", latitudeMax)); mapWriter.write(String.format(Locale.ENGLISH, nsowLine, "sued", latitudeMin)); mapWriter.write(String.format(Locale.ENGLISH, nsowLine, "ost", longitudeMax)); mapWriter.write(String.format(Locale.ENGLISH, nsowLine, "west", longitudeMin)); NumberFormat nf = new DecimalFormat("0.000000E000", Utilities.DFS_ENG); mapWriter.write("scale_area = 6 = " + nf.format(scale).toLowerCase() + "\r\n"); mapWriter.write("proj_mode = 10 = proj\r\n"); mapWriter.write("projparams = 10 = proj=merc\r\n"); mapWriter.write("datum1 = 10 = WGS 84# 6378137# 298.257223563# 0# 0# 0#\r\n"); mapWriter.write("c1_x = 7 = 0\r\n"); mapWriter.write("c1_y = 7 = 0\r\n"); mapWriter.write("c2_x = 7 = " + (width - 1) + "\r\n"); mapWriter.write("c2_y = 7 = 0\r\n"); mapWriter.write("c3_x = 7 = " + (width - 1) + "\r\n"); mapWriter.write("c3_y = 7 = " + (height - 1) + "\r\n"); mapWriter.write("c4_x = 7 = 0\r\n"); mapWriter.write("c4_y = 7 = " + (height - 1) + "\r\n"); mapWriter.write("c5_x = 7 = 0\r\n"); mapWriter.write("c5_y = 7 = 0\r\n"); mapWriter.write("c6_x = 7 = 0\r\n"); mapWriter.write("c6_y = 7 = 0\r\n"); mapWriter.write("c7_x = 7 = 0\r\n"); mapWriter.write("c7_y = 7 = 0\r\n"); mapWriter.write("c8_x = 7 = 0\r\n"); mapWriter.write("c8_y = 7 = 0\r\n"); mapWriter.write("c9_x = 7 = 0\r\n"); mapWriter.write("c9_y = 7 = 0\r\n"); mapWriter.write(String.format(Locale.ENGLISH, cLine, 1, "lat", latitudeMax)); mapWriter.write(String.format(Locale.ENGLISH, cLine, 1, "lon", longitudeMin)); mapWriter.write(String.format(Locale.ENGLISH, cLine, 2, "lat", latitudeMax)); mapWriter.write(String.format(Locale.ENGLISH, cLine, 2, "lon", longitudeMax)); mapWriter.write(String.format(Locale.ENGLISH, cLine, 3, "lat", latitudeMin)); mapWriter.write(String.format(Locale.ENGLISH, cLine, 3, "lon", longitudeMax)); mapWriter.write(String.format(Locale.ENGLISH, cLine, 4, "lat", latitudeMin)); mapWriter.write(String.format(Locale.ENGLISH, cLine, 4, "lon", longitudeMin)); mapWriter.flush(); mapWriter.close(); } catch (IOException e) { throw new MapCreationException("Error writing cal file: " + e.getMessage(), map, e); } finally { Utilities.closeStream(fout); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/Osmdroid.java0000644000175000017500000000673012131416172031206 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import mobac.exceptions.AtlasTestException; import mobac.exceptions.MapCreationException; import mobac.program.annotations.AtlasCreatorName; import mobac.program.atlascreators.impl.MapTileWriter; import mobac.program.atlascreators.tileprovider.TileProvider; import mobac.program.interfaces.AtlasInterface; import mobac.program.interfaces.MapInterface; import mobac.program.model.Settings; import mobac.utilities.Utilities; import mobac.utilities.stream.ZipStoreOutputStream; /** * * http://sourceforge.net/p/mobac/feature-requests/162/ */ @AtlasCreatorName("Osmdroid ZIP") public class Osmdroid extends OSMTracker { protected ZipStoreOutputStream zipStream = null; protected String currentMapStoreName = null; public void createMap() throws MapCreationException, InterruptedException { createTiles(); } @Override public void startAtlasCreation(AtlasInterface atlas, File customAtlasDir) throws AtlasTestException, IOException, InterruptedException { if (customAtlasDir == null) customAtlasDir = Settings.getInstance().getAtlasOutputDirectory(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd_HHmmss"); String atlasDirName = atlas.getName() + "_" + sdf.format(new Date()); super.startAtlasCreation(atlas, customAtlasDir); zipStream = new ZipStoreOutputStream(new File(atlasDir, atlasDirName + ".zip")); mapTileWriter = new OSMDroidTileWriter(); } @Override public void abortAtlasCreation() throws IOException { Utilities.closeStream(zipStream); super.abortAtlasCreation(); } @Override public void finishAtlasCreation() throws IOException, InterruptedException { Utilities.closeStream(zipStream); super.finishAtlasCreation(); } @Override public void initializeMap(MapInterface map, TileProvider mapTileProvider) { super.initializeMap(map, mapTileProvider); currentMapStoreName = map.getMapSource().getName(); if (currentMapStoreName.equals("TilesAtHome")) currentMapStoreName = "Osmarender"; else if (currentMapStoreName.equals("OSM Cycle Map")) currentMapStoreName = "CycleMap"; } private class OSMDroidTileWriter implements MapTileWriter { public void finalizeMap() throws IOException { } public void writeTile(int tilex, int tiley, String tileType, byte[] tileData) throws IOException { String tileName = currentMapStoreName + "/" + String.format(tileFileNamePattern, zoom, tilex, tiley, tileType); zipStream.writeStoredEntry(tileName, tileData); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/Galileo.java0000644000175000017500000000203612122526604030777 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import mobac.program.annotations.AtlasCreatorName; @AtlasCreatorName("Galileo Offline Maps") public class Galileo extends BigPlanetTracks { } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/TomTomRaster.java0000644000175000017500000002160212131416122032014 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.awt.Color; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.StringWriter; import java.text.NumberFormat; import javax.imageio.ImageIO; import mobac.exceptions.AtlasTestException; import mobac.exceptions.MapCreationException; import mobac.mapsources.mapspace.MercatorPower2MapSpace; import mobac.program.annotations.AtlasCreatorName; import mobac.program.interfaces.LayerInterface; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSpace; import mobac.program.interfaces.MapSpace.ProjectionCategory; import mobac.program.interfaces.TileImageDataWriter; import mobac.program.tiledatawriter.TileImageJpegDataWriter; import mobac.utilities.Charsets; import mobac.utilities.Utilities; /** * * http://sourceforge.net/p/mobac/feature-requests/225/ * http://create.tomtom.com/manuals/create-your-own-content/index.html?map_overlays.htm * * @author r_x */ @AtlasCreatorName(value = "TomTom Raster (image + SAT)") public class TomTomRaster extends AtlasCreator { protected File layerDir; @Override public boolean testMapSource(MapSource mapSource) { MapSpace mapSpace = mapSource.getMapSpace(); return (mapSpace instanceof MercatorPower2MapSpace && ProjectionCategory.SPHERE.equals(mapSpace .getProjectionCategory())); } @Override protected void testAtlas() throws AtlasTestException { Runtime r = Runtime.getRuntime(); long heapMaxSize = r.maxMemory(); int maxMapSize = (int) (Math.sqrt(heapMaxSize / 3d) * 0.8); // reduce maximum by 20% maxMapSize = (maxMapSize / 100) * 100; // round by 100; for (LayerInterface layer : atlas) { for (MapInterface map : layer) { int w = map.getMaxTileCoordinate().x - map.getMinTileCoordinate().x; int h = map.getMaxTileCoordinate().y - map.getMinTileCoordinate().y; if (w > maxMapSize || h > maxMapSize) throw new AtlasTestException("Map size too large for memory (is: " + Math.max(w, h) + " max: " + maxMapSize + ")", map); } } } @Override public void initLayerCreation(LayerInterface layer) throws IOException { super.initLayerCreation(layer); layerDir = new File(atlasDir, layer.getName()); Utilities.mkDirs(layerDir); } @Override public void createMap() throws MapCreationException, InterruptedException { try { createImage(); } catch (InterruptedException e) { throw e; } catch (MapCreationException e) { throw e; } catch (Exception e) { throw new MapCreationException(map, e); } } protected void createImage() throws InterruptedException, MapCreationException { atlasProgress.initMapCreation((xMax - xMin + 1) * (yMax - yMin + 1)); ImageIO.setUseCache(false); int mapWidth = (xMax - xMin + 1) * tileSize; int mapHeight = (yMax - yMin + 1) * tileSize; int maxImageSize = getMaxImageSize(); int imageWidth = Math.min(maxImageSize, mapWidth); int imageHeight = Math.min(maxImageSize, mapHeight); int len = Math.max(mapWidth, mapHeight); double scaleFactor = 1.0; boolean scaleImage = (len > maxImageSize); if (scaleImage) { scaleFactor = (double) getMaxImageSize() / (double) len; if (mapWidth != mapHeight) { // Map is not rectangle -> adapt height or width if (mapWidth > mapHeight) imageHeight = (int) (scaleFactor * mapHeight); else imageWidth = (int) (scaleFactor * mapWidth); } } if (imageHeight < 0 || imageWidth < 0) throw new MapCreationException("Invalid map size: (width/height: " + imageWidth + "/" + imageHeight + ")", map); long imageSize = 3l * ((long) imageWidth) * ((long) imageHeight); if (imageSize > Integer.MAX_VALUE) throw new MapCreationException("Map image too large: (width/height: " + imageWidth + "/" + imageHeight + ") - reduce the map size and try again", map); BufferedImage tileImage = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_3BYTE_BGR); Graphics2D graphics = tileImage.createGraphics(); try { if (scaleImage) { graphics.setTransform(AffineTransform.getScaleInstance(scaleFactor, scaleFactor)); graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); } int lineY = 0; for (int y = yMin; y <= yMax; y++) { int lineX = 0; for (int x = xMin; x <= xMax; x++) { checkUserAbort(); atlasProgress.incMapCreationProgress(); try { byte[] sourceTileData = mapDlTileProvider.getTileData(x, y); if (sourceTileData != null) { BufferedImage tile = ImageIO.read(new ByteArrayInputStream(sourceTileData)); graphics.drawImage(tile, lineX, lineY, Color.WHITE, null); } } catch (IOException e) { log.error("", e); } lineX += tileSize; } lineY += tileSize; } } finally { graphics.dispose(); } writeTileImage(tileImage); } protected void writeTileImage(BufferedImage tileImage) throws MapCreationException { TileImageDataWriter writer; if (parameters != null) { writer = parameters.getFormat().getDataWriter(); } else writer = new TileImageJpegDataWriter(0.9); writer.initialize(); try { int initialBufferSize = tileImage.getWidth() * tileImage.getHeight() / 4; ByteArrayOutputStream buf = new ByteArrayOutputStream(initialBufferSize); writer.processImage(tileImage, buf); String imageFileName = map.getName() + "." + writer.getType(); File imageFile = new File(layerDir, imageFileName); FileOutputStream fout = new FileOutputStream(imageFile); try { fout.write(buf.toByteArray()); fout.flush(); } finally { fout.close(); } writeSatFile(imageFileName, tileImage.getWidth(), tileImage.getHeight()); } catch (Exception e) { throw new MapCreationException(map, e); } } /** * SAT file content * *
	 * Line 1 - filename of the image file.
	 * Line 2 - GPS coordinate of the top left corner of the image (longitude).
	 * Line 3 - GPS coordinate of the top left corner of the image (latitude).
	 * Line 4 - GPS coordinate of the bottom right corner of the image (longitude).
	 * Line 5 - GPS coordinate of the bottom right corner of the image (latitude).
	 * Line 6 - Minimum zoom level for image to be visible (min = 0).
	 * Line 7 - Maximum zoom level for image to be visible (max = 65,535).
	 * Line 8 - Width of image file in pixels.
	 * Line 9 - Height of image file in pixels.
	 * 
*/ protected void writeSatFile(String imageFileName, int width, int height) throws IOException { int startX = xMin * tileSize; int startY = yMin * tileSize; MapSpace mapSpace = mapSource.getMapSpace(); NumberFormat df = Utilities.FORMAT_6_DEC_ENG; String longitudeMin = df.format(mapSpace.cXToLon(startX, zoom)); String longitudeMax = df.format(mapSpace.cXToLon(startX + width, zoom)); String latitudeMin = df.format(mapSpace.cYToLat(startY + height, zoom)); String latitudeMax = df.format(mapSpace.cYToLat(startY, zoom)); StringWriter sw = new StringWriter(); sw.write(imageFileName + "\r\n"); sw.write(longitudeMin + "\r\n"); sw.write(latitudeMax + "\r\n"); sw.write(longitudeMax + "\r\n"); sw.write(latitudeMin + "\r\n"); sw.write("0\r\n"); sw.write("65535\r\n"); sw.write(Integer.toString(width) + "\r\n"); sw.write(Integer.toString(height)); int i = imageFileName.lastIndexOf('.'); String satFileName = imageFileName.substring(0, i) + ".sat"; FileOutputStream fout = new FileOutputStream(new File(layerDir,satFileName)); OutputStreamWriter writer = new OutputStreamWriter(fout, Charsets.ISO_8859_1); writer.append(sw.toString()); writer.flush(); writer.close(); } protected int getMaxImageSize() { return 2048; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/AndNav.java0000644000175000017500000000253312122526604030574 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import mobac.program.annotations.AtlasCreatorName; /** * Creates maps using the AndNav atlas format. * * Please note that this atlas format ignores the defined atlas structure. It * uses a separate directory for each used map source and inside one directory * for each zoom level. */ @AtlasCreatorName("AndNav atlas format") public class AndNav extends OSMTracker { public AndNav() { super(); tileFileNamePattern += ".andnav"; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/Ozi.java0000644000175000017500000002273212122526604030171 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.awt.Color; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.util.Locale; import javax.imageio.ImageIO; import mobac.exceptions.MapCreationException; import mobac.mapsources.mapspace.MercatorPower2MapSpace; import mobac.program.annotations.AtlasCreatorName; import mobac.program.annotations.SupportedParameters; import mobac.program.atlascreators.tileprovider.TileProvider; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSpace; import mobac.program.interfaces.MapSpace.ProjectionCategory; import mobac.utilities.Utilities; import mobac.utilities.geo.GeoUtils; import mobac.utilities.imageio.PngXxlWriter; @AtlasCreatorName(value = "OziExplorer (PNG & MAP)", type = "OziPng") @SupportedParameters(names = {}) public class Ozi extends AtlasCreator { protected File layerDir = null; protected String mapName = null; @Override public boolean testMapSource(MapSource mapSource) { MapSpace mapSpace = mapSource.getMapSpace(); return (mapSpace instanceof MercatorPower2MapSpace && ProjectionCategory.SPHERE.equals(mapSpace .getProjectionCategory())); // TODO supports Mercator ellipsoid? } @Override public void initializeMap(MapInterface map, TileProvider mapTileProvider) { super.initializeMap(map, mapTileProvider); layerDir = new File(atlasDir, map.getLayer().getName()); mapName = map.getName(); } public void createMap() throws MapCreationException, InterruptedException { try { Utilities.mkDir(layerDir); } catch (IOException e) { throw new MapCreationException(map, e); } createTiles(); writeMapFile(); } protected void writeMapFile() { FileOutputStream fout = null; try { fout = new FileOutputStream(new File(layerDir, mapName + ".map")); writeMapFile(map.getName() + ".png", fout); } catch (Exception e) { log.error("", e); } finally { Utilities.closeStream(fout); } } protected void writeMapFile(String imageFileName, OutputStream stream) throws IOException { log.trace("Writing map file"); OutputStreamWriter mapWriter = new OutputStreamWriter(stream, TEXT_FILE_CHARSET); MapSpace mapSpace = mapSource.getMapSpace(); double longitudeMin = mapSpace.cXToLon(xMin * tileSize, zoom); double longitudeMax = mapSpace.cXToLon((xMax + 1) * tileSize - 1, zoom); double latitudeMin = mapSpace.cYToLat((yMax + 1) * tileSize - 1, zoom); double latitudeMax = mapSpace.cYToLat(yMin * tileSize, zoom); int width = (xMax - xMin + 1) * tileSize; int height = (yMax - yMin + 1) * tileSize; // Calculate the 100 pixel scale here for MM1B // Supplied by MrPete, based on suggestion from Des Newman, author of OziExplorer // Set latitude to midpoint (maxLat+minLat/2) double midLat = Math.toRadians((latitudeMax + latitudeMin) / 2.0); // Calculate 50 pixel Longitude for interpolation: Lon50 = 50/(ImagePixelWidth) * abs(maxLon - minLon) double rlonMax = Math.toRadians(longitudeMax); double rlonMin = Math.toRadians(longitudeMin); double Lon50 = (50.0 / width) * Math.abs(rlonMax - rlonMin); // Calculate midpoint Lon: midLon = (maxLon+minLon)/2 double midLon = (rlonMax + rlonMin) / 2.0; // Set lonW and lonE to midpoint +/1 50 pixels: lonW = midLon - Lon50; lonE = midLon+Lon50 double lonW = midLon - Lon50; double lonE = midLon + Lon50; // Now do the calculation: // d=2*asin(sqrt((sin((lat1-lat2)/2))^2 + cos(lat1)*cos(lat2)*(sin((lon1-lon2)/2))^2)) // d=2*asin(sqrt(0 + cos(lat1)*cos(lat2)*(sin((lon1-lon2)/2))^2)) double mDistA = Math.cos(midLat); double mDistB = Math.sin((lonW - lonE) / 2.0); double mDist = 2.0 * Math.asin(Math.sqrt(mDistA * mDistA * mDistB * mDistB)); // For the final scaling, convert to distance in meters (multiply by earth radius), // then simply divide by 100 (100 pixels between the two reference points) // We're using the polar radius, as this gives results very close to OziExplorer double mm1b = 6399592 * mDist / 100.0; mapWriter.write(prepareMapString(imageFileName, longitudeMin, longitudeMax, latitudeMin, latitudeMax, width, height, mm1b)); mapWriter.flush(); } protected String prepareMapString(String fileName, double longitudeMin, double longitudeMax, double latitudeMin, double latitudeMax, int width, int height, double mm1b) { StringBuffer sbMap = new StringBuffer(); sbMap.append("OziExplorer Map Data File Version 2.2\r\n"); sbMap.append(fileName + "\r\n"); sbMap.append(fileName + "\r\n"); sbMap.append("1 ,Map Code,\r\n"); sbMap.append("WGS 84,WGS 84, 0.0000, 0.0000,WGS 84\r\n"); sbMap.append("Reserved 1\r\n"); sbMap.append("Reserved 2\r\n"); sbMap.append("Magnetic Variation,,,E\r\n"); sbMap.append("Map Projection,Mercator,PolyCal,No," + "AutoCalOnly,No,BSBUseWPX,No\r\n"); String latMax = GeoUtils.getDegMinFormat(latitudeMax, true); String latMin = GeoUtils.getDegMinFormat(latitudeMin, true); String lonMax = GeoUtils.getDegMinFormat(longitudeMax, false); String lonMin = GeoUtils.getDegMinFormat(longitudeMin, false); String pointLine = "Point%02d,xy, %4s, %4s,in, deg, %1s, %1s, grid, , , ,N\r\n"; sbMap.append(String.format(pointLine, 1, 0, 0, latMax, lonMin)); sbMap.append(String.format(pointLine, 2, width - 1, 0, latMax, lonMax)); sbMap.append(String.format(pointLine, 3, width - 1, height - 1, latMin, lonMax)); sbMap.append(String.format(pointLine, 4, 0, height - 1, latMin, lonMin)); for (int i = 5; i <= 30; i++) { String s = String.format(pointLine, i, "", "", "", ""); sbMap.append(s); } sbMap.append("Projection Setup,,,,,,,,,,\r\n"); sbMap.append("Map Feature = MF ; Map Comment = MC These follow if they exist\r\n"); sbMap.append("Track File = TF These follow if they exist\r\n"); sbMap.append("Moving Map Parameters = MM? These follow if they exist\r\n"); sbMap.append("MM0,Yes\r\n"); sbMap.append("MMPNUM,4\r\n"); String mmpxLine = "MMPXY, %d, %5d, %5d\r\n"; sbMap.append(String.format(mmpxLine, 1, 0, 0)); sbMap.append(String.format(mmpxLine, 2, width - 1, 0)); sbMap.append(String.format(mmpxLine, 3, width - 1, height - 1)); sbMap.append(String.format(mmpxLine, 4, 0, height - 1)); String mpllLine = "MMPLL, %d, %2.6f, %2.6f\r\n"; sbMap.append(String.format(Locale.ENGLISH, mpllLine, 1, longitudeMin, latitudeMax)); sbMap.append(String.format(Locale.ENGLISH, mpllLine, 2, longitudeMax, latitudeMax)); sbMap.append(String.format(Locale.ENGLISH, mpllLine, 3, longitudeMax, latitudeMin)); sbMap.append(String.format(Locale.ENGLISH, mpllLine, 4, longitudeMin, latitudeMin)); sbMap.append("MOP,Map Open Position,0,0\r\n"); sbMap.append(String.format(Locale.ENGLISH, "MM1B, %2.6f\r\n", mm1b)); sbMap.append("IWH,Map Image Width/Height, " + width + ", " + height + "\r\n"); return sbMap.toString(); } /** * Writes the large picture (tile) line by line. Each line has the full width of the map and the height of one tile * (256 pixels). */ protected void createTiles() throws InterruptedException, MapCreationException { atlasProgress.initMapCreation((xMax - xMin + 1) * (yMax - yMin + 1)); ImageIO.setUseCache(false); int width = (xMax - xMin + 1) * tileSize; int height = (yMax - yMin + 1) * tileSize; int tileLineHeight = tileSize; FileOutputStream fileOs = null; Color backgroundColor = mapSource.getBackgroundColor(); try { fileOs = new FileOutputStream(new File(layerDir, mapName + ".png")); PngXxlWriter pngWriter = new PngXxlWriter(width, height, fileOs); for (int y = yMin; y <= yMax; y++) { BufferedImage lineImage = new BufferedImage(width, tileLineHeight, BufferedImage.TYPE_INT_RGB); Graphics2D graphics = lineImage.createGraphics(); try { graphics.setColor(backgroundColor); graphics.fillRect(0, 0, width, tileLineHeight); int lineX = 0; for (int x = xMin; x <= xMax; x++) { checkUserAbort(); atlasProgress.incMapCreationProgress(); BufferedImage tile = mapDlTileProvider.getTileImage(x, y); if (tile != null) graphics.drawImage(tile, lineX, 0, backgroundColor, null); lineX += tileSize; } } finally { graphics.dispose(); } pngWriter.writeTileLine(lineImage); } pngWriter.finish(); } catch (IOException e) { throw new MapCreationException(map, e); } finally { Utilities.closeStream(fileOs); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/MobileTrailExplorer.java0000644000175000017500000000777612122526606033371 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import javax.imageio.ImageIO; import mobac.exceptions.MapCreationException; import mobac.mapsources.mapspace.MercatorPower2MapSpace; import mobac.program.annotations.AtlasCreatorName; import mobac.program.atlascreators.tileprovider.ConvertedRawTileProvider; import mobac.program.atlascreators.tileprovider.TileProvider; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSource; import mobac.program.model.TileImageFormat; import mobac.program.model.TileImageType; import mobac.utilities.Utilities; /** * Creates maps using the Mobile Trail Explorer (MTE) / JTileDownloader atlas format (converted to PNG, size 256x256 * pixel). * * Please note that this atlas format ignores the defined atlas structure. It uses a separate directory for each used * map source and inside one directory for each zoom level. */ @AtlasCreatorName(value = "Mobile Trail Explorer", type = "MTE") public class MobileTrailExplorer extends AtlasCreator { private File mapDir = null; private File mapZoomDir = null; protected String appendFileExt = ""; @Override public boolean testMapSource(MapSource mapSource) { return MercatorPower2MapSpace.INSTANCE_256.equals(mapSource.getMapSpace()); } @Override public void initializeMap(MapInterface map, TileProvider mapTileProvider) { super.initializeMap(map, mapTileProvider); String mapName = map.getMapSource().getName().replaceAll(" ", "_"); mapDir = new File(atlasDir, mapName); mapZoomDir = new File(mapDir, Integer.toString(map.getZoom())); } public void createMap() throws MapCreationException, InterruptedException { try { Utilities.mkDir(mapDir); Utilities.mkDir(mapZoomDir); } catch (IOException e1) { throw new MapCreationException(map, e1); } if (mapSource.getTileImageType() != TileImageType.PNG) // If the tile image format is not png we have to convert it mapDlTileProvider = new ConvertedRawTileProvider(mapDlTileProvider, TileImageFormat.PNG); createTiles(); } protected void createTiles() throws InterruptedException, MapCreationException { atlasProgress.initMapCreation((xMax - xMin + 1) * (yMax - yMin + 1)); ImageIO.setUseCache(false); for (int x = xMin; x <= xMax; x++) { File xDir = new File(mapZoomDir, Integer.toString(x)); try { Utilities.mkDir(xDir); } catch (IOException e1) { throw new MapCreationException(map, e1); } for (int y = yMin; y <= yMax; y++) { checkUserAbort(); atlasProgress.incMapCreationProgress(); try { String tileFileName = x + "/" + y + ".png"; byte[] sourceTileData = mapDlTileProvider.getTileData(x, y); if (sourceTileData != null) { File f = new File(mapZoomDir, tileFileName); FileOutputStream out = new FileOutputStream(f); try { out.write(sourceTileData); } finally { Utilities.closeStream(out); } } } catch (IOException e) { throw new MapCreationException("Error writing tile image: " + e.getMessage(), map, e); } } } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/Ublox.java0000644000175000017500000000666612122526606030533 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.util.Locale; import mobac.program.annotations.AtlasCreatorName; import mobac.program.interfaces.MapSpace; import mobac.utilities.Utilities; @AtlasCreatorName("Ublox") public class Ublox extends Ozi { @Override protected void writeMapFile() { FileOutputStream fout = null; try { fout = new FileOutputStream(new File(layerDir, mapName + ".mcf")); writeMapFile(map.getName(), fout); } catch (Exception e) { log.error("", e); } finally { Utilities.closeStream(fout); } } @Override protected void writeMapFile(String imageFileName, OutputStream stream) throws IOException { log.trace("Writing mcf file"); OutputStreamWriter mcfWriter = new OutputStreamWriter(stream, TEXT_FILE_CHARSET); MapSpace mapSpace = mapSource.getMapSpace(); double longitudeMin = mapSpace.cXToLon(xMin * tileSize, zoom); double longitudeMax = mapSpace.cXToLon((xMax + 1) * tileSize - 1, zoom); double latitudeMin = mapSpace.cYToLat((yMax + 1) * tileSize - 1, zoom); double latitudeMax = mapSpace.cYToLat(yMin * tileSize, zoom); int width = (xMax - xMin + 1) * tileSize; int height = (yMax - yMin + 1) * tileSize; String refFmt = "%d = %5d, %5d, %10.6f, %10.6f\r\n"; mcfWriter.write("; I N F O\r\n"); mcfWriter.write("; ------------------------------------------------------------\r\n"); mcfWriter.write("; File: " + imageFileName + ".mcf\r\n"); mcfWriter.write("; Source: " + map.getMapSource().getName() + "\r\n"); mcfWriter.write("\r\n"); mcfWriter.write("; R E F E R E N C E\r\n"); mcfWriter.write("; ------------------------------------------------------------\r\n"); mcfWriter.write("; 3 Points must be defined to calibrate a Map\r\n"); mcfWriter.write("; Parameters:\r\n"); mcfWriter.write("; # = index of the point (1 to 3)\r\n"); mcfWriter.write("; x,y = image coordinates\r\n"); mcfWriter.write("; lat,lon = world coordinates\r\n"); mcfWriter.write("; Syntax:\r\n"); mcfWriter.write("; # = , , , \r\n"); mcfWriter.write("\r\n"); mcfWriter.write("[REFERENCE]\r\n"); mcfWriter.write(String.format(Locale.ENGLISH, refFmt, 1, 0, 0, longitudeMin, latitudeMax)); mcfWriter.write(String.format(Locale.ENGLISH, refFmt, 2, width, height, longitudeMax, latitudeMin)); mcfWriter.write(String.format(Locale.ENGLISH, refFmt, 3, width, 0, longitudeMax, latitudeMax)); mcfWriter.flush(); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/RMapsSQLite.java0000644000175000017500000002252612127544344031543 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.io.File; import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Locale; import mobac.exceptions.AtlasTestException; import mobac.exceptions.MapCreationException; import mobac.program.annotations.AtlasCreatorName; import mobac.program.annotations.SupportedParameters; import mobac.program.atlascreators.tileprovider.ConvertedRawTileProvider; import mobac.program.interfaces.AtlasInterface; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSpace; import mobac.program.interfaces.MapSpace.ProjectionCategory; import mobac.program.interfaces.RequiresSQLite; import mobac.program.model.Settings; import mobac.program.model.TileImageParameters; import mobac.program.model.TileImageParameters.Name; import mobac.utilities.Utilities; import mobac.utilities.jdbc.SQLiteLoader; /** * Atlas/Map creator for "BigPlanet-Maps application for Android" (offline SQLite maps) * http://code.google.com/p/bigplanet/ *

* Some source parts are taken from the "android-map.blogspot.com Version of Mobile Atlas Creator": * http://code.google.com/p/android-map/ *

*

* Additionally the created BigPlanet SQLite database has one additional table containing special info needed by the * Android application RMaps.
* (Database statements: {@link #RMAPS_TABLE_INFO_DDL} and {@link #RMAPS_UPDATE_INFO_SQL} ).
* Changes made by Robert, author of RMaps. *

*/ @AtlasCreatorName(value = "RMaps SQLite", type = "RMaps") @SupportedParameters(names = { Name.format }) public class RMapsSQLite extends AtlasCreator implements RequiresSQLite { private static final int MAX_BATCH_SIZE = 1000; private static final String TABLE_DDL = "CREATE TABLE IF NOT EXISTS tiles (x int, y int, z int, s int, image blob, PRIMARY KEY (x,y,z,s))"; private static final String INDEX_DDL = "CREATE INDEX IF NOT EXISTS IND on tiles (x,y,z,s)"; private static final String INSERT_SQL = "INSERT or REPLACE INTO tiles (x,y,z,s,image) VALUES (?,?,?,0,?)"; private static final String RMAPS_TABLE_INFO_DDL = "CREATE TABLE IF NOT EXISTS info AS SELECT 99 AS minzoom, 0 AS maxzoom"; private static final String RMAPS_CLEAR_INFO_SQL = "DELETE FROM info;"; private static final String RMAPS_UPDATE_INFO_MINMAX_SQL = "INSERT INTO info (minzoom,maxzoom) VALUES (?,?);"; private static final String RMAPS_INFO_MAX_SQL = "SELECT DISTINCT z FROM tiles ORDER BY z DESC LIMIT 1;"; private static final String RMAPS_INFO_MIN_SQL = "SELECT DISTINCT z FROM tiles ORDER BY z ASC LIMIT 1;"; protected File databaseFile; protected Connection conn = null; protected PreparedStatement prepStmt; public RMapsSQLite() { super(); SQLiteLoader.loadSQLiteOrShowError(); } @Override public boolean testMapSource(MapSource mapSource) { MapSpace mapSpace = mapSource.getMapSpace(); boolean correctTileSize = (256 == mapSpace.getTileSize()); ProjectionCategory pc = mapSpace.getProjectionCategory(); boolean correctProjection = (ProjectionCategory.SPHERE.equals(pc) || ProjectionCategory.ELLIPSOID.equals(pc)); return correctTileSize && correctProjection; } @Override public void startAtlasCreation(AtlasInterface atlas, File customAtlasDir) throws IOException, AtlasTestException, InterruptedException { if (customAtlasDir == null) customAtlasDir = Settings.getInstance().getAtlasOutputDirectory(); super.startAtlasCreation(atlas, customAtlasDir); databaseFile = new File(atlasDir, getDatabaseFileName()); log.debug("SQLite Database file: " + databaseFile); } @Override public void createMap() throws MapCreationException, InterruptedException { try { Utilities.mkDir(atlasDir); } catch (IOException e) { throw new MapCreationException(map, e); } try { SQLiteLoader.loadSQLite(); } catch (SQLException e) { throw new MapCreationException(SQLiteLoader.getMsgSqliteMissing(), map, e); } try { openConnection(); initializeDB(); createTiles(); } catch (SQLException e) { throw new MapCreationException("Error creating SQL database \"" + databaseFile + "\": " + e.getMessage(), map, e); } } protected void openConnection() throws SQLException { if (conn == null || conn.isClosed()) { String url = "jdbc:sqlite:/" + databaseFile.getAbsolutePath(); conn = DriverManager.getConnection(url); } } @Override public void abortAtlasCreation() throws IOException { SQLiteLoader.closeConnection(conn); conn = null; super.abortAtlasCreation(); } @Override public void finishAtlasCreation() throws IOException, InterruptedException { SQLiteLoader.closeConnection(conn); conn = null; super.finishAtlasCreation(); } protected void initializeDB() throws SQLException { Statement stat = conn.createStatement(); stat.executeUpdate(TABLE_DDL); stat.executeUpdate(INDEX_DDL); createInfoTable(stat); stat.executeUpdate("CREATE TABLE IF NOT EXISTS android_metadata (locale TEXT)"); if (!(stat.executeQuery("SELECT * FROM android_metadata").next())) { String locale = Locale.getDefault().toString(); stat.executeUpdate("INSERT INTO android_metadata VALUES ('" + locale + "')"); } stat.close(); } protected void createInfoTable(Statement stat) throws SQLException { stat.executeUpdate(RMAPS_TABLE_INFO_DDL); } protected void createTiles() throws InterruptedException, MapCreationException { int maxMapProgress = 2 * (xMax - xMin + 1) * (yMax - yMin + 1); atlasProgress.initMapCreation(maxMapProgress); TileImageParameters param = map.getParameters(); if (param != null) mapDlTileProvider = new ConvertedRawTileProvider(mapDlTileProvider, param.getFormat()); try { conn.setAutoCommit(false); int batchTileCount = 0; int tilesWritten = 0; Runtime r = Runtime.getRuntime(); long heapMaxSize = r.maxMemory(); prepStmt = conn.prepareStatement(getTileInsertSQL()); for (int x = xMin; x <= xMax; x++) { for (int y = yMin; y <= yMax; y++) { checkUserAbort(); atlasProgress.incMapCreationProgress(); try { byte[] sourceTileData = mapDlTileProvider.getTileData(x, y); if (sourceTileData != null) { writeTile(x, y, zoom, sourceTileData); tilesWritten++; long heapAvailable = heapMaxSize - r.totalMemory() + r.freeMemory(); batchTileCount++; if ((heapAvailable < HEAP_MIN) || (batchTileCount >= MAX_BATCH_SIZE)) { log.trace("Executing batch containing " + batchTileCount + " tiles"); prepStmt.executeBatch(); prepStmt.clearBatch(); System.gc(); conn.commit(); atlasProgress.incMapCreationProgress(batchTileCount); batchTileCount = 0; } } } catch (IOException e) { throw new MapCreationException(map, e); } } } prepStmt.executeBatch(); prepStmt.clearBatch(); System.gc(); if (tilesWritten > 0) updateTileMetaInfo(); log.trace("Final commit containing " + batchTileCount + " tiles"); conn.commit(); atlasProgress.setMapCreationProgress(maxMapProgress); } catch (SQLException e) { throw new MapCreationException(map, e); } } protected void updateTileMetaInfo() throws SQLException { Statement stat = conn.createStatement(); ResultSet rs = stat.executeQuery(RMAPS_INFO_MAX_SQL); if (!rs.next()) throw new SQLException("failed to retrieve max tile zoom info"); int max = rs.getInt(1); rs.close(); rs = stat.executeQuery(RMAPS_INFO_MIN_SQL); if (!rs.next()) throw new SQLException("failed to retrieve min tile zoom info"); int min = rs.getInt(1); rs.close(); PreparedStatement ps = conn.prepareStatement(RMAPS_UPDATE_INFO_MINMAX_SQL); ps.setInt(1, min); ps.setInt(2, max); stat.execute(RMAPS_CLEAR_INFO_SQL); ps.execute(); stat.close(); ps.close(); } protected void writeTile(int x, int y, int z, byte[] tileData) throws SQLException, IOException { prepStmt.setInt(1, x); prepStmt.setInt(2, y); prepStmt.setInt(3, 17 - z); prepStmt.setBytes(4, tileData); prepStmt.addBatch(); } protected String getDatabaseFileName() { return atlas.getName() + ".sqlitedb"; } protected String getTileInsertSQL() { return INSERT_SQL; } } ././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/MobileTrailExplorerCache.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/MobileTrailExplorerCache0000644000175000017500000001233312122526604033354 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.io.BufferedOutputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.HashSet; import java.util.Set; import javax.imageio.ImageIO; import mobac.exceptions.AtlasTestException; import mobac.exceptions.MapCreationException; import mobac.mapsources.mapspace.MercatorPower2MapSpace; import mobac.program.annotations.AtlasCreatorName; import mobac.program.atlascreators.tileprovider.ConvertedRawTileProvider; import mobac.program.atlascreators.tileprovider.TileProvider; import mobac.program.interfaces.AtlasInterface; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSource; import mobac.program.model.TileImageFormat; import mobac.program.model.TileImageType; import mobac.utilities.Utilities; /** * Creates maps using the Mobile Trail Explorer (MTE) cache format. * * Please note that this atlas format ignores the defined atlas structure. * */ @AtlasCreatorName(value = "Mobile Trail Explorer Cache", type = "MTECache") public class MobileTrailExplorerCache extends AtlasCreator { protected DataOutputStream cacheOutStream = null; protected long lastTileOffset = 0; protected Set availableTileList = new HashSet(); @Override public boolean testMapSource(MapSource mapSource) { return MercatorPower2MapSpace.INSTANCE_256.equals(mapSource.getMapSpace()); } @Override public void startAtlasCreation(AtlasInterface atlas, File customAtlasDir) throws IOException, InterruptedException, AtlasTestException { super.startAtlasCreation(atlas, customAtlasDir); File cacheFile = new File(atlasDir, "MTEFileCache"); OutputStream out = new BufferedOutputStream(new FileOutputStream(cacheFile), 8216); cacheOutStream = new DataOutputStream(out); } @Override public void abortAtlasCreation() throws IOException { Utilities.closeStream(cacheOutStream); super.abortAtlasCreation(); } @Override public void finishAtlasCreation() throws IOException, InterruptedException { super.finishAtlasCreation(); cacheOutStream.close(); } @Override public void initializeMap(MapInterface map, TileProvider mapTileProvider) { super.initializeMap(map, mapTileProvider); } public void createMap() throws MapCreationException, InterruptedException { if (mapSource.getTileImageType() != TileImageType.PNG) // If the tile image format is not png we have to convert it mapDlTileProvider = new ConvertedRawTileProvider(mapDlTileProvider, TileImageFormat.PNG); createTiles(); } protected void createTiles() throws InterruptedException, MapCreationException { atlasProgress.initMapCreation((xMax - xMin + 1) * (yMax - yMin + 1)); ImageIO.setUseCache(false); String mapName = map.getMapSource().getName().replaceAll(" ", "_"); for (int x = xMin; x <= xMax; x++) { for (int y = yMin; y <= yMax; y++) { checkUserAbort(); atlasProgress.incMapCreationProgress(); try { byte[] sourceTileData = mapDlTileProvider.getTileData(x, y); if (sourceTileData != null) writeTile(mapName, sourceTileData, x, y, zoom); } catch (IOException e) { throw new MapCreationException("Error writing tile image: " + e.getMessage(), map, e); } } } } protected boolean writeTile(String cache, byte[] tileData, int x, int y, int zoom) throws IOException { String url = "not used"; String cacheKey = cache + "-" + zoom + "-" + x + "-" + y; if (availableTileList.contains(cacheKey)) { log.warn("Map tile already in cache: " + cacheKey + " -> ignoring"); return false; } cacheOutStream.writeInt(x); cacheOutStream.writeInt(y); cacheOutStream.writeInt(zoom); byte[] urlBytes = url.getBytes(); cacheOutStream.writeShort(urlBytes.length); cacheOutStream.write(urlBytes); byte[] keyBytes = cacheKey.getBytes(); cacheOutStream.writeShort(keyBytes.length); cacheOutStream.write(keyBytes); cacheOutStream.writeLong(lastTileOffset); lastTileOffset += 12 + // x, y and z 2 + urlBytes.length + // strings and their lengths 2 + keyBytes.length + 8 + // tile offset (long) 4 + // image byte array length (int) tileData.length; cacheOutStream.writeInt(tileData.length); cacheOutStream.write(tileData); return true; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/CacheWolf.java0000644000175000017500000001261012122526606031257 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import mobac.exceptions.MapCreationException; import mobac.program.annotations.AtlasCreatorName; import mobac.program.annotations.SupportedParameters; import mobac.program.atlascreators.impl.MapTileBuilder; import mobac.program.atlascreators.impl.MapTileWriter; import mobac.program.atlascreators.tileprovider.CacheTileProvider; import mobac.program.atlascreators.tileprovider.TileProvider; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSpace; import mobac.program.model.TileImageParameters.Name; import mobac.utilities.Utilities; @AtlasCreatorName("CacheWolf (WFL)") @SupportedParameters(names = { Name.format, Name.height, Name.width }) public class CacheWolf extends Ozi { @Override public void initializeMap(MapInterface map, TileProvider mapTileProvider) { super.initializeMap(map, mapTileProvider); } @Override public void createMap() throws MapCreationException, InterruptedException { try { Utilities.mkDirs(layerDir); } catch (IOException e1) { throw new MapCreationException(map, e1); } if (parameters == null) { // One image per map super.createTiles(); writeWflFile(); } else // Use automatic tiling as specified in the parameters createTiles(); } @Override protected void createTiles() throws InterruptedException, MapCreationException { MapTileWriter mapTileWriter; CacheTileProvider ctp = new CacheTileProvider(mapDlTileProvider); try { mapDlTileProvider = ctp; mapTileWriter = new CWFileTileWriter(); MapTileBuilder mapTileBuilder = new MapTileBuilder(this, mapTileWriter, true); atlasProgress.initMapCreation(mapTileBuilder.getCustomTileCount()); mapTileBuilder.createTiles(); } catch (IOException e) { throw new MapCreationException(map, e); } finally { ctp.cleanup(); } } private void writeWflFile() throws MapCreationException { int width = (xMax - xMin + 1) * tileSize; int height = (yMax - yMin + 1) * tileSize; try { writeWflFile(mapName, 0, 0, width, height); } catch (IOException e) { throw new MapCreationException("Error writing wfl file: " + e.getMessage(), map, e); } } private void writeWflFile(String filename, int tilex, int tiley, int width, int height) throws IOException { FileOutputStream fout = null; try { fout = new FileOutputStream(new File(layerDir, filename + ".wfl")); OutputStreamWriter mapWriter = new OutputStreamWriter(fout, TEXT_FILE_CHARSET); MapSpace mapSpace = mapSource.getMapSpace(); int xStart = xMin * tileSize; int yStart = yMin * tileSize; if (parameters != null) { xStart += tilex * parameters.getWidth(); yStart += tiley * parameters.getHeight(); } double topLeftLon = mapSpace.cXToLon(xStart, zoom); double topLeftLat = mapSpace.cYToLat(yStart, zoom); double bottomRightLon = mapSpace.cXToLon(xStart + width, zoom); double bottomRightLat = mapSpace.cYToLat(yStart + height, zoom); double[] affine = { 0, 0, 0, 0 }; // Mobile Atlas Creator does only output maps with north at top // (no rotation). Therefore we should be able to simplify the affine // calculation process: affine[1] = (bottomRightLon - topLeftLon) / width; affine[2] = (bottomRightLat - topLeftLat) / height; for (double d : affine) mapWriter.write(Double.toString(d) + "\n"); mapWriter.write(Double.toString(topLeftLat) + "\n"); mapWriter.write(Double.toString(topLeftLon) + "\n"); mapWriter.write(Double.toString(bottomRightLat) + "\n"); mapWriter.write(Double.toString(bottomRightLon) + "\n"); mapWriter.flush(); mapWriter.close(); } finally { Utilities.closeStream(fout); } } public class CWFileTileWriter implements MapTileWriter { public CWFileTileWriter() throws IOException { super(); log.debug("Writing tiles to set folder: " + layerDir); } public void writeTile(int tilex, int tiley, String imageFormat, byte[] tileData) throws IOException { String tileFileName = String.format("%s_%dx%d", mapName, tilex, tiley); File f = new File(layerDir, tileFileName + '.' + imageFormat); FileOutputStream out = new FileOutputStream(f); try { out.write(tileData); } finally { Utilities.closeStream(out); } writeWflFile(tileFileName, tilex, tiley, parameters.getWidth(), parameters.getHeight()); } public void finalizeMap() { } } } ././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/BackCountryNavigator.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/BackCountryNavigator.jav0000644000175000017500000000233512171650636033372 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import mobac.program.annotations.AtlasCreatorName; /** * Creates maps using the BCNav SQLite atlas format. * * * @see http://www.backcountrynavigator.com */ @AtlasCreatorName("BackCountry Navigator (SQLite)") public class BackCountryNavigator extends RMapsSQLite { public BackCountryNavigator() { super(); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/impl/0000755000175000017500000000000012127544344027526 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/impl/MapTileBuilder.java0000644000175000017500000002214112127544344033233 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators.impl; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; import javax.imageio.ImageIO; import mobac.exceptions.MapCreationException; import mobac.program.atlascreators.AtlasCreator; import mobac.program.atlascreators.tileprovider.TileProvider; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.TileImageDataWriter; import mobac.program.model.TileImageParameters; import mobac.utilities.MyMath; import org.apache.log4j.Logger; public class MapTileBuilder { private static final Logger log = Logger.getLogger(MapTileBuilder.class); private final AtlasCreator atlasCreator; private final TileProvider mapDlTileProvider; private final MapInterface map; private final MapSource mapSource; private final TileImageParameters parameters; private final TileImageDataWriter tileImageDataWriter; private final int tileSize; private final int xMin; private final int xMax; private final int yMin; private final int yMax; private final boolean useRealTileSize; private int realWidth; private int realHeight; int mergedWidth; int mergedHeight; final int customTileCount; final int xStart; final int yStart; final int xEnd; final int yEnd; protected final MapTileWriter mapTileWriter; /** * @param atlasCreator * @param mapTileWriter * @param useRealTileSize * affects the tile size at the left and bottom border of the map. If true those tile will * have the size of the remaining image data available size (they can be smaller than the size * specified). If false the tile size will be as specified by the map's * {@link TileImageParameters}. */ public MapTileBuilder(AtlasCreator atlasCreator, MapTileWriter mapTileWriter, boolean useRealTileSize) { this(atlasCreator, atlasCreator.getParameters().getFormat().getDataWriter(), mapTileWriter, useRealTileSize); } /** * * @param atlasCreator * @param tileImageDataWriter * @param mapTileWriter * @param useRealTileSize * affects the tile size at the left and bottom border of the map. If true those tile will * have the size of the remaining image data available size (they can be smaller than the size * specified). If false the tile size will be as specified by the map's * {@link TileImageParameters}. */ public MapTileBuilder(AtlasCreator atlasCreator, TileImageDataWriter tileImageDataWriter, MapTileWriter mapTileWriter, boolean useRealTileSize) { this.atlasCreator = atlasCreator; this.tileImageDataWriter = tileImageDataWriter; this.mapTileWriter = mapTileWriter; this.mapDlTileProvider = atlasCreator.getMapDlTileProvider(); this.useRealTileSize = useRealTileSize; map = atlasCreator.getMap(); mapSource = map.getMapSource(); tileSize = mapSource.getMapSpace().getTileSize(); xMax = atlasCreator.getXMax(); xMin = atlasCreator.getXMin(); yMax = atlasCreator.getYMax(); yMin = atlasCreator.getYMin(); parameters = atlasCreator.getParameters(); // left upper point on the map in pixels // regarding the current zoom level xStart = xMin * tileSize; yStart = yMin * tileSize; // lower right point on the map in pixels // regarding the current zoom level xEnd = xMax * tileSize + (tileSize - 1); yEnd = yMax * tileSize + (tileSize - 1); mergedWidth = xEnd - xStart + 1; mergedHeight = yEnd - yStart + 1; realWidth = parameters.getWidth(); realHeight = parameters.getHeight(); if (useRealTileSize) { // Reduce tile size of overall map height/width // if it is smaller than one tile if (realWidth > mergedWidth) realWidth = mergedWidth; if (realHeight > mergedHeight) realHeight = mergedHeight; } customTileCount = MyMath.divCeil(mergedWidth, realWidth) * MyMath.divCeil(mergedHeight, realHeight); } public void createTiles() throws MapCreationException, InterruptedException { // Absolute positions int xAbsPos = xStart; int yAbsPos = yStart; log.trace("tile size: " + realWidth + " * " + realHeight); log.trace("X: from " + xStart + " to " + xEnd); log.trace("Y: from " + yStart + " to " + yEnd); // We don't work with large images, therefore we can disable the (file) // cache of ImageIO. This will speed up the creation process a bit ImageIO.setUseCache(false); ByteArrayOutputStream buf = new ByteArrayOutputStream(32768); tileImageDataWriter.initialize(); int currentTileHeight = realHeight; int currentTileWidth = realWidth; try { String tileType = tileImageDataWriter.getType().getFileExt(); int tiley = 0; while (yAbsPos < yEnd) { int tilex = 0; xAbsPos = xStart; if (useRealTileSize) currentTileHeight = Math.min(realHeight, yEnd - yAbsPos + 1); while (xAbsPos < xEnd) { if (useRealTileSize) currentTileWidth = Math.min(realWidth, xEnd - xAbsPos + 1); atlasCreator.checkUserAbort(); atlasCreator.getAtlasProgress().incMapCreationProgress(); BufferedImage tileImage = new BufferedImage(currentTileWidth, currentTileHeight, BufferedImage.TYPE_3BYTE_BGR); buf.reset(); try { Graphics2D graphics = tileImage.createGraphics(); prepareTile(graphics); paintCustomTile(graphics, xAbsPos, yAbsPos); graphics.dispose(); tileImageDataWriter.processImage(tileImage, buf); mapTileWriter.writeTile(tilex, tiley, tileType, buf.toByteArray()); } catch (IOException e) { throw new MapCreationException("Error writing tile image: " + e.getMessage(), map, e); } tilex++; xAbsPos += realWidth; } tiley++; yAbsPos += realHeight; } } finally { tileImageDataWriter.dispose(); } } protected void prepareTile(Graphics2D graphics) { graphics.setColor(mapSource.getBackgroundColor()); graphics.fillRect(0, 0, realWidth, realHeight); } /** * Paints the graphics of the custom tile specified by the pixel coordinates xAbsPos and * yAbsPos on the currently selected map & layer. * * @param graphics * @param xAbsPos * @param yAbsPos */ private void paintCustomTile(Graphics2D graphics, int xAbsPos, int yAbsPos) { int xTile = xAbsPos / tileSize; int xTileOffset = -(xAbsPos % tileSize); for (int x = xTileOffset; x < realWidth; x += tileSize) { int yTile = yAbsPos / tileSize; int yTileOffset = -(yAbsPos % tileSize); for (int y = yTileOffset; y < realHeight; y += tileSize) { try { BufferedImage orgTileImage = loadOriginalMapTile(xTile, yTile); if (orgTileImage != null) { //int w = orgTileImage.getWidth(); //int h = orgTileImage.getHeight(); graphics.drawImage(orgTileImage, xTileOffset, yTileOffset, tileSize, tileSize, null); } } catch (Exception e) { log.error("Error while painting sub-tile", e); } yTile++; yTileOffset += tileSize; } xTile++; xTileOffset += tileSize; } } public int getCustomTileCount() { return customTileCount; } /** * A simple local cache holding the last 10 loaded original tiles. If the custom tile size is smaller than 256x256 * the efficiency of this cache is very high (~ 75% hit rate). */ private CachedTile[] cache = new CachedTile[10]; private int cachePos = 0; private BufferedImage loadOriginalMapTile(int xTile, int yTile) throws Exception { for (CachedTile ct : cache) { if (ct == null) continue; if (ct.xTile == xTile && ct.yTile == yTile) { // log.trace("cache hit"); return ct.image; } } // log.trace("cache miss"); BufferedImage image = mapDlTileProvider.getTileImage(xTile, yTile); if (image == null) return null; cache[cachePos] = new CachedTile(image, xTile, yTile); cachePos = (cachePos + 1) % cache.length; return image; } private static class CachedTile { BufferedImage image; int xTile; int yTile; public CachedTile(BufferedImage image, int tile, int tile2) { super(); this.image = image; xTile = tile; yTile = tile2; } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/impl/aqm/0000755000175000017500000000000012122526606030300 5ustar paulliupaulliu././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/impl/aqm/FlatPackCreator.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/impl/aqm/FlatPackCreator0000644000175000017500000001166012122526606033234 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators.impl.aqm; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import mobac.utilities.Charsets; import mobac.utilities.Utilities; public class FlatPackCreator { public static final String FLAT_PACK_HEADER = "FLATPACK1"; public static final int FILE_COPY_BUFFER_LEN = 4096 * 10; private String packPath = null; private FileOutputStream dataStream = null; private ByteArrayOutputStream structBuffer = null; private OutputStreamWriter structBufferWriter = null; private long currentDataWritedSize = 0; private long currentNbFiles = 0; public FlatPackCreator(final File packPath) throws FileNotFoundException { this(packPath.getAbsolutePath()); } public FlatPackCreator(final String packPath) throws FileNotFoundException { this.packPath = packPath; if (packPath == null) throw new NullPointerException("Pack file path is null."); dataStream = new FileOutputStream(packPath + ".tmp"); structBuffer = new ByteArrayOutputStream(); structBufferWriter = new OutputStreamWriter(structBuffer, Charsets.ISO_8859_1); currentDataWritedSize = 0; currentNbFiles = 0; } public final void add(final String filePath, final String fileEntryName) throws IOException { add(new File(filePath), fileEntryName); } public final void add(final File filePath) throws IOException { add(filePath, filePath.getName()); } public final void add(final File filePath, final String fileEntryName) throws IOException { // read file content FileInputStream in = new FileInputStream(filePath); byte[] buff = new byte[(int) filePath.length()]; int read = in.read(buff); in.close(); if (filePath.length() != read) throw new IOException("Error reading '" + filePath + "'."); add(buff, fileEntryName); } public final void add(final byte[] buff, final String fileEntryName) throws IOException { if (dataStream == null) throw new IOException("Write stream is null."); // write file size String fileSize = Integer.toString(buff.length) + "\0"; dataStream.write(fileSize.getBytes(Charsets.ISO_8859_1)); // write file into pack data if (buff.length > 0) dataStream.write(buff); // write file into pack structure structBufferWriter.append(fileEntryName + "\0" + currentDataWritedSize + "\0"); // update writed size currentDataWritedSize += buff.length + fileSize.length(); currentNbFiles++; } public final void close() throws IOException { if (dataStream == null) throw new NullPointerException("Write stream is null."); // close data file dataStream.flush(); dataStream.close(); dataStream = null; File tmpFile = new File(packPath + ".tmp"); // open pack file FileOutputStream packStream = new FileOutputStream(packPath); try { String nbFiles = Long.toString(currentNbFiles) + "\0"; // write header packStream.write(FLAT_PACK_HEADER.getBytes(Charsets.ISO_8859_1)); // write struct structBufferWriter.flush(); structBufferWriter.close(); int headerSize = structBuffer.size() + nbFiles.length(); packStream.write(Integer.toString(headerSize).getBytes(Charsets.ISO_8859_1)); packStream.write('\0'); packStream.write(nbFiles.getBytes(Charsets.ISO_8859_1)); structBuffer.writeTo(packStream); // Free memory structBufferWriter = null; structBuffer = null; // write data FileInputStream in = new FileInputStream(tmpFile); try { byte[] buffer = new byte[FILE_COPY_BUFFER_LEN]; int read; while ((read = in.read(buffer)) > 0) packStream.write(buffer, 0, read); packStream.flush(); packStream.close(); } finally { Utilities.closeStream(in); } } finally { Utilities.closeStream(packStream); } // delete temp file if (tmpFile.isFile()) Utilities.deleteFile(tmpFile); // reset state packPath = null; structBuffer = null; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/impl/MapTileWriter.java0000644000175000017500000000273412122526606033123 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators.impl; import java.io.IOException; public interface MapTileWriter { /** * * @param tilex * x tile number regarding regarding the currently processed map * (0..mapWidth / tileWidth)] * @param tiley * y tile number regarding regarding the currently processed map * (0..mapheight / tileHeight)] * @param tileType * @param tileData * @throws IOException */ public void writeTile(int tilex, int tiley, String tileType, byte[] tileData) throws IOException; public void finalizeMap() throws IOException; } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/impl/gemf/0000755000175000017500000000000012122526606030440 5ustar paulliupaulliu././@LongLink0000000000000000000000000000015300000000000011564 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/impl/gemf/GEMFFileCreator.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/impl/gemf/GEMFFileCreato0000644000175000017500000002755112122526606033051 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ /** * */ package mobac.program.atlascreators.impl.gemf; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.TreeSet; import org.apache.log4j.Logger; /** * GEMF File creator class. * * Reference about GEMF format: https://sites.google.com/site/abudden/android-map-store * * @author A. S. Budden * @author Erik Burrows * * This class is a stripped-down version of the GEMFFile.java class at: * http://code.google.com/p/osmdroid/source/ * browse/trunk/osmdroid-android/src/main/java/org/osmdroid/util/GEMFFile.java * * (Date: Wed, 11th of April 2012) * * The original GEMFFile.java from above has been reduced to the functionality of writing a GEMF archive, as * reading the archive seems not to be necessary. * * @author M. Reiter * */ public class GEMFFileCreator { private static final long FILE_SIZE_LIMIT = 1 * 1024 * 1024 * 1024; // 1GB private static final int FILE_COPY_BUFFER_SIZE = 1024; private static final int VERSION = 4; private static final int TILE_SIZE = 256; private static final int U32_SIZE = 4; private static final int U64_SIZE = 8; /* * Constructor to create new GEMF file from directory of sources/tiles. * * @param pLocation String object representing path to first GEMF archive file. Additional files (if archive size * exceeds FILE_SIZE_LIMIT will be created with numerical suffixes, eg: test.gemf-1, test.gemf-2. * * @param pSourceFolders Each specified folder will be imported into the GEMF archive as a seperate source. The name * of the folder will be the name of the source in the archive. */ public GEMFFileCreator(final String pLocation, final List pSourceFolders, Logger log) throws FileNotFoundException, IOException { /** *

		 * 1. For each source folder
		 *   1. Create array of zoom levels, X rows, Y rows
		 * 2. Build index data structure index[source][zoom][range]
		 *   1. For each S-Z-X find list of Ys values
		 *   2. For each S-Z-X-Ys set, find complete X ranges
		 *   3. For each S-Z-Xr-Ys set, find complete Y ranges, create Range record
		 * 3. Write out index
		 *   1. Header
		 *   2. Sources
		 *   3. For each Range
		 *     1. Write Range record
		 * 4. For each Range record
		 *   1. For each Range entry
		 *     1. If over file size limit, start new data file
		 *   2. Write tile data
		 * 
*/ // this.mLocation = pLocation; // Create in-memory array of sources, X and Y values. final LinkedHashMap>>> dirIndex = new LinkedHashMap>>>(); for (final File sourceDir : pSourceFolders) { final LinkedHashMap>> zList = new LinkedHashMap>>(); for (final File zDir : sourceDir.listFiles()) { // Make sure the directory name is just a number try { Integer.parseInt(zDir.getName()); } catch (final NumberFormatException e) { continue; } final LinkedHashMap> xList = new LinkedHashMap>(); for (final File xDir : zDir.listFiles()) { // Make sure the directory name is just a number try { Integer.parseInt(xDir.getName()); } catch (final NumberFormatException e) { continue; } final LinkedHashMap yList = new LinkedHashMap(); for (final File yFile : xDir.listFiles()) { try { Integer.parseInt(yFile.getName().substring(0, yFile.getName().indexOf('.'))); } catch (final NumberFormatException e) { continue; } yList.put(Integer.parseInt(yFile.getName().substring(0, yFile.getName().indexOf('.'))), yFile); } xList.put(new Integer(xDir.getName()), yList); } zList.put(Integer.parseInt(zDir.getName()), xList); } dirIndex.put(sourceDir.getName(), zList); } // Create a source index list final LinkedHashMap sourceIndex = new LinkedHashMap(); final LinkedHashMap indexSource = new LinkedHashMap(); int si = 0; for (final String source : dirIndex.keySet()) { sourceIndex.put(source, new Integer(si)); indexSource.put(new Integer(si), source); ++si; } // Create the range objects final List ranges = new ArrayList(); for (final String source : dirIndex.keySet()) { for (final Integer zoom : dirIndex.get(source).keySet()) { // Get non-contiguous Y sets for each Z/X final LinkedHashMap, List> ySets = new LinkedHashMap, List>(); for (final Integer x : new TreeSet(dirIndex.get(source).get(zoom).keySet())) { final List ySet = new ArrayList(); for (final Integer y : dirIndex.get(source).get(zoom).get(x).keySet()) { ySet.add(y); } if (ySet.size() == 0) { continue; } Collections.sort(ySet); if (!ySets.containsKey(ySet)) { ySets.put(ySet, new ArrayList()); } ySets.get(ySet).add(x); } // For each Y set find contiguous X sets final LinkedHashMap, List> xSets = new LinkedHashMap, List>(); for (final List ySet : ySets.keySet()) { final TreeSet xList = new TreeSet(ySets.get(ySet)); List xSet = new ArrayList(); for (int i = xList.first(); i < xList.last() + 1; ++i) { if (xList.contains(new Integer(i))) { xSet.add(new Integer(i)); } else { if (xSet.size() > 0) { xSets.put(ySet, xSet); xSet = new ArrayList(); } } } if (xSet.size() > 0) { xSets.put(ySet, xSet); } } // For each contiguous X set, find contiguous Y sets and create GEMFRange object for (final List xSet : xSets.keySet()) { final TreeSet yList = new TreeSet(xSet); final TreeSet xList = new TreeSet(ySets.get(xSet)); GEMFRange range = new GEMFRange(); range.zoom = zoom; range.sourceIndex = sourceIndex.get(source); range.xMin = xList.first(); range.xMax = xList.last(); for (int i = yList.first(); i < yList.last() + 1; ++i) { if (yList.contains(new Integer(i))) { if (range.yMin == null) { range.yMin = i; } range.yMax = i; } else { if (range.yMin != null) { ranges.add(range); range = new GEMFRange(); range.zoom = zoom; range.sourceIndex = sourceIndex.get(source); range.xMin = xList.first(); range.xMax = xList.last(); } } } if (range.yMin != null) { ranges.add(range); } } } } // Calculate size of header for computation of data offsets int source_list_size = 0; for (final String source : sourceIndex.keySet()) { source_list_size += (U32_SIZE + U32_SIZE + source.length()); } long offset = U32_SIZE + // GEMF Version U32_SIZE + // Tile size U32_SIZE + // Number of sources source_list_size + ranges.size() * ((U32_SIZE * 6) + U64_SIZE) + U32_SIZE; // Number of ranges // Calculate offset for each range in the data set for (final GEMFRange range : ranges) { range.offset = offset; for (int x = range.xMin; x < range.xMax + 1; ++x) { for (int y = range.yMin; y < range.yMax + 1; ++y) { offset += (U32_SIZE + U64_SIZE); } } } final long headerSize = offset; RandomAccessFile gemfFile = new RandomAccessFile(pLocation, "rw"); // Write version header gemfFile.writeInt(VERSION); // Write file size header gemfFile.writeInt(TILE_SIZE); // Write number of sources gemfFile.writeInt(sourceIndex.size()); // Write source list for (final String source : sourceIndex.keySet()) { gemfFile.writeInt(sourceIndex.get(source)); gemfFile.writeInt(source.length()); gemfFile.write(source.getBytes()); } // Write number of ranges gemfFile.writeInt(ranges.size()); // Write range objects for (final GEMFRange range : ranges) { gemfFile.writeInt(range.zoom); gemfFile.writeInt(range.xMin); gemfFile.writeInt(range.xMax); gemfFile.writeInt(range.yMin); gemfFile.writeInt(range.yMax); gemfFile.writeInt(range.sourceIndex); gemfFile.writeLong(range.offset); } // Write file offset list for (final GEMFRange range : ranges) { for (int x = range.xMin; x < range.xMax + 1; ++x) { for (int y = range.yMin; y < range.yMax + 1; ++y) { gemfFile.writeLong(offset); long fileSize = 0; try { fileSize = dirIndex.get(indexSource.get(range.sourceIndex)).get(range.zoom).get(x).get(y).length(); } catch (NullPointerException e) { //dont' do anything here. Error will be logged later. } gemfFile.writeInt((int) fileSize); offset += fileSize; } } } // // Write tiles // final byte[] buf = new byte[FILE_COPY_BUFFER_SIZE]; long currentOffset = headerSize; int fileIndex = 0; for (final GEMFRange range : ranges) { for (int x = range.xMin; x < range.xMax + 1; ++x) { for (int y = range.yMin; y < range.yMax + 1; ++y) { long fileSize = 0; try { fileSize = dirIndex.get(indexSource.get(range.sourceIndex)).get(range.zoom).get(x).get(y).length(); } catch (NullPointerException e) { //don't do anything here. Error will be logged later. } if (currentOffset + fileSize > FILE_SIZE_LIMIT) { gemfFile.close(); ++fileIndex; gemfFile = new RandomAccessFile(pLocation + "-" + fileIndex, "rw"); currentOffset = 0; } else { currentOffset += fileSize; } try { final FileInputStream tile = new FileInputStream(dirIndex.get(indexSource.get(range.sourceIndex)).get(range.zoom).get(x).get(y)); int read = tile.read(buf, 0, FILE_COPY_BUFFER_SIZE); while (read != -1) { gemfFile.write(buf, 0, read); read = tile.read(buf, 0, FILE_COPY_BUFFER_SIZE); } tile.close(); } catch (Exception e) { log.warn("Please check that all required Tiles have been downloaded correctly. I am missing tile for x=" + x + ", y=" + y + ", z=" + range.zoom); } } } } gemfFile.close(); // Complete construction of GEMFFile object // openFiles(); // readHeader(); } // Class to represent a range of stored tiles within the archive. private class GEMFRange { Integer zoom; Integer xMin; Integer xMax; Integer yMin; Integer yMax; Integer sourceIndex; Long offset; @Override public String toString() { return String.format("GEMF Range: source=%d, zoom=%d, x=%d-%d, y=%d-%d, offset=0x%08X", sourceIndex, zoom, xMin, xMax, yMin, yMax, offset); } }; } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/impl/rmp/0000755000175000017500000000000012122526606030320 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/impl/rmp/MobacTile.java0000644000175000017500000001344612122526606033032 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators.impl.rmp; import java.awt.Color; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.awt.image.WritableRaster; import java.io.IOException; import mobac.program.atlascreators.tileprovider.TileProvider; import mobac.program.interfaces.MapSpace; import org.apache.log4j.Logger; public class MobacTile { private static final Logger log = Logger.getLogger(MobacTile.class); private final TileProvider tileProvider; private final int tilex; private final int tiley; private BufferedImage image; private BoundingRect boundingRect; public MobacTile(TileProvider tileProvider, MapSpace mapSpace, int tilex, int tiley, int zoom) { this.tileProvider = tileProvider; this.tilex = tilex; this.tiley = tiley; image = null; int tileSize = mapSpace.getTileSize(); int x = tilex * tileSize; int y = tiley * tileSize; double north = mapSpace.cYToLat(y, zoom); double south = mapSpace.cYToLat(y + tileSize - 1, zoom); double west = mapSpace.cXToLon(x, zoom); double east = mapSpace.cXToLon(x + tileSize - 1, zoom); // north and south have to be negated - this really strange! boundingRect = new BoundingRect(-north, -south, west, east); } /** * Returns the image of the tile. Creates on if necessary */ public BufferedImage getImage() { /* --- Load image if none is present --- */ if (image == null) image = loadImage(); return image; } private BufferedImage loadImage() { try { image = tileProvider.getTileImage(tilex, tiley); } catch (IOException e) { log.error("", e); image = createBlack(256, 256); } return image; } /** * create a black Tile * * @return image of black square */ private BufferedImage createBlack(int width, int height) { BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics graph = img.getGraphics(); graph.setColor(Color.BLACK); graph.fillRect(0, 0, width, height); return img; } public void drawSubImage(BoundingRect dest_area, BufferedImage dest_image) { BufferedImage src_image; WritableRaster src_graph, dst_graph; BoundingRect src_area; int maxx, maxy; double src_c_x, src_c_y; int pix_x, pix_y; BufferedImage imageBuffer; Graphics graphics; int[] pixel = new int[3]; /* --- Get the coordination rectangle of the source image --- */ src_area = boundingRect; /* --- Get Graphics context --- */ src_image = getImage(); if (src_image == null) return; /* --- Convert it to RGB color space --- */ imageBuffer = new BufferedImage(src_image.getWidth(), src_image.getHeight(), BufferedImage.TYPE_INT_RGB); graphics = imageBuffer.createGraphics(); try { graphics.drawImage(src_image, 0, 0, null); } finally { graphics.dispose(); } src_graph = imageBuffer.getRaster(); dst_graph = dest_image.getRaster(); /* * --- Iterate over all pixels of the destination image. Unfortunately * we need this technique because source and dest do not have exactly * the same zoom level, so the source image has to be compressed or * expanded to match the destination image --- */ maxx = dest_image.getWidth(); maxy = dest_image.getHeight(); for (int y = 0; y < maxy; y++) { /* --- Calculate the y-coordinate of the current line --- */ src_c_y = dest_area.getNorth() + (dest_area.getSouth() - dest_area.getNorth()) * y / maxy; /* --- Calculate the pixel line of the source image --- */ pix_y = (int) ((src_c_y - src_area.getNorth()) * 256 / (src_area.getSouth() - src_area.getNorth()) + 0.5); /* --- Ignore line that are out of the source area --- */ if (pix_y < 0 || pix_y > 255) continue; // log.trace("scale factor y: " + (pix_y / (double) y)); for (int x = 0; x < maxx; x++) { /* --- Calculate the x-coordinate of the current row --- */ src_c_x = dest_area.getWest() + (dest_area.getEast() - dest_area.getWest()) * x / maxx; /* --- Calculate the pixel row of the source image --- */ pix_x = (int) ((src_c_x - src_area.getWest()) * 256 / (src_area.getEast() - src_area.getWest()) + 0.5); /* --- Ignore the row if it is outside the source area --- */ if (pix_x < 0 || pix_x > 255) continue; /* --- Transfer the pixel --- */ src_graph.getPixel(pix_x, pix_y, pixel); dst_graph.setPixel(x, y, pixel); } } } public int getImageHeight() { /* --- A tile is always 256 pixels high --- */ return 256; } public int getImageWidth() { /* --- A tile is always 256 pixels wide --- */ return 256; } public BufferedImage getSubImage(BoundingRect area, int width, int height) { BufferedImage result = createBlack(width, height); drawSubImage(area, result); return result; } @Override public String toString() { return String.format("MobacTile x/y [%d/%d] = %s", tilex, tiley, boundingRect); } } ././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/impl/rmp/BoundingRect.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/impl/rmp/BoundingRect.ja0000644000175000017500000000421612122526606033222 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ /* ********************************************* * Copyright: Andreas Sander * * * ********************************************* */ package mobac.program.atlascreators.impl.rmp; /** * Rectangle made from latitude/longitude coordinates. Negative latitude is to * the north and negative longitude is to the west. * * @author Andreas Sander * */ public class BoundingRect { private double north; private double south; private double west; private double east; /** * Constructor */ public BoundingRect(double north, double south, double west, double east) { this.north = north; this.south = south; this.west = west; this.east = east; } public double getNorth() { return north; } public void setNorth(double north) { this.north = north; } public double getSouth() { return south; } public void setSouth(double south) { this.south = south; } public double getWest() { return west; } public void setWest(double west) { this.west = west; } public double getEast() { return east; } public void setEast(double east) { this.east = east; } @Override public String toString() { return String.format("BoundingRect [N=%2.4f, S==%2.4f, W=%2.4f, E=%2.4f]", north, south, west, east); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/impl/rmp/RmpWriter.java0000644000175000017500000002033612122526606033122 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ /* ********************************************* * Copyright: Andreas Sander * * * ********************************************* */ package mobac.program.atlascreators.impl.rmp; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.io.RandomAccessFile; import java.util.ArrayList; import mobac.program.atlascreators.impl.rmp.interfaces.RmpFileEntry; import mobac.program.atlascreators.impl.rmp.rmpfile.RmpIni; import mobac.utilities.Utilities; import mobac.utilities.stream.CountingOutputStream; import mobac.utilities.stream.RandomAccessFileOutputStream; import org.apache.commons.io.output.NullOutputStream; import org.apache.log4j.Logger; /** * Class that writes files in RMP archive format * */ public class RmpWriter { /** * Max file size: 2147483647 bytes = 2047,99 MiB */ public static final long MAX_FILE_SIZE = 0xffffffffl; private static final Logger log = Logger.getLogger(RmpWriter.class); private final ArrayList entries = new ArrayList(); private final File rmpFile; private final RandomAccessFile rmpOutputFile; private int projectedEntryCount; private ChecksumOutputStream entryOut; /** * @param imageName * @param layerCount * projected number of layers that will be written to this rmp file * @param rmpFile * @throws IOException * @throws InterruptedException */ public RmpWriter(String imageName, int layerCount, File rmpFile) throws IOException, InterruptedException { this.rmpFile = rmpFile; // We only use one A00 entry per map/layer - therefore we can // pre-calculate the number of entries: // RmpIni + (TLM & A00) per layer + Bmp2Bit + Bmp4bit this.projectedEntryCount = (3 + (2 * layerCount)); if (rmpFile.exists()) Utilities.deleteFile(rmpFile); log.debug("Writing data to " + rmpFile.getAbsolutePath()); rmpOutputFile = new RandomAccessFile(rmpFile, "rw"); // Calculate offset to the directory end int directoryEndOffset = projectedEntryCount * 24 + 10; rmpOutputFile.seek(directoryEndOffset); entryOut = new ChecksumOutputStream(new RandomAccessFileOutputStream(rmpOutputFile)); /* --- Write the directory-end marker --- */ RmpTools.writeFixedString(entryOut, "MAGELLAN", 30); RmpIni rmpIni = new RmpIni(imageName, layerCount); /* --- Create packer and fill it with content --- */ writeFileEntry(rmpIni); } public void writeFileEntry(RmpFileEntry entry) throws IOException, InterruptedException { EntryInfo info = new EntryInfo(); info.name = entry.getFileName(); info.extendsion = entry.getFileExtension(); info.offset = rmpOutputFile.getFilePointer(); entry.writeFileContent(entryOut); info.length = rmpOutputFile.getFilePointer() - info.offset; if ((info.length % 2) != 0) entryOut.write(0); entries.add(info); if (rmpOutputFile.getFilePointer() > MAX_FILE_SIZE) throwRmpTooLarge(); log.debug("Written data of entry " + entry + " bytes=" + info.length); } public void prepareFileEntry(RmpFileEntry entry) throws IOException, InterruptedException { EntryInfo info = new EntryInfo(); info.name = entry.getFileName(); info.extendsion = entry.getFileExtension(); long pos = rmpOutputFile.getFilePointer(); info.offset = pos; CountingOutputStream cout = new CountingOutputStream(new NullOutputStream()); entry.writeFileContent(cout); info.length = cout.getBytesWritten(); long newPos = pos + info.length; if ((info.length % 2) != 0) newPos++; if (newPos > MAX_FILE_SIZE) throwRmpTooLarge(); rmpOutputFile.seek(newPos); entries.add(info); log.debug("Prepared data of entry " + entry + " bytes=" + info.length); } public void writePreparedFileEntry(RmpFileEntry entry) throws IOException, InterruptedException { long pos = rmpOutputFile.getFilePointer(); EntryInfo info = new EntryInfo(); info.name = entry.getFileName(); info.extendsion = entry.getFileExtension(); int index = entries.indexOf(info); if (index < 0) throw new RuntimeException("Index for entry not found"); info = entries.get(index); rmpOutputFile.seek(info.offset); entry.writeFileContent(entryOut); if (rmpOutputFile.getFilePointer() > MAX_FILE_SIZE) throwRmpTooLarge(); long newLength = rmpOutputFile.getFilePointer() - info.offset; if (newLength != info.length) throw new RuntimeException("Length of entry has changed!"); if ((newLength % 2) != 0) entryOut.write(0); // restore old file position rmpOutputFile.seek(pos); } private void throwRmpTooLarge() throws IOException { throw new IOException("RMP file size exeeds 2GiB! The RMP file format does not support that."); } /** * Writes the directory of the archive into the rmp file * * @throws IOException * Error accessing disk */ public void writeDirectory() throws IOException { if (projectedEntryCount != entries.size()) throw new RuntimeException("Entry count does not correspond " + "to the projected layer count: \nProjected: " + projectedEntryCount + "\nPresent:" + entries.size()); // Finalize the list of written entries RmpTools.writeFixedString(entryOut, "MAGELLAN", 8); entryOut.writeChecksum(); log.debug("Finished writing entries, updating directory"); /* --- Create file --- */ rmpOutputFile.seek(0); OutputStream out = new RandomAccessFileOutputStream(rmpOutputFile); ChecksumOutputStream cout = new ChecksumOutputStream(out); /* --- Write header with number of files --- */ RmpTools.writeValue(cout, entries.size(), 4); RmpTools.writeValue(cout, entries.size(), 4); /* --- Write the directory --- */ log.debug("Writing directory: " + entries.size() + " entries"); for (EntryInfo entryInfo : entries) { log.trace("Entry: " + entryInfo); /* --- Write directory entry --- */ RmpTools.writeFixedString(cout, entryInfo.name, 9); RmpTools.writeFixedString(cout, entryInfo.extendsion, 7); RmpTools.writeValue(cout, entryInfo.offset, 4); RmpTools.writeValue(cout, entryInfo.length, 4); } /* --- Write the header checksum (2 bytes) --- */ cout.writeChecksum(); } public void close() { try { rmpOutputFile.close(); } catch (Exception e) { log.error("", e); } } public void delete() throws IOException { close(); Utilities.deleteFile(rmpFile); } private static class EntryInfo { String name; String extendsion; long offset; long length; @Override public String toString() { return "\"" + name + "." + extendsion + "\" offset=" + offset + " length=" + length; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((extendsion == null) ? 0 : extendsion.hashCode()); result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; EntryInfo other = (EntryInfo) obj; if (extendsion == null) { if (other.extendsion != null) return false; } else if (!extendsion.equals(other.extendsion)) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/impl/rmp/MultiImage.java0000644000175000017500000000757412122526606033235 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators.impl.rmp; import java.awt.Color; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import mobac.exceptions.MapCreationException; import mobac.program.atlascreators.tileprovider.TileProvider; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSpace; import mobac.utilities.collections.SoftHashMap; import org.apache.log4j.Logger; /** * CalibratedImage that gets its data from a set of other CalibratedImage2 * */ public class MultiImage { private static final Logger log = Logger.getLogger(MultiImage.class); private final MapInterface map; private final MapSource mapSource; private final int zoom; private final TileProvider tileProvider; private SoftHashMap cache; public MultiImage(MapSource mapSource, TileProvider tileProvider, MapInterface map) { this.mapSource = mapSource; this.tileProvider = tileProvider; this.zoom = map.getZoom(); this.map = map; cache = new SoftHashMap(400); } public BufferedImage getSubImage(BoundingRect area, int width, int height) throws MapCreationException { if (log.isTraceEnabled()) log.trace(String.format("getSubImage %d %d %s", width, height, area)); MapSpace mapSpace = mapSource.getMapSpace(); int tilesize = mapSpace.getTileSize(); int xMax = mapSource.getMapSpace().cLonToX(area.getEast(), zoom) / tilesize; int xMin = mapSource.getMapSpace().cLonToX(area.getWest(), zoom) / tilesize; int yMax = mapSource.getMapSpace().cLatToY(-area.getSouth(), zoom) / tilesize; int yMin = mapSource.getMapSpace().cLatToY(-area.getNorth(), zoom) / tilesize; BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D graph = result.createGraphics(); try { graph.setColor(Color.WHITE); graph.fillRect(0, 0, width, height); for (int x = xMin; x <= xMax; x++) { for (int y = yMin; y <= yMax; y++) { TileKey key = new TileKey(x, y); MobacTile image = cache.get(key); if (image == null) { image = new MobacTile(tileProvider, mapSpace, x, y, zoom); cache.put(key, image); } image.drawSubImage(area, result); } } } catch (Throwable t) { throw new MapCreationException(map, t); } finally { graph.dispose(); } return result; } protected static class TileKey { int x; int y; public TileKey(int x, int y) { this.x = x; this.y = y; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + x; result = prime * result + y; return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; TileKey other = (TileKey) obj; if (x != other.x) return false; if (y != other.y) return false; return true; } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/impl/rmp/RmpTools.java0000644000175000017500000001056312122526606032747 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ /* ********************************************* * Copyright: Andreas Sander * * * ********************************************* */ package mobac.program.atlascreators.impl.rmp; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.OutputStream; public class RmpTools { /** * Copies the given value into the stream as binary value, with least * significant byte first. * * @param stream * stream to write to * @param value * value to write * @param length * number of bytes to write to stream * @throws IOException */ public static void writeValue(OutputStream stream, int value, int length) throws IOException { int i; for (i = 0; i < length; i++) { stream.write(value & 0xFF); value >>= 8; } } public static void writeValue(OutputStream stream, long value, int length) throws IOException { int i; for (i = 0; i < length; i++) { stream.write((int)(value & 0xFF)); value >>= 8; } } /** * Writes the given string into the stream. The string is written with a * fixed length. If the length is longer than the string, then 00 bytes are * written * * @param stream * stream to write to * @param str * strign to write * @param length * number of bytes to write * @throws IOException */ public static void writeFixedString(OutputStream stream, String str, int length) throws IOException { int i; int value; for (i = 0; i < length; i++) { if (i < str.length()) value = str.charAt(i); else value = 0; stream.write(value); } } /** * Write a double value into a byte array * * @param os * stream to write to * @param value * value to write */ public static void writeDouble(OutputStream os, double value) throws IOException { ByteArrayOutputStream bo; DataOutputStream dos; byte[] b; byte help; /* --- Convert the value into a byte array --- */ bo = new ByteArrayOutputStream(); dos = new DataOutputStream(bo); /* --- Convert the value into a 8 byte double --- */ dos.writeDouble(value); dos.close(); b = bo.toByteArray(); /* --- Change byte order --- */ for (int i = 0; i < 4; i++) { help = b[i]; b[i] = b[7 - i]; b[7 - i] = help; } /* --- Write result into output stream --- */ os.write(b); } /** * Build an image name from a filename. The image name is the name of the * file without path and extension . The length of the name is limited to 8 * chars. We use only 6 chars, so we can use 99 images */ public static String buildImageName(String name) { int index; /* --- Remove the extension --- */ index = name.indexOf('.'); if (index != -1) name = name.substring(0, index); /* --- Limit the filename to 8 chars --- */ if (name.length() > 8) name = name.substring(0, 8); return name.toLowerCase().trim(); } /** * Builds a tile name from a basename and an index. */ public static String buildTileName(String basename, int index) { String indexstr; /* --- Convert the index number to a string --- */ indexstr = String.valueOf(index); /* * --- cut the basename so that basename+index is not longer than 8 * chars --- */ if (indexstr.length() + basename.length() > 8) basename = basename.substring(0, 8 - indexstr.length()); return basename.trim() + indexstr; } } ././@LongLink0000000000000000000000000000015000000000000011561 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/impl/rmp/TileContainer.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/impl/rmp/TileContainer.j0000644000175000017500000000761512122526606033244 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ /* ********************************************* * Copyright: Andreas Sander * * * ********************************************* */ package mobac.program.atlascreators.impl.rmp; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; /** * Container for tiles and link to subtrees * */ public class TileContainer { private final TileContainer previous; private final ArrayList tiles; private final ArrayList followUps; public TileContainer() { this(null); } public TileContainer(TileContainer previous) { this.previous = previous; tiles = new ArrayList(100); followUps = new ArrayList(); } /** * Set tile for given position. next is only valid if a previous value is * set */ public void addTile(Tiledata tile, TileContainer next) { tiles.add(tile); if (previous != null) followUps.add(next); } /** * Returns the number of tiles in this container including all sub * containers */ public int getTileCount() { int count = tiles.size(); if (previous != null) count += previous.getTileCount(); for (TileContainer next : followUps) count += next.getTileCount(); return count; } /** * returns the number of containers in the tree */ public int getContainerCount() { return 1 + followUps.size(); } /** * Write the whole tree into the stream */ public void writeTree(OutputStream os) throws IOException { /* --- if this container has subtrees --- */ if (previous != null) { /* --- Write previous --- */ previous.writeTree(os); /* --- Write ourselves --- */ writeContainer(os); /* --- And all subtrees --- */ for (TileContainer tc : followUps) tc.writeTree(os); } else { /* --- Just write the tile itself, if it does not have subtrees --- */ writeContainer(os); } } /** * Write the content of the container */ public void writeContainer(OutputStream os) throws IOException { /* --- Number of tiles in subtree --- */ RmpTools.writeValue(os, getTileCount(), 4); /* --- Number of tiles in node --- */ RmpTools.writeValue(os, tiles.size(), 2); /* --- Last node flag --- */ RmpTools.writeValue(os, previous == null ? 1 : 0, 2); /* --- Info about 99 tiles --- */ for (int i = 0; i < 99; i++) { int x = 0; int y = 0; int offset = 0; if (i < tiles.size()) { x = tiles.get(i).posx; y = tiles.get(i).posy; offset = tiles.get(i).totalOffset; } RmpTools.writeValue(os, x, 4); RmpTools.writeValue(os, y, 4); RmpTools.writeValue(os, 0, 4); RmpTools.writeValue(os, offset, 4); } /* --- Offset to previous --- */ if (previous == null) RmpTools.writeValue(os, 0, 4); else RmpTools.writeValue(os, 0x0f5c, 4); /* --- Offset to following --- */ for (int i = 0; i < 99; i++) { if (i < followUps.size()) RmpTools.writeValue(os, 0x0f5c + (i + 2) * 1992, 4); else RmpTools.writeValue(os, 0, 4); } } } ././@LongLink0000000000000000000000000000015700000000000011570 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/impl/rmp/ChecksumOutputStream.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/impl/rmp/ChecksumOutputS0000644000175000017500000000620712122526606033356 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ /* ------------------------------------------------------------------------ CheckSumStream.java Project: Testing --------------------------------------------------------------------------*/ /* --- created: 15.08.2008 a.sander $History:$ --- */ package mobac.program.atlascreators.impl.rmp; import java.io.IOException; import java.io.OutputStream; /** * OutputStream that calculates a 2Byte XOR checksum over the stream written * */ public class ChecksumOutputStream extends OutputStream { private OutputStream nextStream; int checksum; boolean evenByte; /** * Constructor * * @param next_stream * stream to write data to */ public ChecksumOutputStream(OutputStream next_stream) { nextStream = next_stream; checksum = 0; evenByte = true; } /** * Resets the checksum to 0 */ public void clearChecksum() { checksum = 0; evenByte = true; } /** * Returns the current checksum */ public int getChecksum() { return checksum; } /** * Sets the current checksum */ public void setChecksum(int checksum) { this.checksum = checksum; } /** * Writes the current checksum (2 bytes) to the output stream */ public void writeChecksum() throws IOException { nextStream.write((checksum >> 8) & 0xFF); nextStream.write(checksum & 0xFF); } @Override public void write(byte[] buf, int off, int len) throws IOException { int value; int o = off; for (int i = 0; i < len; i++) { if (evenByte) value = (((int) buf[o++]) & 0xFF) << 8; else value = (((int) buf[o++]) & 0xFF); checksum ^= value; evenByte = !evenByte; } /* --- Send to next stream --- */ nextStream.write(buf, off, len); } @Override public void write(byte[] buf) throws IOException { write(buf, 0, buf.length); } @Override public void write(int val) throws IOException { int value; if (evenByte) value = (val & 0xFF) << 8; else value = (val & 0xFF); checksum ^= value; evenByte = !evenByte; /* --- Send to next stream --- */ nextStream.write(val); } @Override public void close() throws IOException { nextStream.close(); } @Override public void flush() throws IOException { nextStream.flush(); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/impl/rmp/interfaces/0000755000175000017500000000000012122526606032443 5ustar paulliupaulliu././@LongLink0000000000000000000000000000016200000000000011564 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/impl/rmp/interfaces/RmpFileEntry.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/impl/rmp/interfaces/RmpF0000644000175000017500000000312212122526606033230 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ /* ********************************************* * Copyright: Andreas Sander * * * ********************************************* */ package mobac.program.atlascreators.impl.rmp.interfaces; import java.io.IOException; import java.io.OutputStream; /** * Interface for all files that are stored in a RMP file * */ public interface RmpFileEntry { /** * Returns the content of the file as byte array * * @throws InterruptedException */ public void writeFileContent(OutputStream os) throws IOException, InterruptedException; /** * Returns the name of the file without extension */ public String getFileName(); /** * Returns the extension of the file */ public String getFileExtension(); } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/impl/rmp/RmpLayer.java0000644000175000017500000002111612122526606032717 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ /* ********************************************* * Copyright: Andreas Sander * * * ********************************************* */ package mobac.program.atlascreators.impl.rmp; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.LinkedList; import java.util.List; import mobac.gui.AtlasProgress; import mobac.program.atlascreators.AtlasCreator; import mobac.program.atlascreators.impl.rmp.interfaces.RmpFileEntry; import org.apache.log4j.Logger; /** * Class for building a TLM file from image and writing the file to a stream * */ public class RmpLayer { private static final Logger log = Logger.getLogger(RmpLayer.class); private List tiles; private TLMEntry tlmFile = null; private final AtlasCreator atlasCreator; /** * Constructor */ public RmpLayer(AtlasCreator atlasCreator) { tiles = new LinkedList(); this.atlasCreator = atlasCreator; } /** * Return the content of the A00 file as byte array */ public RmpFileEntry getA00File(String image_name) { return new A00Entry(image_name); } /** * Return the content of the TLM file as byte array * * @throws IOException */ public TLMEntry getTLMFile(String image_name) { tlmFile.setImageName(image_name); return tlmFile; } public void addPreparedImage(Tiledata tileData) throws IOException { tiles.add(tileData); } /** * distribute the tiles over containers of max 256 tiles */ private TileContainer buildTileTree() { TileContainer[] container; TileContainer indexContainer = null; int containerCount; /* * --- Calculate the number of tiles and tiles per container. 99 would * be possible but we limit ourselves to 80 - That's enough --- */ int count = tiles.size(); containerCount = count / 80; if (count % 80 != 0) containerCount++; int tilesPerContainer = count / containerCount; /* --- Create containers --- */ container = new TileContainer[containerCount]; for (int i = 0; i < containerCount; i++) container[i] = new TileContainer(); /* * --- We need an index container if there is more than one container. * Container 0 is the previous of the index container --- */ if (containerCount > 1) indexContainer = new TileContainer(container[0]); /* --- Place the tiles into the container --- */ int tileCount = 0; int totalTileCount = 0; int containerNumber = 0; for (Tiledata tiledata : tiles) { /* * --- Starting with the second container, the first element is * moved to the index container --- */ if (tileCount == 0 && containerNumber != 0) indexContainer.addTile(tiledata, container[containerNumber]); else container[containerNumber].addTile(tiledata, null); /* --- Switch to next container if we reach end of container --- */ tileCount++; if (tileCount == tilesPerContainer) { containerNumber++; tileCount = 0; /* * --- Recalculate the number of tiles per container because of * rounding issues */ if (containerCount != containerNumber) tilesPerContainer = (count - (totalTileCount + 1)) / (containerCount - containerNumber); } totalTileCount++; } /* * --- If we have multiple containers, then the index container is the * result, otherwise the single container. */ if (indexContainer == null) return container[0]; else return indexContainer; } /** * Create the TLM file from the TileContainer infos * * @throws IOException */ public void buildTLMFile(double tile_width, double tile_height, double left, double right, double top, double bottom) throws IOException { tlmFile = new TLMEntry(tile_width, tile_height, left, right, top, bottom); tlmFile.updateContent(); } public class TLMEntry implements RmpFileEntry { private byte[] data = null; String imageName; final double tile_width; final double tile_height; final double left; final double right; final double top; final double bottom; public TLMEntry(double tile_width, double tile_height, double left, double right, double top, double bottom) { super(); this.tile_width = tile_width; this.tile_height = tile_height; this.left = left; this.right = right; this.top = top; this.bottom = bottom; } public void updateContent() throws IOException { // calculate offset of each tile in A00 file int totaloffset = 4; for (Tiledata tile : tiles) { tile.totalOffset = totaloffset; totaloffset += tile.getTileDataSize() + 4; } /* --- Build the tile container --- */ TileContainer container = buildTileTree(); log.debug("Number of output tiles: " + container.getTileCount()); /* --- Create Output file --- */ ByteArrayOutputStream bos = new ByteArrayOutputStream(16384); /* --- header --- */ RmpTools.writeValue(bos, 1, 4); // Start of block RmpTools.writeValue(bos, container.getTileCount(), 4); // Number of // tiles in files RmpTools.writeValue(bos, 256, 2); // Hor. size of tile in pixel RmpTools.writeValue(bos, 256, 2); // Vert. size of tile in pixel RmpTools.writeValue(bos, 1, 4); // Start of block RmpTools.writeDouble(bos, tile_height); // Height of tile in degree RmpTools.writeDouble(bos, tile_width); // Tile width in degree RmpTools.writeDouble(bos, left); // Frame RmpTools.writeDouble(bos, top); // Frame RmpTools.writeDouble(bos, right); // Frame RmpTools.writeDouble(bos, bottom); // Frame RmpTools.writeValue(bos, 0, 88); // Filler RmpTools.writeValue(bos, 256, 2); // Tile size ???? RmpTools.writeValue(bos, 0, 2); // Filler int size = 256 + 1940 + 3 * 1992; size += container.getContainerCount() * 1992; if (container.getContainerCount() != 1) size += 1992; RmpTools.writeValue(bos, size, 4); // File size RmpTools.writeValue(bos, 0, 96); // Filler RmpTools.writeValue(bos, 1, 4); // Start of block RmpTools.writeValue(bos, 99, 4); // Number of tiles in block int firstBlockOffset = 0x0f5c + ((container.getContainerCount() == 1) ? 0 : 1992); RmpTools.writeValue(bos, firstBlockOffset, 4); // offset for first // block RmpTools.writeValue(bos, 0, 3920); // Filler /* --- Write the Tiledata --- */ container.writeTree(bos); /* --- Add two empty blocks --- */ RmpTools.writeValue(bos, 0, 1992 * 2); data = bos.toByteArray(); } public void setImageName(String imageName) { this.imageName = imageName; } public String getFileExtension() { return "tlm"; } public String getFileName() { return imageName; } public void writeFileContent(OutputStream out) throws IOException { out.write(data); } } protected class A00Entry implements RmpFileEntry { protected String name; public A00Entry(String name) { super(); this.name = name; } public String getFileExtension() { return "a00"; } public String getFileName() { return name; } public void writeFileContent(OutputStream os) throws IOException, InterruptedException { BufferedOutputStream bos = new BufferedOutputStream(os, 32768); /* --- Number of tiles --- */ RmpTools.writeValue(bos, tiles.size(), 4); AtlasProgress atlasProgress = atlasCreator.getAtlasProgress(); /* --- The tiles --- */ int x = 0; int xMax = tiles.size(); for (Tiledata tile : tiles) { tile.writeTileData(bos); atlasCreator.checkUserAbort(); atlasProgress.setMapCreationProgress((1000 * x++ / xMax)); } bos.flush(); } @Override public String toString() { return "A00Entry"; } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/impl/rmp/Tiledata.java0000644000175000017500000000431712122526606032717 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ /* ********************************************* * Copyright: Andreas Sander * * * ********************************************* */ package mobac.program.atlascreators.impl.rmp; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import mobac.exceptions.MapCreationException; import mobac.program.interfaces.TileImageDataWriter; /** * Content of a single tile * */ public class Tiledata { private final TileImageDataWriter writer; public int posx; public int posy; public int totalOffset; public MultiImage si; public BoundingRect rect; private int dataSize = 0; public Tiledata(TileImageDataWriter writer) { this.writer = writer; } public int getTileDataSize() { return dataSize; } public void writeTileData(OutputStream out) throws IOException { try { BufferedImage image = si.getSubImage(rect, 256, 256); ByteArrayOutputStream bout = new ByteArrayOutputStream(16384); writer.processImage(image, bout); byte[] data = bout.toByteArray(); dataSize = data.length; // Utilities.saveBytes(String.format("D:/jpg/mobac-%04d-%04d.jpg", posx, posy), data); RmpTools.writeValue(out, dataSize, 4); out.write(data); } catch (MapCreationException e) { throw new IOException(e.getCause()); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/impl/rmp/rmpfile/0000755000175000017500000000000012122526606031756 5ustar paulliupaulliu././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/impl/rmp/rmpfile/Bmp2bit.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/impl/rmp/rmpfile/Bmp2bit0000644000175000017500000000571612122526606033211 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators.impl.rmp.rmpfile; public class Bmp2bit extends GeneralRmpFileEntry { private static final byte[] content = { 73, 99, 111, 110, 32, 102, 105, 108, 101, 32, 118, 101, 114, 115, 105, 111, 110, 32, 49, 46, 48, 46, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1, 0, 0, 60, 0, 0, 0, -16, -1, -1, 127, -40, 0, 0, 0, -15, -1, -1, 127, 116, 1, 0, 0, 0, 1, 0, 0, -1, -1, -1, -1, 88, 0, 0, 0, -104, 0, 0, 0, 0, 0, 0, 0, 16, 0, 16, 0, 4, 2, 0, 0, 0, 0, 0, 0, 63, -1, -1, -4, 48, 0, 0, 12, 48, 0, 0, 12, 48, 0, 0, 12, 48, 0, 0, 12, 48, 0, 0, 12, 48, 0, 0, 12, 48, 0, 0, 12, 48, 0, 0, 12, 48, 0, 0, 12, 48, 0, 0, 12, 48, 0, 0, 12, 48, 0, 0, 12, 63, -1, -1, -4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -1, -1, -64, 3, -1, -1, -64, 3, -1, -1, -64, 3, -1, -1, -64, 3, -1, -1, -64, 3, -1, -1, -64, 3, -1, -1, -64, 3, -1, -1, -64, 3, -1, -1, -64, 3, -1, -1, -64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -16, -1, -1, 127, -1, -1, -1, -1, -12, 0, 0, 0, 52, 1, 0, 0, 0, 0, 0, 0, 1, 0, 64, 0, 4, 8, 0, 0, 81, -3, -40, -70, -124, 24, -99, -19, 46, -36, -3, -21, -128, 98, 96, -75, 82, -99, 78, 108, -79, 18, -9, -36, -20, -88, -41, 84, -99, 88, 98, 40, 74, 93, 118, -31, -73, -62, -98, -43, -41, 12, -75, 60, 69, 54, -54, -40, 51, -73, -18, 36, 83, 86, -8, 80, -2, 105, -61, -122, 37, 114, 7, -7, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -15, -1, -1, 127, -1, -1, -1, -1, -112, 1, 0, 0, -88, 1, 0, 0, 0, 0, 0, 0, 1, 0, 24, 0, 4, 8, 0, 0, 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1 }; public Bmp2bit() { super(content, "bmp2bit", "ics"); } @Override public String toString() { return this.getClass().getSimpleName() + " " + getFileName() + "." + getFileExtension(); } } ././@LongLink0000000000000000000000000000016600000000000011570 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/impl/rmp/rmpfile/GeneralRmpFileEntry.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/impl/rmp/rmpfile/General0000644000175000017500000000370212122526606033260 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ /* ********************************************* * Copyright: Andreas Sander * * * ********************************************* */ package mobac.program.atlascreators.impl.rmp.rmpfile; import java.io.IOException; import java.io.OutputStream; import mobac.program.atlascreators.impl.rmp.interfaces.RmpFileEntry; /** * General class for storing the content of a rmp file * */ public class GeneralRmpFileEntry implements RmpFileEntry { protected final byte[] content; protected final String filename; protected final String extension; public GeneralRmpFileEntry(byte[] content, String filename, String extension) { this.content = content; this.filename = filename; this.extension = extension; } public void writeFileContent(OutputStream os) throws IOException { os.write(content); } public String getFileExtension() { return extension; } public String getFileName() { return filename; } @Override public String toString() { return "GeneralRmpFileEntry \"" + filename + "." + extension + "\" content-len=" + content.length; } } ././@LongLink0000000000000000000000000000015100000000000011562 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/impl/rmp/rmpfile/RmpIni.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/impl/rmp/rmpfile/RmpIni.0000644000175000017500000000421112122526606033153 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ /* ********************************************* * Copyright: Andreas Sander * * * ********************************************* */ package mobac.program.atlascreators.impl.rmp.rmpfile; import java.io.ByteArrayOutputStream; import java.io.PrintStream; import mobac.program.atlascreators.impl.rmp.RmpTools; import org.apache.log4j.Logger; /** * Instance of the rmp.ini file * * @author Andreas * */ public class RmpIni extends GeneralRmpFileEntry { private static final Logger log = Logger.getLogger(RmpIni.class); public RmpIni(String layername, int count) { super(generateContent(layername, count), "rmp", "ini"); } private static byte[] generateContent(String layername, int count) { ByteArrayOutputStream bos; PrintStream ps; int i; bos = new ByteArrayOutputStream(); ps = new PrintStream(bos); /* --- Content of rmp.ini is a simple INI file --- */ ps.print("[T_Layers]\r\n"); for (i = 0; i < count; i++) { String layerName = RmpTools.buildTileName(layername, i); log.trace("layer name: " + layerName); ps.print(i + "=" + layerName + "\r\n"); } ps.flush(); return bos.toByteArray(); } @Override public String toString() { return this.getClass().getSimpleName() + " size=" + content.length; } } ././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/impl/rmp/rmpfile/Bmp4bit.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/impl/rmp/rmpfile/Bmp4bit0000644000175000017500000000656212122526606033213 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators.impl.rmp.rmpfile; public class Bmp4bit extends GeneralRmpFileEntry { private static final byte[] content = { 73, 99, 111, 110, 32, 102, 105, 108, 101, 32, 118, 101, 114, 115, 105, 111, 110, 32, 49, 46, 48, 46, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1, 0, 0, 60, 0, 0, 0, -16, -1, -1, 127, 88, 1, 0, 0, -15, -1, -1, 127, -12, 1, 0, 0, 0, 1, 0, 0, -1, -1, -1, -1, 88, 0, 0, 0, -40, 0, 0, 0, 0, 0, 0, 0, 16, 0, 16, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 51, 51, 51, 51, 51, 51, 48, 3, 0, 0, 0, 0, 0, 0, 48, 3, 0, 0, 0, 0, 0, 0, 48, 3, 0, 0, 0, 0, 0, 0, 48, 3, 0, 0, 0, 0, 0, 0, 48, 3, 0, 0, 0, 0, 0, 0, 48, 3, 0, 0, 0, 0, 0, 0, 48, 3, 0, 0, 0, 0, 0, 0, 48, 3, 0, 0, 0, 0, 0, 0, 48, 3, 0, 0, 0, 0, 0, 0, 48, 3, 0, 0, 0, 0, 0, 0, 48, 3, 0, 0, 0, 0, 0, 0, 48, 3, 0, 0, 0, 0, 0, 0, 48, 3, 51, 51, 51, 51, 51, 51, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, -1, -1, -1, -1, -16, 0, 0, 15, -1, -1, -1, -1, -16, 0, 0, 15, -1, -1, -1, -1, -16, 0, 0, 15, -1, -1, -1, -1, -16, 0, 0, 15, -1, -1, -1, -1, -16, 0, 0, 15, -1, -1, -1, -1, -16, 0, 0, 15, -1, -1, -1, -1, -16, 0, 0, 15, -1, -1, -1, -1, -16, 0, 0, 15, -1, -1, -1, -1, -16, 0, 0, 15, -1, -1, -1, -1, -16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -16, -1, -1, 127, -1, -1, -1, -1, 116, 1, 0, 0, -76, 1, 0, 0, 0, 0, 0, 0, 1, 0, 64, 0, 4, 8, 0, 0, 81, -3, -40, -70, -124, 24, -99, -19, 46, -36, -3, -21, -128, 98, 96, -75, 82, -99, 78, 108, -79, 18, -9, -36, -20, -88, -41, 84, -99, 88, 98, 40, 74, 93, 118, -31, -73, -62, -98, -43, -41, 12, -75, 60, 69, 54, -54, -40, 51, -73, -18, 36, 83, 86, -8, 80, -2, 105, -61, -122, 37, 114, 7, -7, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -15, -1, -1, 127, -1, -1, -1, -1, 16, 2, 0, 0, 40, 2, 0, 0, 0, 0, 0, 0, 1, 0, 24, 0, 4, 8, 0, 0, 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 0, -1, -1 }; public Bmp4bit() { super(content, "bmp4bit", "ics"); } @Override public String toString() { return this.getClass().getSimpleName() + " " + getFileName() + "." + getFileExtension(); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/impl/rungps/0000755000175000017500000000000012122526606031040 5ustar paulliupaulliu././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/impl/rungps/RunGPSAtlasFile.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/impl/rungps/RunGPSAtlasF0000644000175000017500000002463112122526606033202 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators.impl.rungps; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.RandomAccessFile; import java.util.ArrayList; import java.util.List; import mobac.utilities.Charsets; import mobac.utilities.Utilities; /** * * @author Tom Henne, eSymetric */ public class RunGPSAtlasFile { public final static String SUFFIX = ".ratlas"; RandomAccessFile raf; RunGPSAtlasHeader rah = new RunGPSAtlasHeader(); File cacheFile; OutputStream cacheOutStream = null; long positionInCacheFile = 0L; int offset = 0; int indexLength = 0; public class RAINode { RAINode() { key = -1; value = -1L; next = -1; child = -1; index = -1; } int key; long value; int next; int child; int index; void readFrom(int index) throws IOException { this.index = index; raf.seek(index); key = raf.readInt(); value = raf.readLong(); next = raf.readInt(); child = raf.readInt(); } void writeNew() throws IOException { raf.seek(indexLength); // go to end raf.writeInt(key); raf.writeLong(value); raf.writeInt(next); raf.writeInt(child); this.index = indexLength; indexLength += 20; } void write() throws IOException { raf.seek(index + 4); raf.writeLong(value); raf.writeInt(next); raf.writeInt(child); } String listAll() throws IOException { return listAll(""); } String listAll(String path) throws IOException { List children = getChildren(); StringBuilder sb = new StringBuilder(); if (key != -1) { // not for root path += "" + key + "/"; if (value != -1L) { sb.append(path).append('=').append(value).append("\n"); } } for (RAINode childNode : children) { sb.append(childNode.listAll(path)); } return sb.toString(); } List getChildren() throws IOException { // currentIndexPos is now at fathers node index pos or -1 List children = new ArrayList(); int indexPos = child; for (;;) { if (indexPos == -1) { break; } RAINode n = new RAINode(); n.readFrom(indexPos); children.add(n); indexPos = n.next; } return children; } RAINode getChildNode(int key, boolean createNew) throws IOException { // currentIndexPos is now at fathers node index pos or -1 // check if father has a child if (this.child == -1) { RAINode newNode = new RAINode(); newNode.key = key; newNode.writeNew(); this.child = newNode.index; this.write(); return newNode; } // find node on this level RAINode n = new RAINode(); int currentIndexPos = this.child; for (;;) { if (currentIndexPos == -1) { break; } n.readFrom(currentIndexPos); if (n.key == key) { return n; } currentIndexPos = n.next; } if (!createNew) { return null; } RAINode newNode = new RAINode(); newNode.key = key; newNode.writeNew(); n.next = newNode.index; n.write(); return newNode; } public int getSize() { return indexLength; } public RandomAccessFile getRandomAccessFile() { return raf; } RAINode getChildNode(List hierarchy) throws IOException { if (hierarchy.isEmpty()) { return this; } int key_ = hierarchy.get(0); hierarchy.remove(0); RAINode childNode = getChildNode(key_, false); if (childNode == null) { return null; } else { return childNode.getChildNode(hierarchy); } } } public boolean readSuccess() { return rah.readSuccess(); } public class RunGPSAtlasHeader { public final static long FILETYPE_KEY = 8723487877262773L; public final static int HEADER_SIZE = 128; // bytes public final static int FILE_VERSION = 3; int indexSize; // bytes public void writeHeader() throws IOException { raf.seek(0); raf.writeLong(FILETYPE_KEY); raf.writeInt(FILE_VERSION); raf.writeInt(indexSize); } public boolean readHeader() throws IOException { if (raf.readLong() != FILETYPE_KEY) { return false; } if (raf.readInt() != FILE_VERSION) { return false; } indexSize = raf.readInt(); return true; } public boolean readSuccess() { return indexSize > 0; } } public RunGPSAtlasFile(String filePath, boolean write) throws IOException { this.offset = RunGPSAtlasHeader.HEADER_SIZE; if (write) { cacheFile = new File(filePath + ".cac"); cacheOutStream = new BufferedOutputStream(new FileOutputStream(cacheFile), 8216); raf = new RandomAccessFile(filePath, "rw"); raf.setLength(0); // delete existing content indexLength = offset; RAINode root = new RAINode(); root.writeNew(); } else { raf = new RandomAccessFile(filePath, "r"); rah.readHeader(); } } public RAINode getRootNode() throws IOException { RAINode root = new RAINode(); root.readFrom(offset); return root; } public String listAll() throws IOException { return getRootNode().listAll(); } public void close() throws IOException { if (cacheOutStream != null) { cacheOutStream.close(); } if (raf != null) { raf.close(); } } public void finishArchive() throws IOException { cacheOutStream.close(); cacheOutStream = null; FileInputStream fis = new FileInputStream(cacheFile); rah.indexSize = indexLength - RunGPSAtlasHeader.HEADER_SIZE; rah.writeHeader(); byte[] buf = new byte[4096]; raf.seek(indexLength); for (;;) { int l = fis.read(buf); if (l <= 0) { break; } raf.write(buf, 0, l); } fis.close(); Utilities.deleteFile(cacheFile); close(); } public void addData(List hierarchy, byte[] data) throws IOException { addData(hierarchy, data, data.length); } public void addData(List hierarchy, byte[] data, int length) throws IOException { cacheOutStream.write(data, 0, length); List posHierarchy = new ArrayList(); posHierarchy.addAll(hierarchy); posHierarchy.add(1); // position setValue(posHierarchy, positionInCacheFile); List lenHierarchy = new ArrayList(); lenHierarchy.addAll(hierarchy); lenHierarchy.add(2); // size setValue(lenHierarchy, length); positionInCacheFile += length; } public static List makeHierarchyFromPath(String path) { // e.g. /10/3487/8345.png // sure that replace() is correct? may be replaceAll() would be better? path = path.replace(File.separatorChar, '/'); int p = path.indexOf('.'); if (p > 0) { path = path.substring(0, p); // remove suffix } if (path.startsWith("/")) { path = path.substring(1); } try { List hierarchy = new ArrayList(); for (;;) { p = path.indexOf('/'); if (p > 0) { hierarchy.add(Integer.parseInt(path.substring(0, p))); path = path.substring(p + 1); } else { hierarchy.add(Integer.parseInt(path)); break; } } return hierarchy; } catch (NumberFormatException e) { return null; } } public byte[] getData(String path) throws IOException { return getData(makeHierarchyFromPath(path)); } public byte[] getData(List keyHierarchy) throws IOException { ArrayList posHierarchy = new ArrayList(); posHierarchy.addAll(keyHierarchy); posHierarchy.add(1); // position long indexPosition = getValue(posHierarchy); if (indexPosition == -1) { return null; } ArrayList sizeHierarchy = new ArrayList(); sizeHierarchy.addAll(keyHierarchy); sizeHierarchy.add(2); // size int size = (int) getValue(sizeHierarchy); if (size == -1) { return null; } byte[] buf = new byte[size]; raf.seek(RunGPSAtlasHeader.HEADER_SIZE + rah.indexSize + indexPosition); raf.readFully(buf); return buf; } public void setValue(List keyHierarchy, long value) throws IOException { setValueImpl(getRootNode(), keyHierarchy, value); } public void setValue(String path, long value) throws IOException { setValue(makeHierarchyFromPath(path), value); } private void setValueImpl(RAINode currentNode, List keyHierarchy, long value) throws IOException { int key = keyHierarchy.get(0); keyHierarchy.remove(0); RAINode n = currentNode.getChildNode(key, true); if (keyHierarchy.isEmpty()) { n.value = value; n.write(); } else { setValueImpl(n, keyHierarchy, value); } } public long getValue(List keyHierarchy) throws IOException { RAINode n = getRootNode().getChildNode(keyHierarchy); return n == null ? -1L : n.value; } public long getValue(String path) throws IOException { return getValue(makeHierarchyFromPath(path)); } public void setString(List keyHierarchy, String value) throws IOException { byte[] data = value.getBytes(Charsets.UTF_8); addData(keyHierarchy, data); } public void setString(String path, String value) throws IOException { setString(makeHierarchyFromPath(path), value); } public String getString(List keyHierarchy) throws IOException { byte[] data = getData(keyHierarchy); if (data != null) { return new String(data, Charsets.UTF_8); } return null; } public String getString(String path) throws IOException { return getString(makeHierarchyFromPath(path)); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/AbstractPlainImage.java0000644000175000017500000001314512127544344033126 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.awt.Color; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.IOException; import javax.imageio.ImageIO; import mobac.exceptions.AtlasTestException; import mobac.exceptions.MapCreationException; import mobac.mapsources.mapspace.MercatorPower2MapSpace; import mobac.program.interfaces.LayerInterface; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSpace; import mobac.program.interfaces.MapSpace.ProjectionCategory; import mobac.utilities.Utilities; public abstract class AbstractPlainImage extends AtlasCreator { @Override public boolean testMapSource(MapSource mapSource) { MapSpace mapSpace = mapSource.getMapSpace(); return (mapSpace instanceof MercatorPower2MapSpace && ProjectionCategory.SPHERE.equals(mapSpace .getProjectionCategory())); } @Override protected void testAtlas() throws AtlasTestException { Runtime r = Runtime.getRuntime(); long heapMaxSize = r.maxMemory(); int maxMapSize = (int) (Math.sqrt(heapMaxSize / 3d) * 0.8); // reduce maximum by 20% maxMapSize = (maxMapSize / 100) * 100; // round by 100; for (LayerInterface layer : atlas) { for (MapInterface map : layer) { int w = map.getMaxTileCoordinate().x - map.getMinTileCoordinate().x; int h = map.getMaxTileCoordinate().y - map.getMinTileCoordinate().y; if (w > maxMapSize || h > maxMapSize) throw new AtlasTestException("Map size too large for memory (is: " + Math.max(w, h) + " max: " + maxMapSize + ")", map); } } } @Override public void createMap() throws MapCreationException, InterruptedException { try { createImage(); } catch (InterruptedException e) { throw e; } catch (MapCreationException e) { throw e; } catch (Exception e) { throw new MapCreationException(map, e); } } /** * @return maximum image height and width. In case an image is larger it will be scaled to fit. */ protected int getMaxImageSize() { return Integer.MAX_VALUE; } protected int getBufferedImageType() { return BufferedImage.TYPE_4BYTE_ABGR; } protected void createImage() throws InterruptedException, MapCreationException { atlasProgress.initMapCreation((xMax - xMin + 1) * (yMax - yMin + 1)); ImageIO.setUseCache(false); int mapWidth = (xMax - xMin + 1) * tileSize; int mapHeight = (yMax - yMin + 1) * tileSize; int maxImageSize = getMaxImageSize(); int imageWidth = Math.min(maxImageSize, mapWidth); int imageHeight = Math.min(maxImageSize, mapHeight); int len = Math.max(mapWidth, mapHeight); double scaleFactor = 1.0; boolean scaleImage = (len > maxImageSize); if (scaleImage) { scaleFactor = (double) getMaxImageSize() / (double) len; if (mapWidth != mapHeight) { // Map is not rectangle -> adapt height or width if (mapWidth > mapHeight) imageHeight = (int) (scaleFactor * mapHeight); else imageWidth = (int) (scaleFactor * mapWidth); } } if (imageHeight < 0 || imageWidth < 0) throw new MapCreationException("Invalid map size: (width/height: " + imageWidth + "/" + imageHeight + ")", map); long imageSize = 3l * ((long) imageWidth) * ((long) imageHeight); if (imageSize > Integer.MAX_VALUE) throw new MapCreationException("Map image too large: (width/height: " + imageWidth + "/" + imageHeight + ") - reduce the map size and try again", map); BufferedImage tileImage = Utilities.safeCreateBufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_3BYTE_BGR); Graphics2D graphics = tileImage.createGraphics(); try { if (scaleImage) { graphics.setTransform(AffineTransform.getScaleInstance(scaleFactor, scaleFactor)); graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); } int lineY = 0; for (int y = yMin; y <= yMax; y++) { int lineX = 0; for (int x = xMin; x <= xMax; x++) { checkUserAbort(); atlasProgress.incMapCreationProgress(); try { byte[] sourceTileData = mapDlTileProvider.getTileData(x, y); if (sourceTileData != null) { BufferedImage tile = ImageIO.read(new ByteArrayInputStream(sourceTileData)); graphics.drawImage(tile, lineX, lineY, tileSize, tileSize, Color.WHITE, null); } } catch (IOException e) { log.error("", e); } lineX += tileSize; } lineY += tileSize; } } finally { graphics.dispose(); } writeTileImage(tileImage); } protected abstract void writeTileImage(BufferedImage tileImage) throws MapCreationException; } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/TrekBuddy.java0000644000175000017500000002756012122526606031333 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.Locale; import javax.imageio.ImageIO; import mobac.exceptions.AtlasTestException; import mobac.exceptions.MapCreationException; import mobac.mapsources.mapspace.MercatorPower2MapSpace; import mobac.program.annotations.AtlasCreatorName; import mobac.program.annotations.SupportedParameters; import mobac.program.atlascreators.impl.MapTileBuilder; import mobac.program.atlascreators.impl.MapTileWriter; import mobac.program.atlascreators.tileprovider.CacheTileProvider; import mobac.program.atlascreators.tileprovider.TileProvider; import mobac.program.interfaces.AtlasInterface; import mobac.program.interfaces.LayerInterface; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSpace; import mobac.program.interfaces.MapSpace.ProjectionCategory; import mobac.program.model.TileImageParameters.Name; import mobac.utilities.Utilities; import mobac.utilities.geo.GeoUtils; @AtlasCreatorName(value = "TrekBuddy untared atlas", type = "UntaredAtlas") @SupportedParameters(names = { Name.format, Name.height, Name.width }) public class TrekBuddy extends AtlasCreator { protected static final String FILENAME_PATTERN = "t_%d_%d.%s"; protected File layerDir = null; protected File mapDir = null; protected MapTileWriter mapTileWriter; @Override public boolean testMapSource(MapSource mapSource) { MapSpace mapSpace = mapSource.getMapSpace(); return (mapSpace instanceof MercatorPower2MapSpace && ProjectionCategory.SPHERE.equals(mapSpace .getProjectionCategory())); // TODO supports Mercator ellipsoid? } public void startAtlasCreation(AtlasInterface atlas, File customAtlasDir) throws IOException, InterruptedException, AtlasTestException { super.startAtlasCreation(atlas, customAtlasDir); } public void finishAtlasCreation() { createAtlasTbaFile("cr"); } @Override public void initializeMap(MapInterface map, TileProvider mapTileProvider) { super.initializeMap(map, mapTileProvider); LayerInterface layer = map.getLayer(); layerDir = new File(atlasDir, layer.getName()); mapDir = new File(layerDir, map.getName()); } protected void writeMapFile() throws IOException { File mapFile = new File(mapDir, map.getName() + ".map"); FileOutputStream mapFileStream = null; try { mapFileStream = new FileOutputStream(mapFile); writeMapFile(mapFileStream); } finally { Utilities.closeStream(mapFileStream); } } protected void writeMapFile(OutputStream stream) throws IOException { writeMapFile("t_." + mapSource.getTileImageType().getFileExt(), stream); } protected void writeMapFile(String imageFileName, OutputStream stream) throws IOException { log.trace("Writing map file"); OutputStreamWriter mapWriter = new OutputStreamWriter(stream, TEXT_FILE_CHARSET); MapSpace mapSpace = mapSource.getMapSpace(); double longitudeMin = mapSpace.cXToLon(xMin * tileSize, zoom); double longitudeMax = mapSpace.cXToLon((xMax + 1) * tileSize - 1, zoom); double latitudeMin = mapSpace.cYToLat((yMax + 1) * tileSize - 1, zoom); double latitudeMax = mapSpace.cYToLat(yMin * tileSize, zoom); int width = (xMax - xMin + 1) * tileSize; int height = (yMax - yMin + 1) * tileSize; mapWriter.write(prepareMapString(imageFileName, longitudeMin, longitudeMax, latitudeMin, latitudeMax, width, height)); mapWriter.flush(); } public void createMap() throws MapCreationException, InterruptedException { try { Utilities.mkDirs(mapDir); // write the .map file containing the calibration points writeMapFile(); // This means there should not be any resizing of the tiles. mapTileWriter = createMapTileWriter(); // Select the tile creator instance based on whether tile image // parameters has been set or not if (parameters != null) createCustomTiles(); else createTiles(); mapTileWriter.finalizeMap(); } catch (MapCreationException e) { throw e; } catch (InterruptedException e) { throw e; } catch (Exception e) { throw new MapCreationException(map, e); } } protected MapTileWriter createMapTileWriter() throws IOException { return new FileTileWriter(); } /** * New experimental custom tile size algorithm implementation. * * It creates each custom sized tile separately. Therefore each original tile (256x256) will be loaded and painted * multiple times. Therefore this implementation needs much more CPU power as each original tile is loaded at least * once and each generated tile has to be saved. * * @throws MapCreationException */ protected void createCustomTiles() throws InterruptedException, MapCreationException { log.debug("Starting map creation using custom parameters: " + parameters); CacheTileProvider ctp = new CacheTileProvider(mapDlTileProvider); try { mapDlTileProvider = ctp; MapTileBuilder mapTileBuilder = new MapTileBuilder(this, mapTileWriter, true); atlasProgress.initMapCreation(mapTileBuilder.getCustomTileCount()); mapTileBuilder.createTiles(); } finally { ctp.cleanup(); } } protected void createTiles() throws InterruptedException, MapCreationException { int tilex = 0; int tiley = 0; atlasProgress.initMapCreation((xMax - xMin + 1) * (yMax - yMin + 1)); ImageIO.setUseCache(false); byte[] emptyTileData = Utilities.createEmptyTileData(mapSource); String tileType = mapSource.getTileImageType().getFileExt(); for (int x = xMin; x <= xMax; x++) { tiley = 0; for (int y = yMin; y <= yMax; y++) { checkUserAbort(); atlasProgress.incMapCreationProgress(); try { byte[] sourceTileData = mapDlTileProvider.getTileData(x, y); if (sourceTileData != null) { mapTileWriter.writeTile(tilex, tiley, tileType, sourceTileData); } else { log.trace(String.format("Tile x=%d y=%d not found in tile archive - creating default", tilex, tiley)); mapTileWriter.writeTile(tilex, tiley, tileType, emptyTileData); } } catch (IOException e) { throw new MapCreationException("Error writing tile image: " + e.getMessage(), map, e); } tiley++; } tilex++; } } private class FileTileWriter implements MapTileWriter { File setFolder; Writer setFileWriter; int tileHeight = 256; int tileWidth = 256; public FileTileWriter() throws IOException { super(); setFolder = new File(mapDir, "set"); Utilities.mkDir(setFolder); log.debug("Writing tiles to set folder: " + setFolder); File setFile = new File(mapDir, map.getName() + ".set"); if (parameters != null) { tileHeight = parameters.getHeight(); tileWidth = parameters.getWidth(); } try { setFileWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(setFile), TEXT_FILE_CHARSET)); } catch (IOException e) { log.error("", e); } } public void writeTile(int tilex, int tiley, String imageFormat, byte[] tileData) throws IOException { String tileFileName = String.format(FILENAME_PATTERN, (tilex * tileWidth), (tiley * tileHeight), imageFormat); File f = new File(setFolder, tileFileName); FileOutputStream out = new FileOutputStream(f); setFileWriter.write(tileFileName + "\r\n"); try { out.write(tileData); } finally { Utilities.closeStream(out); } } public void finalizeMap() { try { setFileWriter.flush(); } catch (IOException e) { log.error("", e); } Utilities.closeWriter(setFileWriter); } } protected String prepareMapString(String fileName, double longitudeMin, double longitudeMax, double latitudeMin, double latitudeMax, int width, int height) { StringBuffer sbMap = new StringBuffer(); sbMap.append("OziExplorer Map Data File Version 2.2\r\n"); sbMap.append(fileName + "\r\n"); sbMap.append(fileName + "\r\n"); sbMap.append("1 ,Map Code,\r\n"); sbMap.append("WGS 84,WGS 84, 0.0000, 0.0000,WGS 84\r\n"); sbMap.append("Reserved 1\r\n"); sbMap.append("Reserved 2\r\n"); sbMap.append("Magnetic Variation,,,E\r\n"); sbMap.append("Map Projection,Mercator,PolyCal,No," + "AutoCalOnly,No,BSBUseWPX,No\r\n"); String latMax = GeoUtils.getDegMinFormat(latitudeMax, true); String latMin = GeoUtils.getDegMinFormat(latitudeMin, true); String lonMax = GeoUtils.getDegMinFormat(longitudeMax, false); String lonMin = GeoUtils.getDegMinFormat(longitudeMin, false); String pointLine = "Point%02d,xy, %4s, %4s,in, deg, %1s, %1s, grid, , , ,N\r\n"; sbMap.append(String.format(pointLine, 1, 0, 0, latMax, lonMin)); sbMap.append(String.format(pointLine, 2, width - 1, 0, latMax, lonMax)); sbMap.append(String.format(pointLine, 3, width - 1, height - 1, latMin, lonMax)); sbMap.append(String.format(pointLine, 4, 0, height - 1, latMin, lonMin)); for (int i = 5; i <= 30; i++) { String s = String.format(pointLine, i, "", "", "", ""); sbMap.append(s); } sbMap.append("Projection Setup,,,,,,,,,,\r\n"); sbMap.append("Map Feature = MF ; Map Comment = MC These follow if they exist\r\n"); sbMap.append("Track File = TF These follow if they exist\r\n"); sbMap.append("Moving Map Parameters = MM? These follow if they exist\r\n"); sbMap.append("MM0,Yes\r\n"); sbMap.append("MMPNUM,4\r\n"); String mmpxLine = "MMPXY, %d, %5d, %5d\r\n"; sbMap.append(String.format(mmpxLine, 1, 0, 0)); sbMap.append(String.format(mmpxLine, 2, width - 1, 0)); sbMap.append(String.format(mmpxLine, 3, width - 1, height - 1)); sbMap.append(String.format(mmpxLine, 4, 0, height - 1)); String mpllLine = "MMPLL, %d, %2.6f, %2.6f\r\n"; sbMap.append(String.format(Locale.ENGLISH, mpllLine, 1, longitudeMin, latitudeMax)); sbMap.append(String.format(Locale.ENGLISH, mpllLine, 2, longitudeMax, latitudeMax)); sbMap.append(String.format(Locale.ENGLISH, mpllLine, 3, longitudeMax, latitudeMin)); sbMap.append(String.format(Locale.ENGLISH, mpllLine, 4, longitudeMin, latitudeMin)); sbMap.append("MOP,Map Open Position,0,0\r\n"); // The simple variant for calculating mm1b // http://www.trekbuddy.net/forum/viewtopic.php?t=3755&postdays=0&postorder=asc&start=286 double mm1b = (longitudeMax - longitudeMin) * 111319; mm1b *= Math.cos(Math.toRadians((latitudeMax + latitudeMin) / 2.0)) / width; sbMap.append(String.format(Locale.ENGLISH, "MM1B, %2.6f\r\n", mm1b)); sbMap.append("IWH,Map Image Width/Height, " + width + ", " + height + "\r\n"); return sbMap.toString(); } public void createAtlasTbaFile(String name) { File crtba = new File(atlasDir.getAbsolutePath(), name + ".tba"); try { FileWriter fw = new FileWriter(crtba); fw.write("Atlas 1.0\r\n"); fw.close(); } catch (IOException e) { log.error("", e); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/Viewranger.java0000644000175000017500000000550512131416116031534 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.io.File; import mobac.exceptions.AtlasTestException; import mobac.program.annotations.AtlasCreatorName; import mobac.program.annotations.SupportedParameters; import mobac.program.atlascreators.tileprovider.ConvertedRawTileProvider; import mobac.program.atlascreators.tileprovider.PngTileProvider; import mobac.program.atlascreators.tileprovider.TileProvider; import mobac.program.interfaces.LayerInterface; import mobac.program.interfaces.MapInterface; import mobac.program.model.TileImageParameters.Name; import mobac.program.model.TileImageType; /** * http://sourceforge.net/p/mobac/feature-requests/219/ */ @AtlasCreatorName("Viewranger") @SupportedParameters(names = { Name.format_png }) public class Viewranger extends OSMTracker { public Viewranger() { super(); tileFileNamePattern = "%d/%d/%d"; } @Override protected void testAtlas() throws AtlasTestException { for (LayerInterface layer : atlas) { for (MapInterface map : layer) { if (map.getParameters() == null) continue; if (!TileImageType.PNG.equals(map.getParameters().getFormat().getType())) throw new AtlasTestException("Only PNG output format allowed for Viewranger", map); if (map.getZoom() > 18) throw new AtlasTestException("Unsupported zoom level: " + map.getZoom() + "\nMaximum supported zoom level is 18", map); if (map.getZoom() < 3) throw new AtlasTestException("Unsupported zoom level: " + map.getZoom() + "\nMinimum suupported toom level is 3", map); } } } @Override public void initializeMap(MapInterface map, TileProvider mapTileProvider) { super.initializeMap(map, mapTileProvider); mapDir = new File(atlasDir, map.getLayer().getName()); tileType = ""; if (parameters == null) mapDlTileProvider = new PngTileProvider(mapDlTileProvider); else mapDlTileProvider = new ConvertedRawTileProvider(mapDlTileProvider, parameters.getFormat()); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/OSMAND_SQlite.java0000644000175000017500000000246612122526604031674 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import mobac.mapsources.mapspace.MercatorPower2MapSpace; import mobac.program.annotations.AtlasCreatorName; import mobac.program.interfaces.MapSource; @AtlasCreatorName(value = "OSMAND SQLite", type = "OSMAND_SQlite") public class OSMAND_SQlite extends RMapsSQLite { @Override public boolean testMapSource(MapSource mapSource) { return MercatorPower2MapSpace.INSTANCE_256.equals(mapSource.getMapSpace()); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/OsmdroidGEMF.java0000644000175000017500000000340112122526604031637 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ /** * */ package mobac.program.atlascreators; import java.io.File; import java.io.IOException; import java.util.LinkedList; import java.util.List; import mobac.program.annotations.AtlasCreatorName; import mobac.program.atlascreators.impl.gemf.GEMFFileCreator; /** * AtlasCreator implementation to create a GEMF archive file. For details about the format, please see the link in * {@link GEMFFileCreator}. * * @author M. Reiter * */ @AtlasCreatorName("Osmdroid GEMF") public class OsmdroidGEMF extends OSMTracker { private static final String GEMF_FILE_EXTENSION = ".gemf"; @Override public void finishAtlasCreation() throws IOException, InterruptedException { List tileFolders = new LinkedList(); tileFolders.add(mapDir); String gemfLocation = new File(atlasDir, atlas.getName() + GEMF_FILE_EXTENSION).toString(); new GEMFFileCreator(gemfLocation, tileFolders, log); super.finishAtlasCreation(); } }mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/AFTrack.java0000644000175000017500000000750412122526606030705 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.awt.Point; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.util.ArrayList; import java.util.Collections; import mobac.program.annotations.AtlasCreatorName; import mobac.program.atlascreators.tileprovider.TileProvider; import mobac.program.interfaces.LayerInterface; import mobac.program.interfaces.MapInterface; import mobac.utilities.Utilities; import mobac.utilities.stream.ZipStoreOutputStream; /** * AFTrack OSZ Atlas format */ @AtlasCreatorName("AFTrack (OSZ)") public class AFTrack extends OSMTracker { private ArrayList zoomLevel = new ArrayList(); private int maxZoom; private Point min; private Point max; @Override public void initLayerCreation(LayerInterface layer) throws IOException { super.initLayerCreation(layer); File oszFile = new File(atlasDir, layer.getName() + ".osz"); mapTileWriter = new OszTileWriter(oszFile); zoomLevel.clear(); min = new Point(); max = new Point(); maxZoom = -1; } @Override public void finishLayerCreation() throws IOException { mapTileWriter.finalizeMap(); mapTileWriter = null; super.finishLayerCreation(); } @Override public void initializeMap(MapInterface map, TileProvider mapTileProvider) { super.initializeMap(map, mapTileProvider); zoomLevel.add(new Integer(map.getZoom())); if (map.getZoom() > maxZoom) { maxZoom = map.getZoom(); min.x = map.getMinTileCoordinate().x / 256; min.y = map.getMinTileCoordinate().y / 256; max.x = map.getMaxTileCoordinate().x / 256; max.y = map.getMaxTileCoordinate().y / 256; } } private class OszTileWriter extends OSMTileWriter { ZipStoreOutputStream zipStream; FileOutputStream out; public OszTileWriter(File oszFile) throws FileNotFoundException { super(); out = new FileOutputStream(oszFile); zipStream = new ZipStoreOutputStream(out); } public void writeTile(int tilex, int tiley, String tileType, byte[] tileData) throws IOException { String entryName = String.format(tileFileNamePattern, zoom, tilex, tiley, tileType); zipStream.writeStoredEntry(entryName, tileData); } public void finalizeMap() throws IOException { ByteArrayOutputStream bout = new ByteArrayOutputStream(100); OutputStreamWriter writer = new OutputStreamWriter(bout); Collections.sort(zoomLevel); for (Integer zoom : zoomLevel) writer.append(String.format("zoom=%d\r\n", zoom.intValue())); writer.append(String.format("minx=%d\r\n", min.x)); writer.append(String.format("maxx=%d\r\n", max.x)); writer.append(String.format("miny=%d\r\n", min.y)); writer.append(String.format("maxy=%d\r\n", max.y)); writer.close(); zipStream.writeStoredEntry("Manifest.txt", bout.toByteArray()); Utilities.closeStream(zipStream); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/MagellanRmp.java0000644000175000017500000001741112122526604031625 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.awt.Point; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import mobac.exceptions.AtlasTestException; import mobac.exceptions.MapCreationException; import mobac.mapsources.mapspace.MercatorPower2MapSpace; import mobac.program.annotations.AtlasCreatorName; import mobac.program.annotations.SupportedParameters; import mobac.program.atlascreators.impl.rmp.BoundingRect; import mobac.program.atlascreators.impl.rmp.MultiImage; import mobac.program.atlascreators.impl.rmp.RmpLayer; import mobac.program.atlascreators.impl.rmp.RmpLayer.TLMEntry; import mobac.program.atlascreators.impl.rmp.RmpTools; import mobac.program.atlascreators.impl.rmp.RmpWriter; import mobac.program.atlascreators.impl.rmp.Tiledata; import mobac.program.atlascreators.impl.rmp.rmpfile.Bmp2bit; import mobac.program.atlascreators.impl.rmp.rmpfile.Bmp4bit; import mobac.program.atlascreators.tileprovider.TileProvider; import mobac.program.interfaces.AtlasInterface; import mobac.program.interfaces.LayerInterface; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSpace; import mobac.program.interfaces.TileImageDataWriter; import mobac.program.model.TileImageParameters.Name; import mobac.program.tiledatawriter.TileImageJpegDataWriter; @AtlasCreatorName(value = "Magellan (RMP)", type = "Rmp") @SupportedParameters(names = { Name.format_jpg }) public class MagellanRmp extends AtlasCreator { TileImageDataWriter tileWriter = null; RmpWriter rmpWriter = null; String imageName = null; int layerNum = 0; @Override public boolean testMapSource(MapSource mapSource) { return MercatorPower2MapSpace.INSTANCE_256.equals(mapSource.getMapSpace()); } @Override public void startAtlasCreation(AtlasInterface atlas, File customAtlasDir) throws IOException, InterruptedException, AtlasTestException { super.startAtlasCreation(atlas, customAtlasDir); int mapCount = 0; for (LayerInterface layer : atlas) mapCount += layer.getMapCount(); imageName = RmpTools.buildImageName(atlas.getName()); rmpWriter = new RmpWriter(imageName, mapCount, new File(atlasDir, imageName + ".rmp")); } @Override protected void testAtlas() throws AtlasTestException { for (LayerInterface layer : atlas) { for (MapInterface map : layer) { Point max = map.getMaxTileCoordinate(); Point min = map.getMinTileCoordinate(); // if (max.x - min.x > 18000 || max.y - min.y > 18000) // throw new AtlasTestException("Map too large. Max size 18000x18000"); if (map.getParameters() != null) { if (!(map.getParameters().getFormat().getDataWriter() instanceof TileImageJpegDataWriter)) throw new AtlasTestException("Only JPEG formats are supported", map); } } } } @Override public void initializeMap(MapInterface map, TileProvider mapTileProvider) { super.initializeMap(map, mapTileProvider); if (parameters != null) { tileWriter = parameters.getFormat().getDataWriter(); } else tileWriter = new TileImageJpegDataWriter(0.9); tileWriter.initialize(); } @Override public void createMap() throws MapCreationException, InterruptedException { createTiles(); } protected void createTiles() throws InterruptedException, MapCreationException { atlasProgress.initMapCreation(1000); ImageIO.setUseCache(false); MultiImage layerImage = new MultiImage(mapSource, mapDlTileProvider, map); try { RmpLayer layer = createLayer(layerImage, layerNum); String layerName = RmpTools.buildTileName(imageName, layerNum); TLMEntry tlmEntry = layer.getTLMFile(layerName); rmpWriter.prepareFileEntry(tlmEntry); rmpWriter.writeFileEntry(layer.getA00File(layerName)); tlmEntry.updateContent(); rmpWriter.writePreparedFileEntry(tlmEntry); atlasProgress.setMapCreationProgress(1000); } catch (IOException e) { throw new MapCreationException(map, e); } layerNum++; } @Override public void finishAtlasCreation() throws IOException, InterruptedException { if (rmpWriter == null) return; // Creation already aborted try { rmpWriter.writeFileEntry(new Bmp2bit()); rmpWriter.writeFileEntry(new Bmp4bit()); rmpWriter.writeDirectory(); } finally { rmpWriter.close(); rmpWriter = null; } } @Override public void abortAtlasCreation() throws IOException { super.abortAtlasCreation(); rmpWriter.delete(); rmpWriter = null; } /** * Create a new instance of a TLM file and fill it with the data of a calibrated image * * @param si * image to get data from * @param layer * Layer number - for status output only * @return TLM instance * @throws InterruptedException * @throws MapCreationException * @throws IOException */ public RmpLayer createLayer(MultiImage si, int layer) throws InterruptedException, MapCreationException, IOException { int count = 0; /* --- Create instance --- */ RmpLayer rmpLayer = new RmpLayer(this); /* --- Get the coordinate space of the image --- */ MapSpace mapSpace = mapSource.getMapSpace(); double north = mapSpace.cYToLat(map.getMinTileCoordinate().y, zoom); double south = mapSpace.cYToLat(map.getMaxTileCoordinate().y, zoom); double west = mapSpace.cXToLon(map.getMinTileCoordinate().x, zoom); double east = mapSpace.cXToLon(map.getMaxTileCoordinate().x, zoom); BoundingRect rect = new BoundingRect(-north, -south, west, east); Point max = map.getMaxTileCoordinate(); Point min = map.getMinTileCoordinate(); int imageWidth = max.x - min.x; int imageHeight = max.y - min.y; /* --- Calculate tile dimensions --- */ double tile_width = (rect.getEast() - rect.getWest()) * 256 / imageWidth; double tile_height = (rect.getSouth() - rect.getNorth()) * 256 / imageHeight; /* --- Calculate the positions of the upper left tile --- */ int x_start = (int) Math.floor((rect.getWest() + 180) / tile_width); int y_start = (int) Math.floor((rect.getNorth() + 90) / tile_height); double x_end = (rect.getEast() + 180.0) / tile_width; double y_end = (rect.getSouth() + 90.0) / tile_height; /* * Create the tiles - process works column wise, starting on the top left corner of the destination area. */ for (int x = x_start; x < x_end; x++) { for (int y = y_start; y < y_end; y++) { count++; /* --- Create tile --- */ BoundingRect subrect = new BoundingRect(y * tile_height - 90, (y + 1) * tile_height - 90, x * tile_width - 180, (x + 1) * tile_width - 180); Tiledata td = new Tiledata(tileWriter); td.posx = x; td.posy = y; td.rect = subrect; td.si = si; rmpLayer.addPreparedImage(td); } } /* --- Build the TLM file --- */ rmpLayer.buildTLMFile(tile_width, tile_height, rect.getWest(), rect.getEast(), rect.getNorth(), rect.getSouth()); return rmpLayer; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/MBTiles.java0000644000175000017500000001554212122526606030732 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.io.File; import java.io.IOException; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Statement; import java.text.SimpleDateFormat; import java.util.Date; import java.util.EnumSet; import java.util.Locale; import mobac.exceptions.AtlasTestException; import mobac.mapsources.mapspace.MercatorPower2MapSpace; import mobac.program.annotations.AtlasCreatorName; import mobac.program.interfaces.LayerInterface; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSpace; import mobac.program.model.TileImageParameters; import mobac.program.model.TileImageType; /** * https://github.com/mapbox/mbtiles-spec/tree/master/1.1 */ @AtlasCreatorName(value = "MBTiles SQLite") public class MBTiles extends RMapsSQLite { private static final String INSERT_SQL = "INSERT or REPLACE INTO tiles (tile_column,tile_row,zoom_level,tile_data) VALUES (?,?,?,?)"; private static final String TABLE_TILES = "CREATE TABLE IF NOT EXISTS tiles (zoom_level integer, tile_column integer, tile_row integer, tile_data blob);"; private static final String INDEX_TILES = "CREATE INDEX IF NOT EXISTS tiles_idx on tiles (zoom_level, tile_column, tile_row)"; private static final String TABLE_METADATA = "CREATE TABLE IF NOT EXISTS metadata (name text, value text);"; private static final String INSERT_METADATA = "INSERT INTO metadata (name,value) VALUES (?,?);"; private static final String INDEX_METADATA = "CREATE UNIQUE INDEX IF NOT EXISTS metadata_idx ON metadata (name);"; private double boundsLatMin; private double boundsLatMax; private double boundsLonMin; private double boundsLonMax; private TileImageType atlasTileImageType; @Override public boolean testMapSource(MapSource mapSource) { return MercatorPower2MapSpace.INSTANCE_256.equals(mapSource.getMapSpace()); } @Override protected void testAtlas() throws AtlasTestException { EnumSet allowed = EnumSet.of(TileImageType.JPG, TileImageType.PNG); // Test of output format - only jpg xor png is allowed TileImageType tit = null; for (LayerInterface layer : atlas) { for (MapInterface map : layer) { TileImageParameters parameters = map.getParameters(); TileImageType currentTit; if (parameters == null) { currentTit = map.getMapSource().getTileImageType(); if (!allowed.contains(currentTit)) throw new AtlasTestException( "Map source format incompatible - tile format conversion to PNG or JPG is required for this map.", map); } else { currentTit = parameters.getFormat().getType(); if (!allowed.contains(currentTit)) throw new AtlasTestException( "Selected custom tile format not supported - only JPG and PNG formats are supported.", map); } if (tit != null && !currentTit.equals(tit)) { throw new AtlasTestException("All maps within one atlas must use the same format (PNG or JPG). " + "Use tile format conversion converting maps with a different format.", map); } tit = currentTit; } } atlasTileImageType = tit; } @Override protected void openConnection() throws SQLException { if (databaseFile.isFile()) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd_HHmmss"); databaseFile = new File(atlasDir, atlas.getName() + "_" + sdf.format(new Date()) + ".mbtiles"); } super.openConnection(); } @Override protected void initializeDB() throws SQLException { Statement stat = conn.createStatement(); stat.executeUpdate(TABLE_TILES); stat.executeUpdate(INDEX_TILES); stat.executeUpdate(TABLE_METADATA); stat.executeUpdate(INDEX_METADATA); stat.close(); boundsLatMin = Double.MAX_VALUE; boundsLatMax = Double.MIN_VALUE; boundsLonMin = Double.MAX_VALUE; boundsLonMax = Double.MIN_VALUE; } @Override protected void updateTileMetaInfo() throws SQLException { MapSpace ms = map.getMapSource().getMapSpace(); double lon1 = ms.cXToLon(map.getMinTileCoordinate().x, zoom); double lon2 = ms.cXToLon(map.getMaxTileCoordinate().x, zoom); double lat1 = ms.cYToLat(map.getMinTileCoordinate().y, zoom); double lat2 = ms.cYToLat(map.getMaxTileCoordinate().y, zoom); boundsLatMin = Math.min(boundsLatMin, Math.min(lat1, lat2)); boundsLatMax = Math.max(boundsLatMax, Math.max(lat1, lat2)); boundsLonMin = Math.min(boundsLonMin, Math.min(lon1, lon2)); boundsLonMax = Math.max(boundsLonMin, Math.max(lon1, lon2)); } @Override public void finishAtlasCreation() throws IOException, InterruptedException { PreparedStatement st; try { st = conn.prepareStatement(INSERT_METADATA); st.setString(1, "bounds"); st.setString(2, String.format(Locale.ENGLISH, "%.3f,%.3f,%.3f,%.3f", boundsLonMin, boundsLatMin, boundsLonMax, boundsLatMax)); st.execute(); st.setString(1, "name"); st.setString(2, atlas.getName()); st.execute(); st.setString(1, "type"); st.setString(2, "baselayer"); st.execute(); st.setString(1, "version"); st.setString(2, "1.1"); st.execute(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); st.setString(1, "description"); st.setString(2, atlas.getName() + " created on " + sdf.format(new Date()) + " by MOBAC"); st.execute(); st.setString(1, "format"); st.setString(2, atlasTileImageType.getFileExt()); st.execute(); st.close(); conn.commit(); } catch (SQLException e) { throw new IOException(e); } super.finishAtlasCreation(); } @Override protected String getTileInsertSQL() { return INSERT_SQL; } @Override protected void writeTile(int x, int y, int z, byte[] tileData) throws SQLException, IOException { y = (1 << z) - y - 1; prepStmt.setInt(1, x); prepStmt.setInt(2, y); prepStmt.setInt(3, z); prepStmt.setBytes(4, tileData); prepStmt.addBatch(); } protected String getDatabaseFileName() { return atlas.getName() + ".mbtiles"; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/PaperAtlasPng.java0000644000175000017500000000410412122526606032124 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.text.DecimalFormat; import javax.imageio.ImageIO; import mobac.exceptions.MapCreationException; import mobac.program.annotations.AtlasCreatorName; import mobac.utilities.Utilities; @AtlasCreatorName(value = "Paper Atlas (PNG)") public class PaperAtlasPng extends PaperAtlas { private final DecimalFormat decimalFormat = new DecimalFormat("#000"); private File mapFolder; public PaperAtlasPng() { super(true); } @Override public void createMap() throws MapCreationException, InterruptedException { mapFolder = new File(getLayerFolder(), map.getName()); try { Utilities.mkDirs(mapFolder); } catch (IOException e) { throw new MapCreationException(map, e); } super.createMap(); mapFolder = null; } @Override protected void processPage(BufferedImage image, int pageNumber) throws MapCreationException { String fileName = decimalFormat.format(pageNumber) + ".png"; File file = new File(mapFolder, fileName); try { ImageIO.write(image, "PNG", file); } catch (IOException e) { throw new MapCreationException(map, e); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/OSMTracker.java0000644000175000017500000001037712122526606031406 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import javax.imageio.ImageIO; import mobac.exceptions.MapCreationException; import mobac.mapsources.mapspace.MercatorPower2MapSpace; import mobac.program.annotations.AtlasCreatorName; import mobac.program.annotations.SupportedParameters; import mobac.program.atlascreators.impl.MapTileWriter; import mobac.program.atlascreators.tileprovider.ConvertedRawTileProvider; import mobac.program.atlascreators.tileprovider.TileProvider; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSource; import mobac.program.model.TileImageParameters.Name; import mobac.utilities.Utilities; /** * Creates maps identical to the atlas format used by OSMTracker. * * Please note that this atlas format ignores the defined atlas structure. It uses a separate directory for each used * map source and inside one directory for each zoom level. */ @AtlasCreatorName("OSMTracker tile storage") @SupportedParameters(names = { Name.format }) public class OSMTracker extends AtlasCreator { protected String tileFileNamePattern = "%d/%d/%d.%s"; protected File mapDir = null; protected String tileType = null; protected MapTileWriter mapTileWriter = null; @Override public boolean testMapSource(MapSource mapSource) { return MercatorPower2MapSpace.INSTANCE_256.equals(mapSource.getMapSpace()); } @Override public void initializeMap(MapInterface map, TileProvider mapTileProvider) { super.initializeMap(map, mapTileProvider); mapDir = new File(atlasDir, map.getMapSource().getName()); tileType = mapSource.getTileImageType().getFileExt(); if (parameters != null) { mapDlTileProvider = new ConvertedRawTileProvider(mapDlTileProvider, parameters.getFormat()); tileType = parameters.getFormat().getFileExt(); } } public void createMap() throws MapCreationException, InterruptedException { // This means there should not be any resizing of the tiles. if (mapTileWriter == null) mapTileWriter = new OSMTileWriter(); createTiles(); } protected void createTiles() throws InterruptedException, MapCreationException { atlasProgress.initMapCreation((xMax - xMin + 1) * (yMax - yMin + 1)); ImageIO.setUseCache(false); for (int x = xMin; x <= xMax; x++) { for (int y = yMin; y <= yMax; y++) { checkUserAbort(); atlasProgress.incMapCreationProgress(); try { byte[] sourceTileData = mapDlTileProvider.getTileData(x, y); if (sourceTileData != null) mapTileWriter.writeTile(x, y, tileType, sourceTileData); } catch (IOException e) { throw new MapCreationException("Error writing tile image: " + e.getMessage(), map, e); } } } } protected class OSMTileWriter implements MapTileWriter { public void writeTile(int tilex, int tiley, String tileType, byte[] tileData) throws IOException { File file = new File(mapDir, String.format(tileFileNamePattern, zoom, tilex, tiley, tileType)); writeTile(file, tileData); } protected void writeTile(File file, byte[] tileData) throws IOException { Utilities.mkDirs(file.getParentFile()); FileOutputStream out = new FileOutputStream(file); try { out.write(tileData); } finally { Utilities.closeStream(out); } } public void finalizeMap() throws IOException { // Nothing to do } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/PathAway.java0000644000175000017500000000614512122526604031146 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.io.File; import java.io.IOException; import mobac.exceptions.AtlasTestException; import mobac.exceptions.MapCreationException; import mobac.program.annotations.AtlasCreatorName; import mobac.program.atlascreators.tileprovider.TileProvider; import mobac.program.interfaces.LayerInterface; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSource; /** * Creates a tile cache structure as used by PathAway (for WindowsMobile, * Symbian, Palm) */ @AtlasCreatorName("PathAway tile cache") public class PathAway extends OSMTracker { public PathAway() { super(); tileFileNamePattern = "%02X/%04X/%04X.%s"; } @Override public void initializeMap(MapInterface map, TileProvider mapTileProvider) { super.initializeMap(map, mapTileProvider); MapSource mapSource = map.getMapSource(); String shortMapDir = null; if (mapSource.getName().equals("Google Maps")) shortMapDir = "G1"; else if (mapSource.getName().equals("Google Earth")) shortMapDir = "G2"; else if (mapSource.getName().equals("Google Terrain")) shortMapDir = "G3"; else if (mapSource.getName().equals("Mapnik")) shortMapDir = "OSM1"; else if (mapSource.getName().equals("OSM Cycle Map")) shortMapDir = "OCM1"; if (shortMapDir != null) mapDir = new File(atlasDir, shortMapDir); } public void createMap() throws MapCreationException, InterruptedException { // This means there should not be any resizing of the tiles. if (mapTileWriter == null) mapTileWriter = new PathAwayTileWriter(); createTiles(); } @Override protected void testAtlas() throws AtlasTestException { for (LayerInterface layer : atlas) { for (MapInterface map : layer) { if (map.getZoom() > 17) throw new AtlasTestException("resolution too high - " + "highest possible zoom level is 17"); } } } protected class PathAwayTileWriter extends OSMTileWriter { @Override public void writeTile(int tilex, int tiley, String tileType, byte[] tileData) throws IOException { File file = new File(mapDir, String.format(tileFileNamePattern, 17 - zoom, tilex, tiley, tileType)); writeTile(file, tileData); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/Glopus.java0000644000175000017500000000776012122526606030707 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import mobac.exceptions.MapCreationException; import mobac.program.annotations.AtlasCreatorName; import mobac.program.atlascreators.tileprovider.TileProvider; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSpace; import mobac.utilities.Utilities; @AtlasCreatorName("Glopus (PNG & KAL)") public class Glopus extends Ozi { @Override public void initializeMap(MapInterface map, TileProvider mapTileProvider) { super.initializeMap(map, mapTileProvider); String layerName = map.getLayer().getName().replaceAll(" ", "_"); mapName = map.getName().replaceAll(" ", "_"); layerDir = new File(atlasDir, layerName); } @Override public void createMap() throws MapCreationException, InterruptedException { try { Utilities.mkDir(layerDir); } catch (IOException e) { throw new MapCreationException(map, e); } createTiles(); writeKalFile(); } private void writeKalFile() throws MapCreationException { FileOutputStream fout = null; try { fout = new FileOutputStream(new File(layerDir, mapName + ".kal")); OutputStreamWriter mapWriter = new OutputStreamWriter(fout, TEXT_FILE_CHARSET); MapSpace mapSpace = mapSource.getMapSpace(); String longitudeMin = Double.toString(mapSpace.cXToLon(xMin * tileSize, zoom)); String longitudeMax = Double.toString(mapSpace.cXToLon((xMax + 1) * tileSize, zoom)); String latitudeMin = Double.toString(mapSpace.cYToLat((yMax + 1) * tileSize, zoom)); String latitudeMax = Double.toString(mapSpace.cYToLat(yMin * tileSize, zoom)); int width = (xMax - xMin + 1) * tileSize; int height = (yMax - yMin + 1) * tileSize; mapWriter.write("[Calibration Point 1]\n"); mapWriter.write(String.format("Longitude = %s\n", longitudeMin)); mapWriter.write(String.format("Latitude = %s\n", latitudeMax)); mapWriter.write("Pixel = POINT(0,0)\n"); mapWriter.write("[Calibration Point 2]\n"); mapWriter.write(String.format("Longitude = %s\n", longitudeMax)); mapWriter.write(String.format("Latitude = %s\n", latitudeMin)); mapWriter.write(String.format("Pixel = POINT(%d,%d)\n", width, height)); mapWriter.write("[Calibration Point 3]\n"); mapWriter.write(String.format("Longitude = %s\n", longitudeMax)); mapWriter.write(String.format("Latitude = %s\n", latitudeMax)); mapWriter.write(String.format("Pixel = POINT(%d,%d)\n", width, 0)); mapWriter.write("[Calibration Point 4]\n"); mapWriter.write(String.format("Longitude = %s\n", longitudeMin)); mapWriter.write(String.format("Latitude = %s\n", latitudeMin)); mapWriter.write(String.format("Pixel = POINT(%d,%d)\n", 0, height)); mapWriter.write("[Map]\n"); mapWriter.write(String.format("Bitmap = %s.png\n", mapName)); mapWriter.write(String.format("Size = SIZE(%d,%d)\n", width, height)); mapWriter.flush(); mapWriter.close(); } catch (IOException e) { throw new MapCreationException(map, e); } finally { Utilities.closeStream(fout); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/OSMAND.java0000644000175000017500000000213412122526606030405 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import mobac.program.annotations.AtlasCreatorName; @AtlasCreatorName("OSMAND tile storage") public class OSMAND extends OSMTracker { public OSMAND() { super(); tileFileNamePattern += ".tile"; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/OsmdroidSQLite.java0000644000175000017500000001271712131416150032266 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.io.File; import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Statement; import javax.imageio.ImageIO; import mobac.exceptions.AtlasTestException; import mobac.exceptions.MapCreationException; import mobac.program.annotations.AtlasCreatorName; import mobac.program.annotations.SupportedParameters; import mobac.program.atlascreators.tileprovider.ConvertedRawTileProvider; import mobac.program.atlascreators.tileprovider.TileProvider; import mobac.program.interfaces.AtlasInterface; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSpace.ProjectionCategory; import mobac.program.interfaces.RequiresSQLite; import mobac.program.model.TileImageParameters.Name; import mobac.utilities.jdbc.SQLiteLoader; /** * http://sourceforge.net/p/mobac/patches/22/ */ @AtlasCreatorName("Osmdroid SQLite") @SupportedParameters(names = { Name.format }) public class OsmdroidSQLite extends AtlasCreator implements RequiresSQLite { private static final int MAX_BATCH_SIZE = 1000; protected Connection conn = null; public OsmdroidSQLite() { super(); SQLiteLoader.loadSQLiteOrShowError(); } @Override public boolean testMapSource(MapSource mapSource) { return mapSource.getMapSpace().getProjectionCategory().equals(ProjectionCategory.SPHERE); } @Override public void startAtlasCreation(AtlasInterface atlas, File customAtlasDir) throws IOException, AtlasTestException, InterruptedException { super.startAtlasCreation(atlas, customAtlasDir); String databaseFile = new File(atlasDir, atlas.getName() + ".sqlite").getAbsolutePath(); try { SQLiteLoader.loadSQLite(); } catch (SQLException e) { throw new AtlasTestException(SQLiteLoader.getMsgSqliteMissing()); } try { conn = DriverManager.getConnection("jdbc:sqlite:" + databaseFile); Statement stat = conn.createStatement(); stat.executeUpdate("CREATE TABLE IF NOT EXISTS tiles (key INTEGER PRIMARY KEY, provider TEXT, tile BLOB)"); stat.close(); } catch (SQLException e) { throw new IOException("Error creating SQL database \"" + databaseFile + "\": " + e.getMessage(), e); } log.debug("SQLite Database file: " + databaseFile); } @Override public void initializeMap(MapInterface map, TileProvider mapTileProvider) { super.initializeMap(map, mapTileProvider); if (parameters != null) mapDlTileProvider = new ConvertedRawTileProvider(mapDlTileProvider, parameters.getFormat()); } @Override public void createMap() throws MapCreationException, InterruptedException { try { String provider = map.getMapSource().getName(); int maxMapProgress = 2 * (xMax - xMin + 1) * (yMax - yMin + 1); atlasProgress.initMapCreation(maxMapProgress); conn.setAutoCommit(false); int batchTileCount = 0; ImageIO.setUseCache(false); PreparedStatement prep = conn.prepareStatement("INSERT or REPLACE INTO tiles VALUES (?, ?, ?);"); Runtime r = Runtime.getRuntime(); long heapMaxSize = r.maxMemory(); for (long x = xMin; x <= xMax; x++) for (long y = yMin; y <= yMax; y++) { checkUserAbort(); atlasProgress.incMapCreationProgress(); byte[] sourceTileData = mapDlTileProvider.getTileData((int) x, (int) y); if (sourceTileData != null) { long z = zoom; long index = (((z << z) + x) << z) + y; prep.setLong(1, index); prep.setString(2, provider); prep.setBytes(3, sourceTileData); prep.addBatch(); long heapAvailable = heapMaxSize - r.totalMemory() + r.freeMemory(); if ((heapAvailable < HEAP_MIN) || (batchTileCount >= MAX_BATCH_SIZE)) { log.trace("Executing batch containing " + batchTileCount + " tiles"); prep.executeBatch(); prep.clearBatch(); System.gc(); conn.commit(); atlasProgress.incMapCreationProgress(batchTileCount); batchTileCount = 0; } } } prep.executeBatch(); conn.setAutoCommit(true); atlasProgress.setMapCreationProgress(maxMapProgress); } catch (SQLException e) { throw new MapCreationException("Error writing tile image: " + e.getMessage(), map, e); } catch (IOException e) { throw new MapCreationException("Error writing tile image: " + e.getMessage(), map, e); } } @Override public void abortAtlasCreation() throws IOException { SQLiteLoader.closeConnection(conn); conn = null; super.abortAtlasCreation(); } @Override public void finishAtlasCreation() throws IOException, InterruptedException { SQLiteLoader.closeConnection(conn); conn = null; super.finishAtlasCreation(); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/OruxMaps.java0000644000175000017500000002553112137626110031205 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.awt.Color; import java.awt.Graphics2D; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.util.Locale; import mobac.exceptions.AtlasTestException; import mobac.exceptions.MapCreationException; import mobac.mapsources.mapspace.MercatorPower2MapSpace; import mobac.program.annotations.AtlasCreatorName; import mobac.program.annotations.SupportedParameters; import mobac.program.atlascreators.impl.MapTileBuilder; import mobac.program.atlascreators.impl.MapTileWriter; import mobac.program.atlascreators.tileprovider.CacheTileProvider; import mobac.program.atlascreators.tileprovider.TileProvider; import mobac.program.interfaces.LayerInterface; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSpace; import mobac.program.model.TileImageFormat; import mobac.program.model.TileImageParameters; import mobac.program.model.TileImageParameters.Name; import mobac.utilities.Charsets; import mobac.utilities.Utilities; /** * Creates maps using the OruxMaps (Android) atlas format. * * @author orux */ @AtlasCreatorName("OruxMaps") @SupportedParameters(names = { Name.format }) public class OruxMaps extends AtlasCreator { // Calibration file extension protected static final String ORUXMAPS_EXT = ".otrk2.xml"; // OruxMaps tile size protected static final int TILE_SIZE = 512; protected String calVersionCode; // OruxMaps background color protected static final Color BG_COLOR = new Color(0xcb, 0xd3, 0xf3); // Each layer is a Main map for OruxMaps protected File oruxMapsMainDir; // Each map is a Layer map for OruxMaps protected File oruxMapsLayerDir; // Images directory for each map protected File oruxMapsImagesDir; protected LayerInterface currentLayer; // We need to override the map name, All maps must have the same prefix (layer name) protected String mapName; public OruxMaps() { super(); calVersionCode = "2.1"; } @Override public boolean testMapSource(MapSource mapSource) { return (mapSource.getMapSpace() instanceof MercatorPower2MapSpace); } @Override protected void testAtlas() throws AtlasTestException { for (LayerInterface layer : atlas) { int cont = layer.getMapCount(); for (int i = 0; i < cont; i++){ MapInterface currMap = layer.getMap(i); int currZoomLevel = currMap.getZoom(); for (int j = i + 1; j < cont; j++){ MapInterface nextMap = layer.getMap(j); int nextZoomLevel = nextMap.getZoom(); if (currZoomLevel == nextZoomLevel) throw new AtlasTestException( "Unable to create a map with more than a layer with the same zoom level: " + currMap + " & " + nextMap + "\nPossible causes:\n" + "You are combining several layers (using drag & drop in 'Atlas Content')\n" + "You are creating a large map, and you have not selected the maximum value in 'Settings - Map size'"); } } } } /* * @see mobac.program.atlascreators.AtlasCreator#initLayerCreation(mobac.program .interfaces.LayerInterface) */ @Override public void initLayerCreation(LayerInterface layer) throws IOException { super.initLayerCreation(layer); currentLayer = layer; oruxMapsMainDir = new File(atlasDir, layer.getName()); Utilities.mkDirs(oruxMapsMainDir); } @Override public void finishLayerCreation() throws IOException { super.finishLayerCreation(); writeMainOtrk2File(currentLayer.getName()); } /* * (non-Javadoc) * * @see mobac.program.atlascreators.AtlasCreator#initializeMap(mobac.program. interfaces.MapInterface, * mobac.utilities.tar.TarIndex) */ @Override public void initializeMap(MapInterface map, TileProvider mapTileProvider) { super.initializeMap(map, mapTileProvider); // OruxMaps default image format, jpeg90; always TILE_SIZE=512; if (parameters == null) parameters = new TileImageParameters(TILE_SIZE, TILE_SIZE, TileImageFormat.JPEG90); else parameters = new TileImageParameters(TILE_SIZE, TILE_SIZE, parameters.getFormat()); mapName = String.format("%s %02d", currentLayer.getName(), map.getZoom()); } @Override public void createMap() throws MapCreationException, InterruptedException { oruxMapsLayerDir = new File(oruxMapsMainDir, mapName); oruxMapsImagesDir = new File(oruxMapsLayerDir, "set"); try { Utilities.mkDir(oruxMapsLayerDir); Utilities.mkDir(oruxMapsImagesDir); writeOtrk2File(); createTiles(); } catch (InterruptedException e) { // User has aborted process return; } catch (Exception e) { throw new MapCreationException(map, e); } } protected void createTiles() throws InterruptedException, MapCreationException { CacheTileProvider ctp = new CacheTileProvider(mapDlTileProvider); try { mapDlTileProvider = ctp; OruxMapTileBuilder mapTileBuilder = new OruxMapTileBuilder(this, new OruxMapTileWriter()); atlasProgress.initMapCreation(mapTileBuilder.getCustomTileCount()); mapTileBuilder.createTiles(); } finally { ctp.cleanup(); } } /** * Main calibration file * * @param name */ private void writeMainOtrk2File(String name) { OutputStreamWriter writer; FileOutputStream otrk2FileStream = null; File otrk2 = new File(oruxMapsMainDir, name + ORUXMAPS_EXT); try { writer = new OutputStreamWriter(new FileOutputStream(otrk2), Charsets.UTF_8); writer.append("\n"); writer.append("\n"); writer.append("\n"); writer.append("\n"); writer.append(appendMapContent()); writer.append("\n"); writer.append("\n"); writer.flush(); } catch (IOException e) { log.error("", e); } finally { Utilities.closeStream(otrk2FileStream); } } protected String appendMapContent() { return ""; } /** * Main calibration file per layer * */ protected void writeOtrk2File() { FileOutputStream stream = null; OutputStreamWriter mapWriter; File otrk2File = new File(oruxMapsLayerDir, mapName + ORUXMAPS_EXT); try { stream = new FileOutputStream(otrk2File); mapWriter = new OutputStreamWriter(stream, "UTF8"); mapWriter.append(prepareOtrk2File()); mapWriter.flush(); } catch (IOException e) { log.error("", e); } finally { Utilities.closeStream(stream); } } /** * Main calibration file per layer * */ protected String prepareOtrk2File() { StringBuilder mapWriter = new StringBuilder(); MapSpace mapSpace = mapSource.getMapSpace(); double longitudeMin = mapSpace.cXToLon(xMin * tileSize, zoom); double longitudeMax = mapSpace.cXToLon((xMax + 1) * tileSize, zoom); double latitudeMin = mapSpace.cYToLat((yMax + 1) * tileSize, zoom); double latitudeMax = mapSpace.cYToLat(yMin * tileSize, zoom); mapWriter.append("\n"); mapWriter.append("\n"); mapWriter.append("\n"); // convert ampersands and others String mapFileName = mapName; mapFileName = mapFileName.replaceAll("&", "&"); mapFileName = mapFileName.replaceAll("<", "<"); mapFileName = mapFileName.replaceAll(">", ">"); mapFileName = mapFileName.replaceAll("\"", """); mapFileName = mapFileName.replaceAll("'", "'"); int mapWidth = (xMax - xMin + 1) * tileSize; int mapHeight = (yMax - yMin + 1) * tileSize; int numXimg = (mapWidth + TILE_SIZE - 1) / TILE_SIZE; int numYimg = (mapHeight + TILE_SIZE - 1) / TILE_SIZE; mapWriter.append("\n"); mapWriter.append("\n"); mapWriter.append("\n"); mapWriter.append("\n"); String cb = "\n"; mapWriter.append(String.format(Locale.ENGLISH, cb, "TL", longitudeMin, latitudeMax)); mapWriter.append(String.format(Locale.ENGLISH, cb, "BR", longitudeMax, latitudeMin)); mapWriter.append(String.format(Locale.ENGLISH, cb, "TR", longitudeMax, latitudeMax)); mapWriter.append(String.format(Locale.ENGLISH, cb, "BL", longitudeMin, latitudeMin)); mapWriter.append("\n"); mapWriter.append("\n"); mapWriter.append("\n"); return mapWriter.toString(); } protected class OruxMapTileBuilder extends MapTileBuilder { public OruxMapTileBuilder(AtlasCreator atlasCreator, MapTileWriter mapTileWriter) { super(atlasCreator, mapTileWriter, false); } @Override protected void prepareTile(Graphics2D graphics) { graphics.setColor(BG_COLOR); graphics.fillRect(0, 0, TILE_SIZE, TILE_SIZE); } } private class OruxMapTileWriter implements MapTileWriter { public void writeTile(int tilex, int tiley, String tileType, byte[] tileData) throws IOException { String tileFileName = String.format("%s_%d_%d.omc2", mapName, tilex, tiley); FileOutputStream out = new FileOutputStream(new File(oruxMapsImagesDir, tileFileName)); try { out.write(tileData); } finally { Utilities.closeStream(out); } } public void finalizeMap() { // Nothing to do } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/IPhone3MapTiles5.java0000644000175000017500000001644112127544344032427 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.awt.Point; import java.io.File; import java.io.IOException; import java.sql.SQLException; import java.sql.Statement; import java.text.SimpleDateFormat; import java.util.Date; import java.util.EnumSet; import mobac.exceptions.AtlasTestException; import mobac.exceptions.MapCreationException; import mobac.mapsources.mapspace.MercatorPower2MapSpace; import mobac.program.annotations.AtlasCreatorName; import mobac.program.annotations.SupportedParameters; import mobac.program.atlascreators.impl.MapTileBuilder; import mobac.program.atlascreators.impl.MapTileWriter; import mobac.program.interfaces.LayerInterface; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSource; import mobac.program.model.TileImageFormat; import mobac.program.model.TileImageParameters; import mobac.program.model.TileImageType; /** * The following SQL statements create SQLite database for background map: * * BEGIN TRANSACTION; CREATE TABLE images(zoom int, x int, y int, flags int, length int, data blob); CREATE TABLE * version(version int); INSERT INTO version VALUES(5); INSERT INTO version VALUES(0); * * CREATE INDEX index1 on images (zoom,x,y,flags); COMMIT; * * The columns in "images" table have the following meaning: * * zoom - zoom level from 1 (top level) to 23 (most detailed level). On the top level we have four squares 128x128 * pixels, it gives 512x512 pixels. So map width = map height = 256 * 2zoom pixels. * * x, y - coordinates for given zoom level: * * * * flags - layer number. Theoretically map could contain number of layers: street, satellite, hybrid and so on. * Practically the program shows only one layer with smallest flags value. * * length - size of binary image in bytes. * * data - binary tile image in PNG or JPEG format. Practically the program supports only PNG for now. * * For more details regarding Web Mercator projection and coordinates please see: * * http://msdn.microsoft.com/en-us/library/bb259689.aspx */ @AtlasCreatorName(value = "iPhone 3 Map Tiles v5") @SupportedParameters(names = {}) public class IPhone3MapTiles5 extends RMapsSQLite { private static final String INSERT_SQL = "INSERT or REPLACE INTO images(x,y,zoom,data,length,flags) VALUES (?,?,?,?,?,0);"; private static final String TABLE_IMAGES = "CREATE TABLE IF NOT EXISTS images(zoom int, x int, y int, flags int, length int, data blob); "; private static final String TABLE_VERSION = "CREATE TABLE IF NOT EXISTS version(version int);"; private static final String TABLE_VERSION_DATA = "INSERT INTO version VALUES(5);"; private static final String INDEX_IMAGES = "CREATE INDEX IF NOT EXISTS index1 on images (zoom,x,y,flags);"; @Override public boolean testMapSource(MapSource mapSource) { return MercatorPower2MapSpace.INSTANCE_256.equals(mapSource.getMapSpace()); } @Override protected void testAtlas() throws AtlasTestException { EnumSet allowed = EnumSet.of(TileImageType.JPG, TileImageType.PNG); // Test of output format - only jpg xor png is allowed for (LayerInterface layer : atlas) { for (MapInterface map : layer) { TileImageParameters parameters = map.getParameters(); TileImageType currentTit; if (parameters == null) { currentTit = map.getMapSource().getTileImageType(); if (!allowed.contains(currentTit)) throw new AtlasTestException( "Map source format incompatible - tile format conversion to PNG or JPG is required for this map.", map); } else { currentTit = parameters.getFormat().getType(); if (!allowed.contains(currentTit)) throw new AtlasTestException( "Selected custom tile format not supported - only JPG and PNG formats are supported.", map); } } } } @Override protected void openConnection() throws SQLException { if (databaseFile.isFile()) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd_HHmmss"); databaseFile = new File(atlasDir, atlas.getName() + "_" + sdf.format(new Date()) + ".sqlitedb"); } super.openConnection(); } @Override protected void initializeDB() throws SQLException { Statement stat = conn.createStatement(); stat.executeUpdate(TABLE_IMAGES); stat.executeUpdate(INDEX_IMAGES); if (stat.executeUpdate(TABLE_VERSION) == 0) stat.execute(TABLE_VERSION_DATA); stat.close(); } @Override protected void createTiles() throws InterruptedException, MapCreationException { try { parameters = new TileImageParameters(128, 128, TileImageFormat.PNG); conn.setAutoCommit(false); prepStmt = conn.prepareStatement(getTileInsertSQL()); MapTileWriter mapTileWriter = new SQLiteMapTileWriter(map); MapTileBuilder mapTileBuilder = new MapTileBuilder(this, mapTileWriter, true); atlasProgress.initMapCreation(mapTileBuilder.getCustomTileCount()); mapTileBuilder.createTiles(); mapTileWriter.finalizeMap(); prepStmt.close(); } catch (SQLException e) { throw new MapCreationException(map, e); } catch (IOException e) { Throwable t = e; if (t.getCause() instanceof SQLException) t = t.getCause(); throw new MapCreationException(map, t); } } @Override protected void updateTileMetaInfo() throws SQLException { } @Override protected String getTileInsertSQL() { return INSERT_SQL; } protected String getDatabaseFileName() { return atlas.getName() + ".sqlitedb"; } private class SQLiteMapTileWriter implements MapTileWriter { private final int z; private final int baseTileX; private final int baseTileY; SQLiteMapTileWriter(MapInterface map) { this.z = map.getZoom() + 1; Point topLeft = map.getMinTileCoordinate(); baseTileX = topLeft.x / 128; baseTileY = topLeft.y / 128; } @Override public void writeTile(int x, int y, String tileType, byte[] tileData) throws IOException { x += baseTileX; y += baseTileY; try { prepStmt.setInt(1, x); prepStmt.setInt(2, y); prepStmt.setInt(3, z); prepStmt.setBytes(4, tileData); prepStmt.setInt(5, tileData.length); prepStmt.addBatch(); } catch (SQLException e) { throw new IOException(e); } } @Override public void finalizeMap() throws IOException { try { prepStmt.executeBatch(); prepStmt.clearBatch(); conn.commit(); } catch (SQLException e) { throw new IOException(e); } } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/Maplorer.java0000644000175000017500000002103512122526606031206 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.io.File; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import java.util.Locale; import javax.imageio.ImageIO; import mobac.exceptions.MapCreationException; import mobac.mapsources.mapspace.MercatorPower2MapSpace; import mobac.program.annotations.AtlasCreatorName; import mobac.program.annotations.SupportedParameters; import mobac.program.atlascreators.impl.MapTileBuilder; import mobac.program.atlascreators.impl.MapTileWriter; import mobac.program.atlascreators.tileprovider.CacheTileProvider; import mobac.program.atlascreators.tileprovider.TileProvider; import mobac.program.interfaces.LayerInterface; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSpace; import mobac.program.interfaces.MapSpace.ProjectionCategory; import mobac.program.model.TileImageParameters.Name; import mobac.utilities.Utilities; /** * AtlasCreator for MAPLORER ( http://maplorer.com ) * * @author Werner Keilholz */ @AtlasCreatorName("Maplorer atlas format") @SupportedParameters(names = { Name.format }) public class Maplorer extends AtlasCreator { private static final String FILENAME_PATTERN = "map_%s%d.%s"; protected File layerFolder = null; protected File mapFolder = null; protected MapTileWriter mapTileWriter; protected int tileXmax = 0; protected int tileYmax = 0; public boolean testMapSource(MapSource mapSource) { MapSpace mapSpace = mapSource.getMapSpace(); return (mapSpace instanceof MercatorPower2MapSpace && ProjectionCategory.SPHERE.equals(mapSpace .getProjectionCategory())); } protected void createCustomTiles() throws InterruptedException, MapCreationException { log.debug("Starting map creation using custom parameters: " + parameters); CacheTileProvider ctp = new CacheTileProvider(mapDlTileProvider); try { mapDlTileProvider = ctp; MapTileBuilder mapTileBuilder = new MapTileBuilder(this, mapTileWriter, true); atlasProgress.initMapCreation(mapTileBuilder.getCustomTileCount()); mapTileBuilder.createTiles(); } finally { ctp.cleanup(); } } public void createMap() throws MapCreationException, InterruptedException { try { Utilities.mkDirs(mapFolder); mapTileWriter = new FileTileWriter(); // Select the tile creator instance based on whether tile image // parameters has been set or not if (parameters != null) createCustomTiles(); else createTiles(); mapTileWriter.finalizeMap(); } catch (MapCreationException e) { throw e; } catch (InterruptedException e) { throw e; } catch (Exception e) { throw new MapCreationException(map, e); } } @Override public void initializeMap(MapInterface map, TileProvider mapTileProvider) { super.initializeMap(map, mapTileProvider); LayerInterface layer = map.getLayer(); layerFolder = new File(atlasDir, layer.getName()); mapFolder = new File(layerFolder, map.getName()); } protected void createTiles() throws InterruptedException, MapCreationException { int tilex = 0; int tiley = 0; atlasProgress.initMapCreation((xMax - xMin + 1) * (yMax - yMin + 1)); ImageIO.setUseCache(false); byte[] emptyTileData = Utilities.createEmptyTileData(mapSource); String tileType = mapSource.getTileImageType().getFileExt(); for (int x = xMin; x <= xMax; x++) { tiley = 0; for (int y = yMin; y <= yMax; y++) { checkUserAbort(); atlasProgress.incMapCreationProgress(); try { byte[] sourceTileData = mapDlTileProvider.getTileData(x, y); if (sourceTileData != null) { mapTileWriter.writeTile(tilex, tiley, tileType, sourceTileData); } else { log.trace(String.format("Tile x=%d y=%d not found in tile archive - creating default", tilex, tiley)); mapTileWriter.writeTile(tilex, tiley, tileType, emptyTileData); } } catch (IOException e) { throw new MapCreationException("Error writing tile image: " + e.getMessage(), map, e); } tiley++; } tilex++; } } public class FileTileWriter implements MapTileWriter { File setFolder; int tileHeight = 256; int tileWidth = 256; public FileTileWriter() throws IOException { super(); setFolder = mapFolder; // don't need an extra sub folder for MAPLORER maps log.debug("Writing tiles to set folder: " + setFolder); if (parameters != null) { tileHeight = parameters.getHeight(); tileWidth = parameters.getWidth(); } } public void writeTile(int tilex, int tiley, String imageFormat, byte[] tileData) throws IOException { String tileFileName = String.format(FILENAME_PATTERN, IntToLetter(tilex + 1), tiley + 1, imageFormat); File f = new File(setFolder, tileFileName); FileOutputStream out = new FileOutputStream(f); try { out.write(tileData); } finally { Utilities.closeStream(out); } tileXmax = tilex; tileYmax = tiley; } private String IntToLetter(int i) throws IOException { if (i > 26) throw new IOException("Maximum tile column overflow - map too wide!"); char c = (char) (i + 64); return Character.toString(c); } public void finalizeMap() throws IOException { MapSpace mapSpace = mapSource.getMapSpace(); // compute corner coordinates for the entire map (all .JPG files) double longitudeMin = mapSpace.cXToLon(xMin * tileSize, zoom); double longitudeMax = mapSpace.cXToLon((xMax + 1) * tileSize - 1, zoom); double latitudeMin = mapSpace.cYToLat((yMax + 1) * tileSize - 1, zoom); double latitudeMax = mapSpace.cYToLat(yMin * tileSize, zoom); double widthInPixel = map.getMaxTileCoordinate().x - map.getMinTileCoordinate().x; double heihgtInPixel = map.getMaxTileCoordinate().y - map.getMinTileCoordinate().y; double pix2longitude = (longitudeMax - longitudeMin) / widthInPixel; double pix2latitude = (latitudeMax - latitudeMin) / heihgtInPixel; // compute corner coordinates for one tile (one JPG file) double lonBL = longitudeMin; double latBL = latitudeMax - tileHeight * pix2latitude; double lonTR = longitudeMin + tileWidth * pix2longitude; double latTR = latitudeMax; // write POS files for (int tilex = 0; tilex <= tileXmax; tilex++) { latBL = latitudeMax - tileHeight * pix2latitude; latTR = latitudeMax; for (int tiley = 0; tiley <= tileYmax; tiley++) { String posFileName = String.format(FILENAME_PATTERN, IntToLetter(tilex + 1), tiley + 1, "POS"); File posFile = new File(setFolder, posFileName); lonBL = Math.max(longitudeMin, lonBL); // for tiles at the edges (might be smaller) latBL = Math.max(latitudeMin, latBL); lonTR = Math.min(longitudeMax, lonTR); latTR = Math.min(latitudeMax, latTR); FileWriter outFile = new FileWriter(posFile); try { PrintWriter out2 = new PrintWriter(outFile); String posLine = "LonBL = %2.6f"; out2.println(String.format(Locale.ENGLISH, posLine, lonBL)); posLine = "LatBL = %2.6f"; out2.println(String.format(Locale.ENGLISH, posLine, latBL)); posLine = "LonTR = %2.6f"; out2.println(String.format(Locale.ENGLISH, posLine, lonTR)); posLine = "LatTR = %2.6f"; out2.println(String.format(Locale.ENGLISH, posLine, latTR)); out2.close(); } finally { Utilities.closeWriter(outFile); } latBL = latBL - tileHeight * pix2latitude; latTR = latTR - tileHeight * pix2latitude; } // for y lonBL = lonBL + tileWidth * pix2longitude; lonTR = lonTR + tileWidth * pix2longitude; } // for x } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/NFComPass.java0000644000175000017500000001442212122526606031220 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.Writer; import mobac.exceptions.MapCreationException; import mobac.mapsources.mapspace.MercatorPower2MapSpace; import mobac.program.annotations.AtlasCreatorName; import mobac.program.annotations.SupportedParameters; import mobac.program.atlascreators.impl.MapTileBuilder; import mobac.program.atlascreators.impl.MapTileWriter; import mobac.program.atlascreators.tileprovider.CacheTileProvider; import mobac.program.atlascreators.tileprovider.TileProvider; import mobac.program.interfaces.LayerInterface; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSpace; import mobac.program.interfaces.MapSpace.ProjectionCategory; import mobac.program.model.TileImageFormat; import mobac.program.model.TileImageParameters; import mobac.program.model.TileImageParameters.Name; import mobac.program.tiledatawriter.TileImagePngDataWriter; import mobac.utilities.Utilities; @AtlasCreatorName(value = "nfComPass") @SupportedParameters(names = { Name.height, Name.width }) public class NFComPass extends AtlasCreator { private File layerDir; private File mapDir; @Override public void initializeMap(MapInterface map, TileProvider mapTileProvider) { super.initializeMap(map, mapTileProvider); LayerInterface layer = map.getLayer(); layerDir = new File(atlasDir, layer.getName()); mapDir = new File(layerDir, map.getName()); if (parameters == null) { parameters = new TileImageParameters(64, 64, TileImageFormat.PNG); } } @Override public boolean testMapSource(MapSource mapSource) { MapSpace mapSpace = mapSource.getMapSpace(); return (mapSpace instanceof MercatorPower2MapSpace && ProjectionCategory.SPHERE.equals(mapSpace .getProjectionCategory())); } @Override public void initLayerCreation(LayerInterface layer) throws IOException { super.initLayerCreation(layer); if (layer.getMapCount() == 0) return; int lastZoom = layer.getMap(0).getZoom(); Writer w = new BufferedWriter(new FileWriter(new File(atlasDir, "nfComPass.dat"), true)); w.append("[" + layer.getName() + "]\r\n"); w.append("SIZEXY = extern\r\n"); w.append("MAPPATH =\r\n"); w.append("VMAX = 160\r\n"); w.append("WIDTH = 5\r\n"); w.append("LASTZOOM = " + lastZoom + "\r\n\r\n"); w.flush(); w.close(); } @Override public void createMap() throws MapCreationException, InterruptedException { try { Utilities.mkDirs(mapDir); } catch (IOException e) { throw new MapCreationException(map, e); } createKalFile(map); CacheTileProvider ctp = new CacheTileProvider(mapDlTileProvider); try { mapDlTileProvider = ctp; MapTileBuilder mapTileBuilder = new MapTileBuilder(this, new TileImagePngDataWriter(), new NFCompassTileWriter(), true); atlasProgress.initMapCreation(mapTileBuilder.getCustomTileCount()); mapTileBuilder.createTiles(); } finally { ctp.cleanup(); } } protected void createKalFile(MapInterface map) throws MapCreationException { Writer w = null; MapSpace mapSpace = map.getMapSource().getMapSpace(); double longitudeMin = mapSpace.cXToLon(xMin * tileSize, zoom); double longitudeMax = mapSpace.cXToLon((xMax + 1) * tileSize - 1, zoom); double latitudeMin = mapSpace.cYToLat((yMax + 1) * tileSize - 1, zoom); double latitudeMax = mapSpace.cYToLat(yMin * tileSize, zoom); int width = (xMax - xMin + 1) * tileSize; int height = (yMax - yMin + 1) * tileSize; try { w = new BufferedWriter(new FileWriter(new File(mapDir, map.getName() + ".kal"), true)); w.append("[" + map.getName() + "]\r\n"); w.append(String.format("TILEXY = %dx%d\r\n", parameters.getWidth(), parameters.getHeight())); w.append("X0LON = " + longitudeMin + "\r\n"); w.append("Y0LAT = " + latitudeMax + "\r\n"); w.append("X1LON = " + longitudeMax + "\r\n"); w.append("Y1LAT = " + latitudeMin + "\r\n"); w.append(String.format("SIZEXY = %dx%d\r\n", width, height)); w.flush(); } catch (IOException e) { throw new MapCreationException(map, e); } finally { Utilities.closeWriter(w); } } public class NFCompassTileWriter implements MapTileWriter { int tileHeight = 256; int tileWidth = 256; int ff_x; int ff_y; public NFCompassTileWriter() { super(); if (parameters != null) { tileHeight = parameters.getHeight(); tileWidth = parameters.getWidth(); } int highest_bit_x = Utilities.getHighestBitSet(tileWidth) + 2; int highest_bit_y = Utilities.getHighestBitSet(tileHeight) + 2; ff_x = Integer.MAX_VALUE << (highest_bit_x); ff_y = Integer.MAX_VALUE << (highest_bit_y); } public void writeTile(int tilex, int tiley, String tileType, byte[] tileData) throws IOException { int x = tilex * tileWidth; int y = tiley * tileHeight; String folderName = String.format("%dx%d", (x & ff_x), (y & ff_y)); String tileFileName = String.format("%d_%d.png", x, y); File folder = new File(mapDir, folderName); Utilities.mkDir(folder); File f = new File(folder, tileFileName); FileOutputStream out = new FileOutputStream(f); try { out.write(tileData); } finally { Utilities.closeStream(out); } } public void finalizeMap() throws IOException { } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/GarminCustom.java0000644000175000017500000000670112122526606032040 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.awt.image.BufferedImage; import java.io.IOException; import mobac.exceptions.AtlasTestException; import mobac.exceptions.MapCreationException; import mobac.program.annotations.AtlasCreatorName; import mobac.program.annotations.SupportedParameters; import mobac.program.interfaces.LayerInterface; import mobac.program.model.Settings; import mobac.program.model.TileImageParameters.Name; import mobac.program.tiledatawriter.TileImageJpegDataWriter; import mobac.utilities.stream.ArrayOutputStream; @AtlasCreatorName("Garmin Custom Map (KMZ)") @SupportedParameters(names = { Name.format_jpg }) public class GarminCustom extends GoogleEarthOverlay { /** * Each jpeg should be less than 3MB. https://forums.garmin.com/showthread.php?t=2646 */ private static final int MAX_FILE_SIZE = 3 * 1024 * 1024; @Override protected void testAtlas() throws AtlasTestException { int maxMap = Settings.getInstance().atlasFormatSpecificSettings.garminCustomMaxMapCount; for (LayerInterface layer : atlas) { if (layer.getMapCount() > maxMap) throw new AtlasTestException("Layer exceeeds the maximum map count of " + maxMap, layer); } } @Override protected void writeTileImage(BufferedImage tileImage) throws MapCreationException { try { TileImageJpegDataWriter writer; if (parameters != null) { writer = (TileImageJpegDataWriter) parameters.getFormat().getDataWriter(); writer = new TileImageJpegDataWriter(writer); } else writer = new TileImageJpegDataWriter(0.9); writer.initialize(); // The maximum file size for the jpg image is 3 MB // This OutputStream will fail if the resulting image is larger than // 3 MB - then we retry using a higher JPEG compression level ArrayOutputStream buf = new ArrayOutputStream(MAX_FILE_SIZE); byte[] data = null; for (int c = 99; c > 50; c -= 5) { buf.reset(); try { writer.processImage(tileImage, buf); data = buf.toByteArray(); break; } catch (IOException e) { log.trace("Image size too large, increasing compression to " + c); } writer.setJpegCompressionLevel(c / 100f); } if (data == null) throw new MapCreationException("Unable to create an image with less than 3 MB!", map); String imageFileName = "files/" + cleanedMapName + "." + writer.getType(); kmzOutputStream.writeStoredEntry(imageFileName, data); addMapToKmz(imageFileName); } catch (Exception e) { throw new MapCreationException(map, e); } } @Override protected int getMaxImageSize() { return 1024; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/PaperAtlasPdf.java0000644000175000017500000000767612122526606032132 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.awt.Color; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import mobac.exceptions.MapCreationException; import mobac.program.ProgramInfo; import mobac.program.annotations.AtlasCreatorName; import mobac.program.model.UnitSystem; import com.itextpdf.text.BadElementException; import com.itextpdf.text.Document; import com.itextpdf.text.DocumentException; import com.itextpdf.text.Image; import com.itextpdf.text.Rectangle; import com.itextpdf.text.pdf.PdfWriter; @AtlasCreatorName(value = "Paper Atlas (PDF)") public class PaperAtlasPdf extends PaperAtlas { private Document document; public PaperAtlasPdf() { super(false); } private Document createDocument(Rectangle r) throws MapCreationException { File pdfFile = new File(getLayerFolder(), map.getName() + ".pdf"); float left = (float) s.marginLeft; float right = (float) s.marginRight; float top = (float) s.marginTop; float bottom = (float) s.marginBottom; Document document = new Document(r, left, right, top, bottom); PdfWriter pdfWriter; try { pdfFile.createNewFile(); pdfWriter = PdfWriter.getInstance(document, new FileOutputStream(pdfFile)); } catch (IOException e) { throw new MapCreationException(map, e); } catch (DocumentException e) { throw new MapCreationException(map, e); } pdfWriter.setCompressionLevel(s.compression); document.open(); document.addAuthor(ProgramInfo.PROG_NAME); document.addCreationDate(); document.addCreator(ProgramInfo.PROG_NAME); document.addProducer(); return document; } @Override public void createMap() throws MapCreationException, InterruptedException { if (s.paperSize != null) { document = createDocument(s.paperSize.createRectangle()); } try { super.createMap(); } finally { try { document.close(); } catch (Exception e) { new MapCreationException(map, e); } document = null; } } @Override protected void processPage(BufferedImage image, int pageNumber) throws MapCreationException { int imageWidth = image.getWidth(); int imageHeight = image.getHeight(); if (document == null) { double width = UnitSystem.pixelsToPoints(imageWidth, s.dpi); double height = UnitSystem.pixelsToPoints(imageHeight, s.dpi); width += s.marginLeft + s.marginRight; height += s.marginTop + s.marginBottom; Rectangle r = new Rectangle((float) width, (float) height); document = createDocument(r); } Image iTextImage; try { iTextImage = Image.getInstance(image, Color.WHITE); } catch (BadElementException e) { throw new MapCreationException(map, e); } catch (IOException e) { throw new MapCreationException(map, e); } iTextImage.setCompressionLevel(s.compression); iTextImage.setDpi(s.dpi, s.dpi); float width = (float) UnitSystem.pixelsToPoints(imageWidth, s.dpi); float height = (float) UnitSystem.pixelsToPoints(imageHeight, s.dpi); iTextImage.scaleAbsolute(width, height); try { document.add(iTextImage); } catch (DocumentException e) { throw new MapCreationException(map, e); } document.newPage(); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/tileprovider/0000755000175000017500000000000012122526606031271 5ustar paulliupaulliu././@LongLink0000000000000000000000000000016000000000000011562 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/tileprovider/MapSourceProvider.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/tileprovider/MapSourcePr0000644000175000017500000000477312122526606033427 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators.tileprovider; import java.awt.image.BufferedImage; import java.io.IOException; import mobac.exceptions.TileException; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSource.LoadMethod; /** * A {@link TileProvider} implementation that retrieves all tiles directly from the {@link MapSource}. */ public class MapSourceProvider implements TileProvider { protected final MapSource mapSource; protected final int zoom; protected final LoadMethod loadMethod; /** * * @param mapSource * @param zoom * @param loadMethod * defines if the tile should be taken from tile cache or from it's original source (web server, * generated...). */ public MapSourceProvider(MapSource mapSource, int zoom, LoadMethod loadMethod) { super(); this.mapSource = mapSource; this.zoom = zoom; this.loadMethod = loadMethod; } public byte[] getTileData(int x, int y) throws IOException { try { return mapSource.getTileData(zoom, x, y, loadMethod); } catch (TileException e) { throw new IOException(e); } catch (InterruptedException e) { throw new RuntimeException(e); } } public BufferedImage getTileImage(int x, int y) throws IOException { try { return mapSource.getTileImage(zoom, x, y, loadMethod); } catch (TileException e) { throw new IOException(e); } catch (InterruptedException e) { throw new RuntimeException(e); } } public boolean preferTileImageUsage() { return false; } public MapSource getMapSource() { return mapSource; } public int getZoom() { return zoom; } } ././@LongLink0000000000000000000000000000016500000000000011567 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/tileprovider/DownloadedTileProvider.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/tileprovider/DownloadedT0000644000175000017500000000451212122526606033422 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators.tileprovider; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.IOException; import javax.imageio.ImageIO; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSource; import mobac.program.model.TileImageType; import mobac.utilities.tar.TarIndex; import org.apache.log4j.Logger; public class DownloadedTileProvider implements TileProvider { private static final Logger log = Logger.getLogger(DownloadedTileProvider.class); public static final String TILE_FILENAME_PATTERN = "x%dy%d"; protected final TarIndex tarIndex; protected final MapInterface map; protected final TileImageType mapTileType; public DownloadedTileProvider(TarIndex tarIndex, MapInterface map) { this.tarIndex = tarIndex; this.map = map; this.mapTileType = map.getMapSource().getTileImageType(); } public byte[] getTileData(int x, int y) throws IOException { log.trace("Reading tile x=" + x + " y=" + y); return tarIndex.getEntryContent(String.format(TILE_FILENAME_PATTERN, x, y)); } public BufferedImage getTileImage(int x, int y) throws IOException { byte[] unconvertedTileData = getTileData(x, y); if (unconvertedTileData == null) return null; return ImageIO.read(new ByteArrayInputStream(unconvertedTileData)); } public boolean preferTileImageUsage() { return false; } public MapSource getMapSource() { return map.getMapSource(); } } ././@LongLink0000000000000000000000000000016500000000000011567 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/tileprovider/GpxPainterTileProvider.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/tileprovider/GpxPainterT0000644000175000017500000000420312122526606033420 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators.tileprovider; import java.awt.image.BufferedImage; import java.io.IOException; import mobac.data.gpx.gpx11.Gpx; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSpace; import mobac.program.model.TileImageFormat; /** * * Incomplete! * * TODO: Fully implement this class so that the content (points, tracks, ...) can be painted on each tile. If the * implementation is complete the {@link GpxPainterTileProvider} can be chained into the tile provider chain after the * {@link DownloadedTileProvider} (see AtlasThread line ~348). * * Problem: texts and lines that span multiple tiles. * */ public class GpxPainterTileProvider extends ConvertedRawTileProvider { private final MapSpace mapSpace; public GpxPainterTileProvider(MapSourceProvider tileProvider, TileImageFormat tileImageFormat, Gpx gpx) { super(tileProvider, tileImageFormat); int zoom = tileProvider.getZoom(); MapSource mapSource = tileProvider.getMapSource(); mapSpace = mapSource.getMapSpace(); // TODO Prepare GPX points } @Override public BufferedImage getTileImage(int x, int y) throws IOException { BufferedImage image = super.getTileImage(x, y); // TODO Perform GPX painting return image; } } ././@LongLink0000000000000000000000000000015600000000000011567 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/tileprovider/PngTileProvider.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/tileprovider/PngTileProv0000644000175000017500000000411012122526606033421 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators.tileprovider; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; import mobac.program.interfaces.TileImageDataWriter; import mobac.program.model.TileImageType; import mobac.program.tiledatawriter.TileImagePngDataWriter; import mobac.utilities.Utilities; /** * A tile provider for atlas formats that only allow PNG images. Each image processed is checked */ public class PngTileProvider extends FilterTileProvider { final TileImageDataWriter writer; public PngTileProvider(TileProvider tileProvider) { super(tileProvider); writer = new TileImagePngDataWriter(); writer.initialize(); } @Override public byte[] getTileData(int x, int y) throws IOException { if (!tileProvider.preferTileImageUsage()) { byte[] data = super.getTileData(x, y); if (Utilities.getImageType(data) == TileImageType.PNG) return data; } ByteArrayOutputStream buffer = new ByteArrayOutputStream(32000); BufferedImage image = getTileImage(x, y); if (image == null) return null; writer.processImage(image, buffer); return buffer.toByteArray(); } public boolean preferTileImageUsage() { return true; } } ././@LongLink0000000000000000000000000000016100000000000011563 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/tileprovider/FilterTileProvider.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/tileprovider/FilterTileP0000644000175000017500000000346412122526606033406 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators.tileprovider; import java.awt.image.BufferedImage; import java.io.IOException; import mobac.program.interfaces.MapSource; import org.apache.log4j.Logger; /** * Base implementation of an {@link TileProvider} that changes somehow the images, e.g. combines two layers to one or * paints something onto a tile image. */ public abstract class FilterTileProvider implements TileProvider { protected final Logger log; protected final TileProvider tileProvider; public FilterTileProvider(TileProvider tileProvider) { log = Logger.getLogger(this.getClass()); this.tileProvider = tileProvider; } public BufferedImage getTileImage(int x, int y) throws IOException { return tileProvider.getTileImage(x, y); } public byte[] getTileData(int x, int y) throws IOException { return tileProvider.getTileData(x, y); } public MapSource getMapSource() { return tileProvider.getMapSource(); } } ././@LongLink0000000000000000000000000000016000000000000011562 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/tileprovider/CacheTileProvider.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/tileprovider/CacheTilePr0000644000175000017500000001504512122526606033344 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators.tileprovider; import java.awt.image.BufferedImage; import java.io.IOException; import java.lang.ref.SoftReference; import java.util.Hashtable; import java.util.concurrent.LinkedBlockingQueue; import mobac.program.interfaces.MapSource; import org.apache.log4j.Logger; /** * A tile cache with speculative loading on a separate thread. Usually this decreases map generation time on multi-core * systems. */ public class CacheTileProvider implements TileProvider { private Logger log = Logger.getLogger(CacheTileProvider.class); /** * Counter for identifying the different threads */ private static int PRELOADER_THREAD_NUM = 1; private Hashtable cache; private PreLoadThread preLoader = new PreLoadThread(); protected final TileProvider tileProvider; public CacheTileProvider(TileProvider tileProvider) { this.tileProvider = tileProvider; cache = new Hashtable(500); preLoader.start(); } public boolean preferTileImageUsage() { return true; } public BufferedImage getTileImage(int x, int y) throws IOException { SRCachedTile cachedTile = cache.get(new CacheKey(x, y)); BufferedImage image = null; if (cachedTile != null) { CachedTile tile = cachedTile.get(); if (tile != null) { if (tile.loaded) log.trace(String.format("Cache hit: x=%d y=%d", x, y)); image = tile.getImage(); if (!tile.nextLoadJobCreated) { // log.debug(String.format("Preload job added : x=%d y=%d l=%d", // x + 1, y, layer)); preloadTile(new CachedTile(new CacheKey(x + 1, y))); tile.nextLoadJobCreated = true; } } } if (image == null) { log.trace(String.format("Cache miss: x=%d y=%d", x, y)); // log.debug(String.format("Preload job added : x=%d y=%d l=%d", x + // 1, y, layer)); preloadTile(new CachedTile(new CacheKey(x + 1, y))); image = internalGetTileImage(x, y); } return image; } protected BufferedImage internalGetTileImage(int x, int y) throws IOException { synchronized (tileProvider) { return tileProvider.getTileImage(x, y); } } public byte[] getTileData(int layer, int x, int y) throws IOException { throw new RuntimeException("Not implemented"); } public byte[] getTileData(int x, int y) throws IOException { throw new RuntimeException("Not implemented"); } public MapSource getMapSource() { return tileProvider.getMapSource(); } private void preloadTile(CachedTile tile) { if (preLoader.queue.remainingCapacity() < 1) { // Preloader thread is too slow log.trace("Preloading rejected: " + tile.key); return; } if (cache.get(tile.key) != null) return; try { preLoader.queue.add(tile); cache.put(tile.key, new SRCachedTile(tile)); } catch (IllegalStateException e) { // Queue is "full" log.trace("Preloading rejected: " + tile.key); } } public void cleanup() { try { cache.clear(); if (preLoader != null) { preLoader.interrupt(); preLoader = null; } } catch (Throwable t) { log.error("", t); } } @Override protected void finalize() throws Throwable { cleanup(); super.finalize(); } private static class SRCachedTile extends SoftReference { public SRCachedTile(CachedTile referent) { super(referent); } } private class PreLoadThread extends Thread { private LinkedBlockingQueue queue = null; public PreLoadThread() { super("ImagePreLoadThread" + (PRELOADER_THREAD_NUM++)); log.debug("Image pre-loader thread started"); // pre-loading more than 20 tiles doesn't make much sense queue = new LinkedBlockingQueue(20); } @Override public void run() { CachedTile tile; try { while (true) { tile = queue.take(); if (tile != null && !tile.loaded) { // log.trace("Loading image async: " + tile); tile.loadImage(); } } } catch (InterruptedException e) { log.debug("Image pre-loader thread terminated"); } } } private static class CacheKey { int x; int y; public CacheKey(int x, int y) { super(); this.x = x; this.y = y; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + x; result = prime * result + y; return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; CacheKey other = (CacheKey) obj; if (x != other.x) return false; if (y != other.y) return false; return true; } @Override public String toString() { return "CacheKey [x=" + x + ", y=" + y + "]"; } } private class CachedTile { CacheKey key; private BufferedImage image; private IOException loadException = null; boolean loaded = false; boolean nextLoadJobCreated = false; public CachedTile(CacheKey key) { super(); this.key = key; image = null; } public synchronized void loadImage() { try { image = internalGetTileImage(key.x, key.y); } catch (IOException e) { loadException = e; } catch (Exception e) { loadException = new IOException(e); } loaded = true; } public synchronized BufferedImage getImage() throws IOException { if (!loaded) loadImage(); if (loadException != null) throw loadException; return image; } @Override public String toString() { return "CachedTile [key=" + key + ", loaded=" + loaded + ", nextLoadJobCreated=" + nextLoadJobCreated + "]"; } } } ././@LongLink0000000000000000000000000000016700000000000011571 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/tileprovider/ConvertedRawTileProvider.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/tileprovider/ConvertedRa0000644000175000017500000000404012122526606033426 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators.tileprovider; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; import javax.imageio.ImageIO; import mobac.program.interfaces.TileImageDataWriter; import mobac.program.model.TileImageFormat; /** * Loads a tile from the underlying {@link TileProvider}, loads the tile to memory, converts it to the desired * {@link TileImageFormat} and returns the binary representation of the image in the specified format. */ public class ConvertedRawTileProvider extends FilterTileProvider { private TileImageDataWriter writer; public ConvertedRawTileProvider(TileProvider tileProvider, TileImageFormat tileImageFormat) { super(tileProvider); writer = tileImageFormat.getDataWriter(); writer.initialize(); ImageIO.setUseCache(false); } public byte[] getTileData(int x, int y) throws IOException { BufferedImage image = getTileImage(x, y); if (image == null) return null; ByteArrayOutputStream buffer = new ByteArrayOutputStream(32000); writer.processImage(image, buffer); return buffer.toByteArray(); } public boolean preferTileImageUsage() { return true; } } ././@LongLink0000000000000000000000000000015300000000000011564 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/tileprovider/TileProvider.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/tileprovider/TileProvide0000644000175000017500000000267412122526606033453 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators.tileprovider; import java.awt.image.BufferedImage; import java.io.IOException; import mobac.program.interfaces.MapSource; public interface TileProvider { public byte[] getTileData(int x, int y) throws IOException; public BufferedImage getTileImage(int x, int y) throws IOException; public MapSource getMapSource(); /** * Indicates if subsequent filter in the filter-chain should prefer the {@link #getTileImage(int, int)} or * {@link #getTileData(int, int)} method. * * @return */ public boolean preferTileImageUsage(); } ././@LongLink0000000000000000000000000000016400000000000011566 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/tileprovider/TileStoreTileProvider.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/tileprovider/TileStoreTi0000644000175000017500000000250612122526606033426 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators.tileprovider; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSource.LoadMethod; /** * A {@link TileProvider} implementation that retrieves all tiles from the tile store (if the mapSource * supports that). */ public class TileStoreTileProvider extends MapSourceProvider { public TileStoreTileProvider(MapSource mapSource, int zoom) { super(mapSource, zoom, LoadMethod.CACHE); } } ././@LongLink0000000000000000000000000000017000000000000011563 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/tileprovider/FilteredMapSourceProvider.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/tileprovider/FilteredMap0000644000175000017500000000460312122526606033413 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators.tileprovider; import java.awt.image.BufferedImage; import java.io.IOException; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSource.LoadMethod; import mobac.program.interfaces.TileFilter; /** * Based on a given {@link TileFilter} implementation an {@link FilteredMapSourceProvider} instance ignores certain * requests via {@link #getTileData(int, int)} and {@link #getTileImage(int, int)} and returns null * instead. * * This functionality is required especially for polygonal maps where certain tiles which are located outside of the * polygon should be ignored. */ public class FilteredMapSourceProvider extends MapSourceProvider { protected final TileFilter tileFilter; public FilteredMapSourceProvider(MapInterface map, LoadMethod loadMethod) { this(map.getMapSource(), map.getZoom(), loadMethod, map.getTileFilter()); } public FilteredMapSourceProvider(MapSource mapSource, int zoom, LoadMethod loadMethod, TileFilter tileFilter) { super(mapSource, zoom, loadMethod); this.tileFilter = tileFilter; } @Override public byte[] getTileData(int x, int y) throws IOException { if (!tileFilter.testTile(x, y, zoom, mapSource)) return null; return super.getTileData(x, y); } @Override public BufferedImage getTileImage(int x, int y) throws IOException { if (!tileFilter.testTile(x, y, zoom, mapSource)) return null; return super.getTileImage(x, y); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/BigPlanetTracks.java0000644000175000017500000000315212131416272032437 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import mobac.mapsources.mapspace.MercatorPower2MapSpace; import mobac.program.annotations.AtlasCreatorName; import mobac.program.interfaces.MapSource; /** * Atlas/Map creator for "BigPlanet-Maps application for Android" (offline SQLite maps) * http://code.google.com/p/bigplanet/ *

* Some source parts are taken from the "android-map.blogspot.com Version of Mobile Atlas Creator": * http://code.google.com/p/android-map/ *

*/ @AtlasCreatorName(value = "Big Planet Tracks SQLite", type = "BigPlanet") public class BigPlanetTracks extends RMapsSQLite { @Override public boolean testMapSource(MapSource mapSource) { return MercatorPower2MapSpace.INSTANCE_256.equals(mapSource.getMapSpace()); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/MGMaps.java0000644000175000017500000002261412122526606030555 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import java.io.RandomAccessFile; import javax.imageio.ImageIO; import mobac.exceptions.AtlasTestException; import mobac.exceptions.MapCreationException; import mobac.mapsources.mapspace.MercatorPower2MapSpace; import mobac.program.annotations.AtlasCreatorName; import mobac.program.annotations.SupportedParameters; import mobac.program.atlascreators.tileprovider.ConvertedRawTileProvider; import mobac.program.atlascreators.tileprovider.TileProvider; import mobac.program.interfaces.AtlasInterface; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSpace; import mobac.program.interfaces.MapSpace.ProjectionCategory; import mobac.program.interfaces.TileImageDataWriter; import mobac.program.model.TileImageParameters.Name; import mobac.utilities.Utilities; import mobac.utilities.stream.ArrayOutputStream; /** * Creates maps using the MGM pack file format (.mgm). * * Each zoom level in a different directory, 64 tiles per mgm file. * *

Format

*
    *
  • 2 bytes: number of tiles in this file for each tile (even for tiles that are not used, in which case the data is * left null)
  • *
  • 1 byte: tile x within this file; add tileX * tilesPerFileX to get global tile number
  • *
  • 1 byte: tile y within this file; add tileY * tilesPerFileY to get global tile number
  • *
  • 4 bytes: offset of the end of the tile data within this file (to get the offset for the start of the tile data, * subtract the value for the previous tile, or 2 + 6 * tilesPerFile tile data 1 tile data 2 ...
  • *
* * @author paour */ @AtlasCreatorName(value = "MGMaps/MyTrails (MGM)", type = "MGM") @SupportedParameters(names = { Name.format }) public class MGMaps extends AtlasCreator { private static final int TILES_PER_FILE_X = 8; private static final int TILES_PER_FILE_Y = 8; private static final int TILES_PER_FILE = TILES_PER_FILE_X * TILES_PER_FILE_Y; private double xResizeRatio = 1.0; private double yResizeRatio = 1.0; @Override public void startAtlasCreation(AtlasInterface atlas, File customAtlasDir) throws AtlasTestException, IOException, InterruptedException { super.startAtlasCreation(atlas, customAtlasDir); File cache_conf = new File(atlasDir, "cache.conf"); PrintWriter pw = new PrintWriter(new FileWriter(cache_conf)); try { pw.println("version=3"); pw.println("tiles_per_file=" + TILES_PER_FILE); pw.println("hash_size=1"); } finally { pw.close(); } } @Override public void initializeMap(final MapInterface map, final TileProvider mapTileProvider) { super.initializeMap(map, mapTileProvider); xResizeRatio = 1.0; yResizeRatio = 1.0; if (parameters != null) { int mapTileSize = map.getMapSource().getMapSpace().getTileSize(); if ((parameters.getWidth() != mapTileSize) || (parameters.getHeight() != mapTileSize)) { // handle image re-sampling + image re-sizing xResizeRatio = (double) parameters.getWidth() / (double) mapTileSize; yResizeRatio = (double) parameters.getHeight() / (double) mapTileSize; } else { // handle only image re-sampling mapDlTileProvider = new ConvertedRawTileProvider(mapDlTileProvider, parameters.getFormat()); } } } @Override public void createMap() throws MapCreationException, InterruptedException { MGMTileWriter mgmTileWriter = null; try { if ((xResizeRatio != 1.0) || (yResizeRatio != 1.0)) mgmTileWriter = new MGMResizeTileWriter(); else mgmTileWriter = new MGMTileWriter(); String name = map.getLayer().getName(); // safe naming: replace all non-word characters: [^a-zA-Z_0-9] name = name.replaceAll("[^a-zA-Z_0-9]", "_"); // crate directory if necessary File folder = new File(atlasDir, name + "_" + map.getZoom()); Utilities.mkDirs(folder); atlasProgress.initMapCreation((xMax - xMin + 1) * (yMax - yMin + 1)); ImageIO.setUseCache(false); int pxMin = xMin / TILES_PER_FILE_X; int pxMax = xMax / TILES_PER_FILE_X; int pyMin = yMin / TILES_PER_FILE_Y; int pyMax = yMax / TILES_PER_FILE_Y; for (int px = pxMin; px <= pxMax; px++) { for (int py = pyMin; py <= pyMax; py++) { int count = 0; int pos = 2 + TILES_PER_FILE * 6; File pack = new File(folder, px + "_" + py + ".mgm"); RandomAccessFile raf = null; try { for (int i = 0; i < TILES_PER_FILE_X; i++) { int x = px * TILES_PER_FILE_X + i; if (x < xMin || x > xMax) { continue; } for (int j = 0; j < TILES_PER_FILE_Y; j++) { int y = py * TILES_PER_FILE_Y + j; if (y < yMin || y > yMax) { continue; } if (raf == null) // Only create a file when needed raf = new RandomAccessFile(pack, "rw"); checkUserAbort(); atlasProgress.incMapCreationProgress(); int res = mgmTileWriter.writeTile(x, y, i, j, raf, pos, count); if (res >= 0) { pos = res; count++; } } } if (raf != null) { // POSITION 0: number of tiles raf.seek(0); raf.writeChar(count); } } finally { Utilities.closeFile(raf); } if (count == 0) { // the file doesn't contain any tiles if (pack.exists()) Utilities.deleteFile(pack); } } } } catch (Exception e) { throw new MapCreationException(map, e); } finally { if (mgmTileWriter != null) mgmTileWriter.dispose(); } } @Override public boolean testMapSource(final MapSource mapSource) { MapSpace mapSpace = mapSource.getMapSpace(); return (mapSpace instanceof MercatorPower2MapSpace) && (ProjectionCategory.SPHERE.equals(mapSource.getMapSpace().getProjectionCategory()) || ProjectionCategory.ELLIPSOID .equals(mapSource.getMapSpace().getProjectionCategory())); } /** * Simply writes the tile to the file without resizing */ private class MGMTileWriter { protected byte[] getSourceTileData(int x, int y) throws IOException { return mapDlTileProvider.getTileData(x, y); } public int writeTile(int x, int y, int i, int j, RandomAccessFile raf, int startPos, int count) throws MapCreationException { try { byte[] sourceTileData = getSourceTileData(x, y); if (sourceTileData == null) return -1; raf.seek(startPos); raf.write(sourceTileData); // write the tile index raf.seek(2 + count * 6); raf.writeByte(i); raf.writeByte(j); int pos = startPos + sourceTileData.length; raf.writeInt(pos); return pos; } catch (IOException e) { throw new MapCreationException("Error writing tile image: " + e.getMessage(), map, e); } } public void dispose() { // Nothing to do } } /** * Resizes the tile and saves it to the file */ private class MGMResizeTileWriter extends MGMTileWriter { private final BufferedImage tileImage; private final Graphics2D graphics; private final TileImageDataWriter writer; private final ArrayOutputStream buffer; public MGMResizeTileWriter() { // resize image tileImage = new BufferedImage(parameters.getWidth(), parameters.getHeight(), BufferedImage.TYPE_3BYTE_BGR); // associated graphics with affine transform graphics = tileImage.createGraphics(); graphics.setTransform(AffineTransform.getScaleInstance(xResizeRatio, yResizeRatio)); graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); // image compression writer writer = parameters.getFormat().getDataWriter(); // buffer to store compressed image buffer = new ArrayOutputStream(3 * parameters.getWidth() * parameters.getHeight()); } @Override protected byte[] getSourceTileData(int x, int y) throws IOException { // need to resize the tile final BufferedImage tile = mapDlTileProvider.getTileImage(x, y); graphics.drawImage(tile, 0, 0, null); buffer.reset(); writer.initialize(); writer.processImage(tileImage, buffer); byte[] processedTileData = buffer.toByteArray(); buffer.reset(); return processedTileData; } @Override public void dispose() { buffer.reset(); graphics.dispose(); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/TileStoreDownload.java0000644000175000017500000000257512122526604033035 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import mobac.exceptions.MapCreationException; import mobac.program.annotations.AtlasCreatorName; import mobac.program.interfaces.MapSource; @AtlasCreatorName(value = "Tile store download only", type = "TILESTORE") public class TileStoreDownload extends AtlasCreator { public TileStoreDownload() { } @Override public boolean testMapSource(MapSource mapSource) { return true; } @Override public void createMap() throws MapCreationException, InterruptedException { } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/atlascreators/AtlasCreator.java0000644000175000017500000002027412127544344032021 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.atlascreators; import java.io.File; import java.io.IOException; import java.nio.charset.Charset; import java.text.SimpleDateFormat; import java.util.Date; import java.util.EnumSet; import mobac.exceptions.AtlasTestException; import mobac.exceptions.MapCreationException; import mobac.gui.AtlasProgress; import mobac.program.AtlasThread; import mobac.program.PauseResumeHandler; import mobac.program.atlascreators.tileprovider.TileProvider; import mobac.program.interfaces.AtlasInterface; import mobac.program.interfaces.LayerInterface; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSource; import mobac.program.model.AtlasOutputFormat; import mobac.program.model.Settings; import mobac.program.model.TileImageFormat; import mobac.program.model.TileImageParameters; import mobac.utilities.Charsets; import mobac.utilities.Utilities; import org.apache.log4j.Logger; /** * Abstract base class for all AtlasCreator implementations. * * The general call schema is as follows: *
    *
  1. AtlasCreator instantiation via {@link AtlasOutputFormat#createAtlasCreatorInstance()}
  2. *
  3. AtlasCreator atlas initialization via {@link #startAtlasCreation(AtlasInterface, File)}
  4. *
  5. 1 to n times {@link #initializeMap(MapInterface, TileProvider)} followed by {@link #createMap()}
  6. *
  7. AtlasCreator atlas finalization via {@link #finishAtlasCreation()}
  8. *
*/ public abstract class AtlasCreator { public static final Charset TEXT_FILE_CHARSET = Charsets.ISO_8859_1; protected final Logger log; /************************************************************/ /** atlas specific fields **/ /************************************************************/ protected AtlasInterface atlas; protected File atlasDir; protected AtlasProgress atlasProgress = null; protected PauseResumeHandler pauseResumeHandler = null; /************************************************************/ /** map specific fields **/ /************************************************************/ protected MapInterface map; protected int xMin; protected int xMax; protected int yMin; protected int yMax; protected int zoom; protected MapSource mapSource; protected int tileSize; /** * Custom tile processing parameters. null if disabled in GUI */ protected TileImageParameters parameters; protected AtlasOutputFormat atlasOutputFormat; protected TileProvider mapDlTileProvider; private boolean aborted = false; /** * Default constructor - initializes the logging environment */ protected AtlasCreator() { log = Logger.getLogger(this.getClass()); }; /** * @param customAtlasDir * if not null the customAtlasDir is used instead of the generated atlas directory name * @throws InterruptedException * @see AtlasCreator */ public void startAtlasCreation(AtlasInterface atlas, File customAtlasDir) throws AtlasTestException, IOException, InterruptedException { this.atlas = atlas; testAtlas(); if (customAtlasDir == null) { // No explicit atlas output directory has been set - generate a new directory name SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd_HHmmss"); String atlasDirName = atlas.getName() + "_" + sdf.format(new Date()); File atlasOutputDir = Settings.getInstance().getAtlasOutputDirectory(); atlasDir = new File(atlasOutputDir, atlasDirName); } else atlasDir = customAtlasDir; Utilities.mkDirs(atlasDir); } protected void testAtlas() throws AtlasTestException { } public void initLayerCreation(LayerInterface layer) throws IOException { } public void finishLayerCreation() throws IOException { } /** * @throws InterruptedException * @see AtlasCreator */ public void finishAtlasCreation() throws IOException, InterruptedException { } public void abortAtlasCreation() throws IOException { this.aborted = true; } public boolean isAborted() { return aborted; } /** * Test if the {@link AtlasCreator} instance supports the selected {@link MapSource} * * @param mapSource * @return true if supported otherwise false * @see AtlasCreator */ public abstract boolean testMapSource(MapSource mapSource); /** * @see AtlasCreator */ public void initializeMap(MapInterface map, TileProvider mapTileProvider) { LayerInterface layer = map.getLayer(); if (mapTileProvider == null) throw new NullPointerException(); this.mapDlTileProvider = mapTileProvider; this.map = map; this.mapSource = map.getMapSource(); this.tileSize = mapSource.getMapSpace().getTileSize(); this.parameters = map.getParameters(); xMin = map.getMinTileCoordinate().x / tileSize; xMax = map.getMaxTileCoordinate().x / tileSize; yMin = map.getMinTileCoordinate().y / tileSize; yMax = map.getMaxTileCoordinate().y / tileSize; this.zoom = map.getZoom(); this.atlasOutputFormat = layer.getAtlas().getOutputFormat(); Thread t = Thread.currentThread(); if (!(t instanceof AtlasThread)) throw new RuntimeException("Calling thread must be AtlasThread!"); AtlasThread at = (AtlasThread) t; atlasProgress = at.getAtlasProgress(); pauseResumeHandler = at.getPauseResumeHandler(); } /** * @throws InterruptedException * @see AtlasCreator */ public abstract void createMap() throws MapCreationException, InterruptedException; /** * Checks if the user has aborted atlas creation and if true an {@link InterruptedException} is thrown. * * @throws InterruptedException */ public void checkUserAbort() throws InterruptedException { if (Thread.currentThread().isInterrupted()) throw new InterruptedException(); pauseResumeHandler.pauseWait(); } public AtlasProgress getAtlasProgress() { return atlasProgress; } public int getXMin() { return xMin; } public int getXMax() { return xMax; } public int getYMin() { return yMin; } public int getYMax() { return yMax; } public MapInterface getMap() { return map; } public TileImageParameters getParameters() { return parameters; } public TileProvider getMapDlTileProvider() { return mapDlTileProvider; } /** * Tests all maps of the currently active atlas if a custom tile image format has been specified and if the * specified format is equal to the allowedFormat. * * @param allowedFormat * @throws AtlasTestException */ protected void performTest_AtlasTileFormat(EnumSet allowedFormats) throws AtlasTestException { for (LayerInterface layer : atlas) { for (MapInterface map : layer) { TileImageParameters parameters = map.getParameters(); if (parameters == null) continue; if (!allowedFormats.contains(parameters.getFormat())) throw new AtlasTestException( "Selected custom tile format not supported - only the following format(s) are supported: " + allowedFormats, map); } } } protected void performTest_MaxMapZoom(int maxZoom) throws AtlasTestException { for (LayerInterface layer : atlas) { for (MapInterface map : layer) { if (map.getZoom() > maxZoom) throw new AtlasTestException("Maximum zoom is " + maxZoom + " for this atlas format", map); } } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/EnvironmentSetup.java0000644000175000017500000001472412134265562030116 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program; import java.io.File; import java.io.FileFilter; import java.io.IOException; import java.util.Locale; import javax.swing.JOptionPane; import mobac.mapsources.MapSourcesManager; import mobac.program.interfaces.MapSource; import mobac.program.model.Atlas; import mobac.program.model.EastNorthCoordinate; import mobac.program.model.Layer; import mobac.program.model.Profile; import mobac.program.model.Settings; import mobac.utilities.GUIExceptionHandler; import mobac.utilities.I18nUtils; import mobac.utilities.Utilities; import mobac.utilities.file.FileExtFilter; import mobac.utilities.file.NamePatternFileFilter; import org.apache.commons.io.FileUtils; import org.apache.log4j.Logger; /** * Creates the necessary files on first time Mobile Atlas Creator is started or tries to update the environment if the * version has changed. */ public class EnvironmentSetup { private static boolean FIRST_START = false; public static Logger log = Logger.getLogger(EnvironmentSetup.class); public static void checkMemory() { Runtime r = Runtime.getRuntime(); long maxHeap = r.maxMemory(); String heapMBFormatted = String.format(Locale.ENGLISH, "%3.2f MiB", maxHeap / 1048576d); log.info("Total available memory to MOBAC: " + heapMBFormatted); if (maxHeap < 200000000) { String msg = String.format(I18nUtils.localizedStringForKey("msg_environment_lack_memory"), heapMBFormatted); JOptionPane.showMessageDialog(null, msg, I18nUtils.localizedStringForKey("msg_environment_lack_memory_title"), JOptionPane.WARNING_MESSAGE); } } public static void upgrade() { FileFilter ff = new NamePatternFileFilter("tac-profile-.*.xml"); File profilesDir = DirectoryManager.currentDir; File[] files = profilesDir.listFiles(ff); for (File f : files) { File dest = new File(profilesDir, f.getName().replaceFirst("tac-", "mobac-")); f.renameTo(dest); } } /** * In case the mapsources directory has been moved by configuration (directories.ini or settings.xml) we * need to copy the existing map packs into the configured directory */ public static void copyMapPacks() { File userMapSourcesDir = Settings.getInstance().getMapSourcesDirectory(); File progMapSourcesDir = new File(DirectoryManager.programDir, "mapsources"); if (userMapSourcesDir.equals(progMapSourcesDir)) return; // no user specific directory configured if (userMapSourcesDir.isDirectory()) return; // directory already exists - map packs should have been already copied try { Utilities.mkDirs(userMapSourcesDir); FileUtils.copyDirectory(progMapSourcesDir, userMapSourcesDir, new FileExtFilter(".jar")); } catch (IOException e) { log.error(e); JOptionPane.showMessageDialog(null, I18nUtils.localizedStringForKey("msg_environment_error_init_mapsrc_dir") + e.getMessage(), I18nUtils.localizedStringForKey("Error"), JOptionPane.ERROR_MESSAGE); System.exit(1); } } /** * Note: This method has be be called before {@link Settings#loadOrQuit()}. Therefore no localization is available at * this point. */ public static void checkFileSetup() { checkDirectory(DirectoryManager.userSettingsDir, "user settings", true); checkDirectory(DirectoryManager.atlasProfilesDir, "atlas profile", true); checkDirectory(DirectoryManager.tileStoreDir, "tile store", true); checkDirectory(DirectoryManager.tempDir, "temporary atlas download", true); if (!Settings.FILE.exists()) { try { FIRST_START = true; Settings.save(); } catch (Exception e) { log.error("Error while creating settings.xml: " + e.getMessage(), e); String[] options = { "Exit", "Show error report" }; int a = JOptionPane.showOptionDialog(null, "Could not create file settings.xml - program will exit.", "Error", 0, JOptionPane.ERROR_MESSAGE, null, options, options[0]); if (a == 1) GUIExceptionHandler.showExceptionDialog(e); System.exit(1); } } } protected static void checkDirectory(File dir, String dirName, boolean checkIsWriteable) { try { Utilities.mkDirs(dir); } catch (IOException e) { GUIExceptionHandler.processFatalExceptionSimpleDialog( String.format(I18nUtils.localizedStringForKey("msg_environment_error_create_dir"), dirName, dir.getAbsolutePath()), e); } if (!checkIsWriteable) return; try { // test if we can write into that directory File testFile = File.createTempFile("MOBAC", "", dir); testFile.createNewFile(); testFile.deleteOnExit(); testFile.delete(); } catch (IOException e) { GUIExceptionHandler.processFatalExceptionSimpleDialog( String.format(I18nUtils.localizedStringForKey("msg_environment_error_write_file"), dirName, dir.getAbsolutePath()), e); } } public static void createDefaultAtlases() { if (!FIRST_START) return; // TODO:MP change sample to Chinese Profile p = new Profile("Google Maps New York"); Atlas atlas = Atlas.newInstance(); try { EastNorthCoordinate max = new EastNorthCoordinate(40.97264, -74.142609); EastNorthCoordinate min = new EastNorthCoordinate(40.541982, -73.699036); Layer layer = new Layer(atlas, "GM New York"); MapSource ms = MapSourcesManager.getInstance().getSourceByName("Mapnik"); if (ms == null) return; layer.addMapsAutocut("GM New York 16", ms, max, min, 16, null, 32000); layer.addMapsAutocut("GM New York 14", ms, max, min, 14, null, 32000); atlas.addLayer(layer); p.save(atlas); } catch (Exception e) { log.error("Creation for example profiles failed", e); GUIExceptionHandler.showExceptionDialog(e); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/tilefilter/0000755000175000017500000000000012122526604026053 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/tilefilter/PolygonTileFilter.java0000644000175000017500000000352412122526604032335 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.tilefilter; import java.awt.Polygon; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.TileFilter; import mobac.program.model.MapPolygon; public class PolygonTileFilter implements TileFilter { private final Polygon polygon; private final int tileSize; private final int polygonZoom; public PolygonTileFilter(MapPolygon map) { this(map.getPolygon(), map.getZoom(), map.getMapSource()); } public PolygonTileFilter(Polygon polygon, int polygonZoom, MapSource mapSource) { super(); this.polygon = polygon; this.polygonZoom = polygonZoom; this.tileSize = mapSource.getMapSpace().getTileSize(); } public boolean testTile(int x, int y, int zoom, MapSource mapSource) { if (polygonZoom != zoom) throw new RuntimeException("Wrong zoom level!"); int tileCoordinateX = x * tileSize; int tileCoordinateY = y * tileSize; return polygon.intersects(tileCoordinateX, tileCoordinateY, tileSize, tileSize); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/tilefilter/DummyTileFilter.java0000644000175000017500000000231312122526604031774 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.tilefilter; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.TileFilter; /** * Dummy tile filter - always returns true for any tile. */ public class DummyTileFilter implements TileFilter { public boolean testTile(int x, int y, int zoom, MapSource mapSource) { return true; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/ProgramInfo.java0000644000175000017500000000660012122526604027000 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program; import java.io.InputStream; import java.util.Properties; import mobac.Main; import mobac.utilities.GUIExceptionHandler; import mobac.utilities.Utilities; public class ProgramInfo { public static String PROG_NAME = "Mobile Atlas Creator"; public static String PROG_NAME_SHORT = "MOBAC"; private static String VERSION = null; private static String SVN_REVISION = "unknown"; private static String userAgent = ""; /** * Show or hide the detailed revision info in the main windows title */ private static boolean titleHideRevision = false; public static void initialize() { InputStream propIn = Main.class.getResourceAsStream("mobac.properties"); try { Properties props = new Properties(); props.load(propIn); VERSION = props.getProperty("mobac.version"); titleHideRevision = Boolean.parseBoolean(props.getProperty("mobac.revision.hide", "false")); System.getProperties().putAll(props); } catch (Exception e) { String msg = "Error reading mobac.properties"; GUIExceptionHandler.processFatalExceptionSimpleDialog(msg, e); } finally { Utilities.closeStream(propIn); } propIn = Main.class.getResourceAsStream("mobac-rev.properties"); try { String rev; if (propIn != null) { Properties props = new Properties(); props.load(propIn); rev = props.getProperty("mobac.revision"); SVN_REVISION = Integer.toString(Utilities.parseSVNRevision(rev)); } else { rev = System.getProperty("mobac.revision.fallback"); SVN_REVISION = Integer.toString(Utilities.parseSVNRevision(rev)) + " exported"; } } catch (Exception e) { Logging.LOG.error("Error reading mobac-rev.properties", e); } finally { Utilities.closeStream(propIn); } userAgent = PROG_NAME_SHORT + "/" + (getVersion().replaceAll(" ", "_")); } public static String getVersion() { if (VERSION != null) return VERSION; else return "UNKNOWN"; } public static String getRevisionStr() { return SVN_REVISION; } public static String getVersionTitle() { String title = PROG_NAME; if (PROG_NAME_SHORT != null) title += " (" + PROG_NAME_SHORT + ") "; else title += " "; if (VERSION != null) { title += getVersion(); } else title += "unknown version"; return title; } public static String getCompleteTitle() { String title = getVersionTitle(); if (!titleHideRevision) title += " (" + SVN_REVISION + ")"; return title; } public static String getUserAgent() { return userAgent; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/download/0000755000175000017500000000000012127544344025525 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/download/UserAgent.java0000644000175000017500000000412712122526606030265 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.download; public class UserAgent { public static final String IE7_XP = "Mozilla/4.0 (compatible; MSIE 7.0; " + "Windows NT 5.1; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1))"; public static final String IE6_XP = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"; public static final String IE9_WIN7 = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)"; public static final String FF2_XP = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en; rv:1.8.1.17) Gecko/20080829"; public static final String FF3_XP = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en; rv:1.9.2) Gecko/20100115 Firefox/3.6"; public static final String FF3_WIN7 = "Mozilla/5.0 (Windows; U; Windows NT 6.1; en; rv:1.9.2.15) Gecko/20110303 Firefox/3.6.15"; public static final String OPERA11_WIN7 = "Opera/9.80 (Windows NT 6.1; U; en) Presto/2.7.62 Version/11.01"; private String name; private String userAgent; protected UserAgent(String name, String userAgent) { super(); this.name = name; this.userAgent = userAgent; } public String getName() { return name; } public String getUserAgent() { return userAgent; } @Override public String toString() { return name; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/download/TileDownLoader.java0000644000175000017500000003447012127544344031254 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.download; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.ProtocolException; import mobac.exceptions.DownloadFailedException; import mobac.exceptions.UnrecoverableDownloadException; import mobac.program.interfaces.HttpMapSource; import mobac.program.interfaces.MapSourceListener; import mobac.program.interfaces.MapSpace; import mobac.program.model.Settings; import mobac.program.model.TileImageType; import mobac.program.tilestore.TileStore; import mobac.program.tilestore.TileStoreEntry; import mobac.utilities.Utilities; import mobac.utilities.stream.ThrottledInputStream; import org.apache.log4j.Logger; public class TileDownLoader { public static String ACCEPT = "text/html, image/png, image/jpeg, image/gif, */*;q=0.1"; static { Object defaultReadTimeout = System.getProperty("sun.net.client.defaultReadTimeout"); if (defaultReadTimeout == null) System.setProperty("sun.net.client.defaultReadTimeout", "15000"); System.setProperty("http.maxConnections", "20"); } private static Logger log = Logger.getLogger(TileDownLoader.class); private static Settings settings = Settings.getInstance(); public static byte[] getImage(int x, int y, int zoom, HttpMapSource mapSource) throws IOException, InterruptedException, UnrecoverableDownloadException { MapSpace mapSpace = mapSource.getMapSpace(); int maxTileIndex = mapSpace.getMaxPixels(zoom) / mapSpace.getTileSize(); if (x > maxTileIndex) throw new RuntimeException("Invalid tile index x=" + x + " for zoom " + zoom); if (y > maxTileIndex) throw new RuntimeException("Invalid tile index y=" + y + " for zoom " + zoom); TileStore ts = TileStore.getInstance(); // Thread.sleep(2000); // Test code for creating random download failures // if (Math.random()>0.7) throw new // IOException("intentionally download error"); Settings s = Settings.getInstance(); TileStoreEntry tile = null; if (s.tileStoreEnabled) { // Copy the file from the persistent tilestore instead of // downloading it from internet. tile = ts.getTile(x, y, zoom, mapSource); boolean expired = isTileExpired(tile); if (tile != null) { if (expired) { log.trace("Expired: " + mapSource.getName() + " " + tile); } else { log.trace("Tile of map source " + mapSource.getName() + " used from tilestore"); byte[] data = tile.getData(); notifyCachedTileUsed(data.length); return data; } } } byte[] data = null; if (tile == null) { data = downloadTileAndUpdateStore(x, y, zoom, mapSource); notifyTileDownloaded(data.length); } else { byte[] updatedData = updateStoredTile(tile, mapSource); if (updatedData != null) { data = updatedData; notifyTileDownloaded(data.length); } else { data = tile.getData(); notifyCachedTileUsed(data.length); } } return data; } private static void notifyTileDownloaded(int size) { if (Thread.currentThread() instanceof MapSourceListener) { ((MapSourceListener) Thread.currentThread()).tileDownloaded(size); } } private static void notifyCachedTileUsed(int size) { if (Thread.currentThread() instanceof MapSourceListener) { ((MapSourceListener) Thread.currentThread()).tileLoadedFromCache(size); } } /** * Download the tile from the web server and updates the tile store if the tile could be successfully retrieved. * * @param x * @param y * @param zoom * @param mapSource * @return * @throws UnrecoverableDownloadException * @throws IOException * @throws InterruptedException */ public static byte[] downloadTileAndUpdateStore(int x, int y, int zoom, HttpMapSource mapSource) throws UnrecoverableDownloadException, IOException, InterruptedException { return downloadTileAndUpdateStore(x, y, zoom, mapSource, Settings.getInstance().tileStoreEnabled); } public static byte[] downloadTile(int x, int y, int zoom, HttpMapSource mapSource) throws UnrecoverableDownloadException, IOException, InterruptedException { return downloadTileAndUpdateStore(x, y, zoom, mapSource, false); } public static byte[] downloadTileAndUpdateStore(int x, int y, int zoom, HttpMapSource mapSource, boolean useTileStore) throws UnrecoverableDownloadException, IOException, InterruptedException { if (zoom < 0) throw new UnrecoverableDownloadException("Negative zoom!"); HttpURLConnection conn = mapSource.getTileUrlConnection(zoom, x, y); if (conn == null) throw new UnrecoverableDownloadException("Tile x=" + x + " y=" + y + " zoom=" + zoom + " is not a valid tile in map source " + mapSource); log.trace("Downloading " + conn.getURL()); prepareConnection(conn); conn.connect(); int code = conn.getResponseCode(); byte[] data = loadBodyDataInBuffer(conn); if (code != HttpURLConnection.HTTP_OK) throw new DownloadFailedException(conn, code); checkContentType(conn, data); checkContentLength(conn, data); String eTag = conn.getHeaderField("ETag"); long timeLastModified = conn.getLastModified(); long timeExpires = conn.getExpiration(); Utilities.checkForInterruption(); TileImageType imageType = Utilities.getImageType(data); if (imageType == null) throw new UnrecoverableDownloadException("The returned image is of unknown format"); if (useTileStore) { TileStore.getInstance().putTileData(data, x, y, zoom, mapSource, timeLastModified, timeExpires, eTag); } Utilities.checkForInterruption(); return data; } public static byte[] updateStoredTile(TileStoreEntry tile, HttpMapSource mapSource) throws UnrecoverableDownloadException, IOException, InterruptedException { final int x = tile.getX(); final int y = tile.getY(); final int zoom = tile.getZoom(); final HttpMapSource.TileUpdate tileUpdate = mapSource.getTileUpdate(); switch (tileUpdate) { case ETag: { boolean unchanged = hasTileETag(tile, mapSource); if (unchanged) { if (log.isTraceEnabled()) log.trace("Data unchanged on server (eTag): " + mapSource + " " + tile); return null; } break; } case LastModified: { boolean isNewer = isTileNewer(tile, mapSource); if (!isNewer) { if (log.isTraceEnabled()) log.trace("Data unchanged on server (LastModified): " + mapSource + " " + tile); return null; } break; } } HttpURLConnection conn = mapSource.getTileUrlConnection(zoom, x, y); if (conn == null) throw new UnrecoverableDownloadException("Tile x=" + x + " y=" + y + " zoom=" + zoom + " is not a valid tile in map source " + mapSource); if (log.isTraceEnabled()) log.trace(String.format("Checking %s %s", mapSource.getName(), tile)); prepareConnection(conn); boolean conditionalRequest = false; switch (tileUpdate) { case IfNoneMatch: { if (tile.geteTag() != null) { conn.setRequestProperty("If-None-Match", tile.geteTag()); conditionalRequest = true; } break; } case IfModifiedSince: { if (tile.getTimeLastModified() > 0) { conn.setIfModifiedSince(tile.getTimeLastModified()); conditionalRequest = true; } break; } } conn.connect(); Settings s = Settings.getInstance(); int code = conn.getResponseCode(); if (conditionalRequest && code == HttpURLConnection.HTTP_NOT_MODIFIED) { // Data unchanged on server if (s.tileStoreEnabled) { tile.update(conn.getExpiration()); TileStore.getInstance().putTile(tile, mapSource); } if (log.isTraceEnabled()) log.trace("Data unchanged on server: " + mapSource + " " + tile); return null; } byte[] data = loadBodyDataInBuffer(conn); if (code != HttpURLConnection.HTTP_OK) throw new DownloadFailedException(conn, code); checkContentType(conn, data); checkContentLength(conn, data); String eTag = conn.getHeaderField("ETag"); long timeLastModified = conn.getLastModified(); long timeExpires = conn.getExpiration(); Utilities.checkForInterruption(); TileImageType imageType = Utilities.getImageType(data); if (imageType == null) throw new UnrecoverableDownloadException("The returned image is of unknown format"); if (s.tileStoreEnabled) { TileStore.getInstance().putTileData(data, x, y, zoom, mapSource, timeLastModified, timeExpires, eTag); } Utilities.checkForInterruption(); return data; } public static boolean isTileExpired(TileStoreEntry tileStoreEntry) { if (tileStoreEntry == null) return true; long expiredTime = tileStoreEntry.getTimeExpires(); if (expiredTime >= 0) { // server had set an expiration time long maxExpirationTime = settings.tileMaxExpirationTime + tileStoreEntry.getTimeDownloaded(); long minExpirationTime = settings.tileMinExpirationTime + tileStoreEntry.getTimeDownloaded(); expiredTime = Math.max(minExpirationTime, Math.min(maxExpirationTime, expiredTime)); } else { // no expiration time set by server - use the default one expiredTime = tileStoreEntry.getTimeDownloaded() + settings.tileDefaultExpirationTime; } return (expiredTime < System.currentTimeMillis()); } /** * Reads all available data from the input stream of conn and returns it as byte array. If no input * data is available the method returns null. * * @param conn * @return * @throws IOException */ protected static byte[] loadBodyDataInBuffer(HttpURLConnection conn) throws IOException { InputStream input = conn.getInputStream(); byte[] data = null; try { if (Thread.currentThread() instanceof MapSourceListener) { // We only throttle atlas downloads, not downloads for the preview map long bandwidthLimit = Settings.getInstance().getBandwidthLimit(); if (bandwidthLimit > 0) { input = new ThrottledInputStream(input); } } data = Utilities.getInputBytes(input); } catch (IOException e) { InputStream errorIn = conn.getErrorStream(); try { byte[] errData = Utilities.getInputBytes(errorIn); log.trace("Retrieved " + errData.length + " error bytes for a HTTP " + conn.getResponseCode()); } catch (Exception ee) { log.debug("Error retrieving error stream content: " + e); } finally { Utilities.closeStream(errorIn); } throw e; } finally { Utilities.closeStream(input); } log.trace("Retrieved " + data.length + " bytes for a HTTP " + conn.getResponseCode()); if (data.length == 0) return null; return data; } /** * Performs a HEAD request for retrieving the LastModified header value. */ protected static boolean isTileNewer(TileStoreEntry tile, HttpMapSource mapSource) throws IOException { long oldLastModified = tile.getTimeLastModified(); if (oldLastModified <= 0) { log.warn("Tile age comparison not possible: " + "tile in tilestore does not contain lastModified attribute"); return true; } HttpURLConnection conn = mapSource.getTileUrlConnection(tile.getZoom(), tile.getX(), tile.getY()); conn.setRequestMethod("HEAD"); conn.setRequestProperty("Accept", ACCEPT); long newLastModified = conn.getLastModified(); if (newLastModified == 0) return true; return (newLastModified > oldLastModified); } protected static boolean hasTileETag(TileStoreEntry tile, HttpMapSource mapSource) throws IOException { String eTag = tile.geteTag(); if (eTag == null || eTag.length() == 0) { log.warn("ETag check not possible: " + "tile in tilestore does not contain ETag attribute"); return true; } HttpURLConnection conn = mapSource.getTileUrlConnection(tile.getZoom(), tile.getX(), tile.getY()); conn.setRequestMethod("HEAD"); conn.setRequestProperty("Accept", ACCEPT); String onlineETag = conn.getHeaderField("ETag"); if (onlineETag == null || onlineETag.length() == 0) return true; return (onlineETag.equals(eTag)); } protected static void prepareConnection(HttpURLConnection conn) throws ProtocolException { conn.setRequestMethod("GET"); Settings s = Settings.getInstance(); conn.setConnectTimeout(1000 * s.httpConnectionTimeout); conn.setReadTimeout(1000 * s.httpReadTimeout); if (conn.getRequestProperty("User-agent") == null) conn.setRequestProperty("User-agent", s.getUserAgent()); conn.setRequestProperty("Accept", ACCEPT); } protected static void checkContentType(HttpURLConnection conn, byte[] data) throws UnrecoverableDownloadException { String contentType = conn.getContentType(); if (contentType != null) { contentType = contentType.toLowerCase(); if (!contentType.startsWith("image/")) { if (log.isTraceEnabled() && contentType.startsWith("text/")) { log.trace("Content (" + contentType + "): " + new String(data)); } throw new UnrecoverableDownloadException("Content type of the loaded image is unknown: " + contentType, UnrecoverableDownloadException.ERROR_CODE_CONTENT_TYPE); } } } /** * Check if the retrieved data length is equal to the header value Content-Length * * @param conn * @param data * @throws UnrecoverableDownloadException */ protected static void checkContentLength(HttpURLConnection conn, byte[] data) throws UnrecoverableDownloadException { int len = conn.getContentLength(); if (len < 0) return; if (data.length != len) throw new UnrecoverableDownloadException("Content length is not as declared by the server: retrived=" + data.length + " bytes expected-content-length=" + len + " bytes"); } } ././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/download/DownloadJobProducerThread.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/download/DownloadJobProducerThread.jav0000644000175000017500000000446412122526606033271 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.download; import java.util.Enumeration; import mobac.program.AtlasThread; import mobac.program.JobDispatcher; import mobac.program.JobDispatcher.Job; import mobac.program.interfaces.DownloadableElement; import mobac.utilities.tar.TarIndexedArchive; import org.apache.log4j.Logger; /** * Creates the jobs for downloading tiles. If the job queue is full it will * block on {@link JobDispatcher#addJob(Job)} */ public class DownloadJobProducerThread extends Thread { private Logger log = Logger.getLogger(DownloadJobProducerThread.class); final JobDispatcher downloadJobDispatcher; final Enumeration jobEnumerator; public DownloadJobProducerThread(AtlasThread atlasThread, JobDispatcher downloadJobDispatcher, TarIndexedArchive tileArchive, DownloadableElement de) { this.downloadJobDispatcher = downloadJobDispatcher; jobEnumerator = de.getDownloadJobs(tileArchive, atlasThread); start(); } @Override public void run() { try { while (jobEnumerator.hasMoreElements()) { Job job = jobEnumerator.nextElement(); downloadJobDispatcher.addJob(job); log.trace("Job added: " + job); } log.debug("All download jobs has been generated"); } catch (InterruptedException e) { downloadJobDispatcher.cancelOutstandingJobs(); log.error("Download job generation interrupted"); } } public void cancel() { try { interrupt(); } catch (Exception e) { } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/download/jobenumerators/0000755000175000017500000000000012122526606030560 5ustar paulliupaulliu././@LongLink0000000000000000000000000000016100000000000011563 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/download/jobenumerators/DownloadJobEnumerator.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/download/jobenumerators/DownloadJobEnu0000644000175000017500000000654712122526606033371 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.download.jobenumerators; import java.awt.Point; import java.util.Enumeration; import mobac.program.JobDispatcher.Job; import mobac.program.download.DownloadJob; import mobac.program.interfaces.DownloadJobListener; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.TileFilter; import mobac.program.model.Map; import mobac.utilities.tar.TarIndexedArchive; /** * Enumerates / creates the download jobs for a regular rectangle single layer map. */ public class DownloadJobEnumerator implements Enumeration { final protected TileFilter tileFilter; final protected DownloadJobListener listener; final protected int xMin; final protected int xMax; final protected int yMax; final protected int zoom; final protected MapSource mapSource; final protected TarIndexedArchive tileArchive; protected int x, y; protected Job nextJob; /** * This enumerator is the unfolded version for two encapsulated loops: * *
	 * for (int y = yMin; y <= yMax; y++) {
	 * 	for (int x = xMin; x <= xMax; x++) {
	 * 		DownloadJob job = new DownloadJob(downloadDestinationDir, tileSource, x, y, zoom, AtlasThread.this);
	 * 	}
	 * }
	 * 
* * @param map * @param tileArchive * @param listener */ public DownloadJobEnumerator(Map map, MapSource mapSource, TarIndexedArchive tileArchive, DownloadJobListener listener) { this.tileFilter = map.getTileFilter(); this.listener = listener; Point minCoord = map.getMinTileCoordinate(); Point maxCoord = map.getMaxTileCoordinate(); int tileSize = map.getMapSource().getMapSpace().getTileSize(); this.xMin = minCoord.x / tileSize; this.xMax = maxCoord.x / tileSize; int yMin = minCoord.y / tileSize; this.yMax = maxCoord.y / tileSize; this.zoom = map.getZoom(); this.tileArchive = tileArchive; this.mapSource = mapSource; y = yMin; x = xMin; nextJob = new DownloadJob(mapSource, x, y, zoom, tileArchive, listener); if (!tileFilter.testTile(x, y, zoom, mapSource)) nextElement(); } public boolean hasMoreElements() { return (nextJob != null); } public Job nextElement() { Job job = nextJob; boolean filter = false; do { x++; if (x > xMax) { y++; x = xMin; if (y > yMax) { nextJob = null; return job; } } filter = tileFilter.testTile(x, y, zoom, mapSource); } while (!filter); nextJob = new DownloadJob(mapSource, x, y, zoom, tileArchive, listener); return job; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/download/DownloadJob.java0000644000175000017500000001007212122526606030566 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.download; import java.net.ConnectException; import java.net.SocketTimeoutException; import mobac.exceptions.DownloadFailedException; import mobac.exceptions.StopAllDownloadsException; import mobac.exceptions.UnrecoverableDownloadException; import mobac.program.JobDispatcher; import mobac.program.JobDispatcher.Job; import mobac.program.atlascreators.tileprovider.DownloadedTileProvider; import mobac.program.interfaces.DownloadJobListener; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSource.LoadMethod; import mobac.utilities.tar.TarIndexedArchive; import org.apache.log4j.Logger; public class DownloadJob implements Job { static Logger log = Logger.getLogger(DownloadJob.class); int errorCounter = 0; final MapSource mapSource; final int xValue; final int yValue; final int zoomValue; final TarIndexedArchive tileArchive; final DownloadJobListener listener; public DownloadJob(MapSource mapSource, int xValue, int yValue, int zoomValue, TarIndexedArchive tileArchive, DownloadJobListener listener) { this.mapSource = mapSource; this.xValue = xValue; this.yValue = yValue; this.zoomValue = zoomValue; this.tileArchive = tileArchive; this.listener = listener; } public void run(JobDispatcher dispatcher) throws Exception { try { // Thread.sleep(1500); listener.jobStarted(); byte[] tileData = mapSource.getTileData(zoomValue, xValue, yValue, LoadMethod.DEFAULT); String tileFileName = String.format(DownloadedTileProvider.TILE_FILENAME_PATTERN, xValue, yValue); if (tileArchive != null) { synchronized (tileArchive) { tileArchive.writeFileFromData(tileFileName, tileData); } } listener.jobFinishedSuccessfully(tileData.length); } catch (UnrecoverableDownloadException e) { listener.jobFinishedWithError(false); log.error("Download of tile z" + zoomValue + "_x" + xValue + "_y" + yValue + " failed with an unrecoverable error: " + e.getCause()); } catch (InterruptedException e) { throw e; } catch (StopAllDownloadsException e) { throw e; } catch (SocketTimeoutException e) { processError(dispatcher, e); } catch (ConnectException e) { processError(dispatcher, e); } catch (DownloadFailedException e) { processError(dispatcher, e); } catch (Exception e) { processError(dispatcher, e); throw e; } } private void processError(JobDispatcher dispatcher, Exception e) { errorCounter++; // Reschedule job to try it later again if (errorCounter <= listener.getMaxDownloadRetries()) { listener.jobFinishedWithError(true); log.warn("Download of tile z" + zoomValue + "_x" + xValue + "_y" + yValue + " failed: \"" + e.getMessage() + "\" (tries: " + errorCounter + ") - rescheduling download job"); dispatcher.addErrorJob(this); } else { listener.jobFinishedWithError(false); log.error("Download of tile z" + zoomValue + "_x" + xValue + "_y" + yValue + " failed again: \"" + e.getMessage() + "\". Retry limit reached, " + "job will not be rescheduled (no further try)"); } } @Override public String toString() { return "DownloadJob x=" + xValue + " y=" + yValue + " z=" + zoomValue; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/tiledatawriter/0000755000175000017500000000000012147023632026734 5ustar paulliupaulliu././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/tiledatawriter/TileImageJpegDataWriter.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/tiledatawriter/TileImageJpegDataWriter0000644000175000017500000001112412147023632033313 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.tiledatawriter; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.OutputStream; import java.util.Iterator; import javax.imageio.IIOImage; import javax.imageio.ImageIO; import javax.imageio.ImageWriteParam; import javax.imageio.ImageWriter; import javax.imageio.stream.ImageOutputStream; import mobac.program.interfaces.TileImageDataWriter; import mobac.program.model.TileImageType; import org.apache.commons.io.output.NullOutputStream; import org.apache.log4j.Logger; public class TileImageJpegDataWriter implements TileImageDataWriter { protected static final Logger log = Logger.getLogger(TileImageJpegDataWriter.class); protected ImageWriter jpegImageWriter = null; protected ImageWriteParam iwp = null; protected float jpegCompressionLevel; /** * * @param jpegCompressionLevel * a float between 0 and 1; 1 specifies minimum compression and maximum quality */ public TileImageJpegDataWriter(double jpegCompressionLevel) { this((float) jpegCompressionLevel); } public TileImageJpegDataWriter(float jpegCompressionLevel) { this.jpegCompressionLevel = (float) jpegCompressionLevel; } public TileImageJpegDataWriter(TileImageJpegDataWriter jpegWriter) { this(jpegWriter.getJpegCompressionLevel()); } public void initialize() { if (log.isTraceEnabled()) { String s = "Available JPEG image writers:"; Iterator writers = ImageIO.getImageWritersByFormatName("jpeg"); while (writers.hasNext()) { ImageWriter w = writers.next(); s += "\n\t" + w.getClass().getName(); } log.trace(s); } jpegImageWriter = ImageIO.getImageWritersByFormatName("jpeg").next(); if (jpegImageWriter == null) throw new NullPointerException("Unable to create a JPEG image writer"); jpegImageWriter.addIIOWriteWarningListener(ImageWriterWarningListener.INSTANCE); log.debug("Used JPEG image writer: " + jpegImageWriter.getClass().getName()); iwp = jpegImageWriter.getDefaultWriteParam(); iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); iwp.setCompressionQuality(jpegCompressionLevel); } public void setJpegCompressionLevel(float jpegCompressionLevel) { this.jpegCompressionLevel = jpegCompressionLevel; iwp.setCompressionQuality(jpegCompressionLevel); } public float getJpegCompressionLevel() { return jpegCompressionLevel; } public void processImage(BufferedImage image, OutputStream out) throws IOException { if (image.getColorModel().hasAlpha()) { // Javas JPEG writes has a bug when the image has alpha transparency // see http://stackoverflow.com/questions/4386446/problem-using-imageio-write-jpg-file BufferedImage imageRGB = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_RGB); Graphics2D g = imageRGB.createGraphics(); g.drawImage(image, null, 0, 0); g.dispose(); image = imageRGB; } ImageOutputStream imageOut = ImageIO.createImageOutputStream(out); jpegImageWriter.setOutput(imageOut); IIOImage ioImage = new IIOImage(image, null, null); jpegImageWriter.write(null, ioImage, iwp); } public void dispose() { jpegImageWriter.dispose(); jpegImageWriter = null; } public TileImageType getType() { return TileImageType.JPG; } public static boolean performOpenJDKJpegTest() { try { TileImageJpegDataWriter writer = new TileImageJpegDataWriter(0.99d); writer.initialize(); OutputStream out = new NullOutputStream(); BufferedImage image = new BufferedImage(10, 10, BufferedImage.TYPE_INT_ARGB); writer.processImage(image, out); return true; } catch (Exception e) { log.debug("Jpeg test failed", e); return false; } } } ././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/tiledatawriter/TileImagePng8DataWriter.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/tiledatawriter/TileImagePng8DataWriter0000644000175000017500000000255612122526604033253 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.tiledatawriter; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.OutputStream; import mobac.optional.JavaAdvancedImaging; public class TileImagePng8DataWriter extends TileImagePngDataWriter { public TileImagePng8DataWriter() { } @Override public void processImage(BufferedImage image, OutputStream out) throws IOException { BufferedImage image2 = JavaAdvancedImaging.colorReduceMedianCut(image, 256); super.processImage(image2, out); } } ././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/tiledatawriter/TileImagePng4DataWriter.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/tiledatawriter/TileImagePng4DataWriter0000644000175000017500000000317612122526604033246 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.tiledatawriter; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.OutputStream; import mobac.optional.JavaAdvancedImaging; import mobac.program.interfaces.TileImageDataWriter; import mobac.program.model.TileImageType; import mobac.utilities.imageio.Png4BitWriter; public class TileImagePng4DataWriter implements TileImageDataWriter { public TileImagePng4DataWriter() { } public void initialize() { } public void processImage(BufferedImage image, OutputStream out) throws IOException { BufferedImage image2 = JavaAdvancedImaging.colorReduceMedianCut(image, 16); Png4BitWriter.writeImage(out, image2); } public void dispose() { } public TileImageType getType() { return TileImageType.PNG; } } ././@LongLink0000000000000000000000000000015100000000000011562 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/tiledatawriter/TileImagePngDataWriter.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/tiledatawriter/TileImagePngDataWriter.0000644000175000017500000000465312122526604033241 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.tiledatawriter; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.OutputStream; import java.util.Iterator; import javax.imageio.IIOImage; import javax.imageio.ImageIO; import javax.imageio.ImageWriter; import mobac.program.interfaces.TileImageDataWriter; import mobac.program.model.TileImageType; import org.apache.log4j.Logger; public class TileImagePngDataWriter implements TileImageDataWriter { protected Logger log; protected ImageWriter pngImageWriter = null; public TileImagePngDataWriter() { log = Logger.getLogger(this.getClass()); } public void initialize() { if (log.isTraceEnabled()) { String s = "Available PNG image writers:"; Iterator writers = ImageIO.getImageWritersByFormatName("png"); while (writers.hasNext()) { ImageWriter w = writers.next(); s += "\n\t" + w.getClass().getName(); } log.trace(s); } pngImageWriter = ImageIO.getImageWritersByFormatName("png").next(); pngImageWriter.addIIOWriteWarningListener(ImageWriterWarningListener.INSTANCE); log.debug("Used PNG image writer: " + pngImageWriter.getClass().getName()); } public void processImage(BufferedImage image, OutputStream out) throws IOException { pngImageWriter.setOutput(ImageIO.createImageOutputStream(out)); IIOImage ioImage = new IIOImage(image, null, null); pngImageWriter.write(ioImage); } public void dispose() { pngImageWriter.dispose(); pngImageWriter = null; } public TileImageType getType() { return TileImageType.PNG; } } ././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/tiledatawriter/ImageWriterWarningListener.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/tiledatawriter/ImageWriterWarningListe0000644000175000017500000000320612122526604033426 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.tiledatawriter; import javax.imageio.ImageWriter; import javax.imageio.event.IIOWriteWarningListener; import org.apache.log4j.Logger; /** * Allows to capture non-fatal warnings that may occur upon writing an image. At the moment all warnings are simply * logged. */ public class ImageWriterWarningListener implements IIOWriteWarningListener { private static final Logger log = Logger.getLogger(ImageWriterWarningListener.class); public static final IIOWriteWarningListener INSTANCE = new ImageWriterWarningListener(); public void warningOccurred(ImageWriter source, int imageIndex, String warning) { if (log.isDebugEnabled()) log.warn(warning + " - caused by: " + source + " on imageIndex " + imageIndex); else log.warn(warning); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/interfaces/0000755000175000017500000000000012122526604026033 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/interfaces/HttpMapSource.java0000644000175000017500000000542312122526604031440 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.interfaces; import java.io.IOException; import java.net.HttpURLConnection; public interface HttpMapSource extends MapSource { /** * Specifies the different mechanisms for detecting updated tiles respectively only download newer tiles than those * stored locally. * *
    *
  • {@link #IfNoneMatch} Server provides ETag header entry for all tiles and supports conditional download * via If-None-Match header entry.
  • *
  • {@link #ETag} Server provides ETag header entry for all tiles but does not support conditional * download via If-None-Match header entry.
  • *
  • {@link #IfModifiedSince} Server provides Last-Modified header entry for all tiles and supports * conditional download via If-Modified-Since header entry.
  • *
  • {@link #LastModified} Server provides Last-Modified header entry for all tiles but does not support * conditional download via If-Modified-Since header entry.
  • *
  • {@link #None} The server does not support any of the listed mechanisms.
  • *
* */ public enum TileUpdate { IfNoneMatch, ETag, IfModifiedSince, LastModified, None } /** * @return The supported tile update mechanism * @see TileUpdate */ public TileUpdate getTileUpdate(); /** * Constructs the tile url connection. If necessary the url connection can be prepared with cookies or other http * specific headers which are required by the http server. * * @param zoom * @param tilex * tile number on x-axis for the specified zoom level * @param tiley * tile number on y-axis for the specified zoom level * @return the initialized urlConnection for downloading the specified tile image */ public HttpURLConnection getTileUrlConnection(int zoom, int tilex, int tiley) throws IOException; } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/interfaces/MapSpace.java0000644000175000017500000000710712122526604030374 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.interfaces; import java.awt.Point; import mobac.mapsources.mapspace.MercatorPower2MapSpace; /** * Preparation for supporting map resolutions other than those uses by * Google/OpenstreetMap. * * {@link MercatorPower2MapSpace} is the only implementation that is currently * supported by Mobile Atlas Creator. *

* DO NOT TRY TO IMPLEMENT YOUR OWN. IT WILL NOT WORK! *

*/ public interface MapSpace { public enum ProjectionCategory { SPHERE, ELLIPSOID, GEOID }; public ProjectionCategory getProjectionCategory(); public int getMaxPixels(int zoom); /** * @return size (height and width) of each tile in pixel */ public int getTileSize(); /** * Converts the horizontal pixel coordinate from map space to longitude. * * @param lon * @param zoom * @return */ public int cLonToX(double lon, int zoom); /** * Converts the vertical pixel coordinate from map space to latitude. * * @param lat * @param zoom * @return */ public int cLatToY(double lat, int zoom); /** * Converts longitude to the horizontal pixel coordinate from map space. * * @param x * @param zoom * @return */ public double cXToLon(int x, int zoom); /** * Converts latitude to the vertical pixel coordinate from map space. * * @param y * @param zoom * @return */ public double cYToLat(int y, int zoom); /** * "Walks" westerly a certain distance on a latitude and returns the * "mileage" in map space pixels. The distance is specified as angular * distance, therefore this method works with all length unit systems (e.g. * metric, imperial, ...). * * @param startX * x-coordinate of start point * @param y * y-coordinate specifying the latitude to "walk" on * @param zoom * @param angularDist * angular distance: distance / earth radius (e.g. 6367.5km or * 3956.6miles) * @return "mileage" in number of pixels */ public int moveOnLatitude(int startX, int y, int zoom, double angularDist); /** * Calculates the distance between two points that are laying on the same * latitude / y-coordinate. * * @param zoom * @param y * y-coordinate specifying the latitude * @param xDist * distance in pixels on the x-axis * @return angular distance angular distance: distance / earth radius (e.g. * 6367.5km or 3956.6miles) */ public double horizontalDistance(int zoom, int y, int xDist); public Point changeZoom(Point pixelCoordinate, int oldZoom, int newZoom); public int xChangeZoom(int x, int oldZoom, int newZoom); public int yChangeZoom(int y, int oldZoom, int newZoom); } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/interfaces/DownloadableElement.java0000644000175000017500000000327412122526604032611 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.interfaces; import java.util.Enumeration; import mobac.program.JobDispatcher.Job; import mobac.utilities.tar.TarIndexedArchive; /** * Classes that implement this interface identify themselves as responsible for * specifying what tiles should be downloaded. * * In general this interface should be implemented in combination with * {@link MapInterface}, {@link LayerInterface} or {@link AtlasInterface}. * */ public interface DownloadableElement { /** * * @param tileArchive * @param listener * @return An enumeration that returns {@link Job} objects. Each job should * download one map tile from the providing web server (or from the * tile cache). */ public Enumeration getDownloadJobs(TarIndexedArchive tileArchive, DownloadJobListener listener); } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/interfaces/CommandLineAction.java0000644000175000017500000000207312122526604032224 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.interfaces; public interface CommandLineAction { public boolean showSplashScreen(); public boolean showMainGUI(); public void runBeforeMainGUI(); public void runMainGUI(); } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/interfaces/LayerInterface.java0000644000175000017500000000235612122526604031601 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.interfaces; public interface LayerInterface extends AtlasObject, Iterable, CapabilityDeletable { public void addMap(MapInterface map); public int getMapCount(); public MapInterface getMap(int index); public AtlasInterface getAtlas(); public long calculateTilesToDownload(); public LayerInterface deepClone(AtlasInterface atlas); } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/interfaces/ExceptionExtendedInfo.java0000644000175000017500000000172712122526604033140 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.interfaces; public interface ExceptionExtendedInfo { public String getExtendedInfo(); } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/interfaces/ToolTipProvider.java0000644000175000017500000000171412122526604032006 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.interfaces; public interface ToolTipProvider { public String getToolTip(); } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/interfaces/RequiresSQLite.java0000644000175000017500000000226212122526604031561 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.interfaces; /** * Marker-Interface which has to implemented by all atlas creator classes which require the SQLite libraries. */ public interface RequiresSQLite { /** * Accumulate tiles in batch process until 20MB of heap are remaining */ public static final long HEAP_MIN = 20 * 1024 * 1024; } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/interfaces/FileBasedMapSource.java0000644000175000017500000000225012122526604032332 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.interfaces; /** * Marker interface for file based map sources (map sources that use tiles present in the file system and therefore do * not stress online tile servers. */ public interface FileBasedMapSource extends MapSource { public void initialize(); public void reinitialize(); } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/interfaces/WrappedMapSource.java0000644000175000017500000000204712122526604032122 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.interfaces; import mobac.exceptions.MapSourceCreateException; public interface WrappedMapSource { public MapSource getMapSource() throws MapSourceCreateException; } ././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/interfaces/MapSourceTextAttribution.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/interfaces/MapSourceTextAttribution.ja0000644000175000017500000000213512122526604033340 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.interfaces; public interface MapSourceTextAttribution { public String getAttributionText(); /** * @return The URL to open when the user clicks the attribution image. */ public String getAttributionLinkURL(); } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/interfaces/MapSourceListener.java0000644000175000017500000000201012122526604032273 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.interfaces; public interface MapSourceListener { public void tileDownloaded(int size); public void tileLoadedFromCache(int size); } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/interfaces/CapabilityDeletable.java0000644000175000017500000000236412122526604032566 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.interfaces; import mobac.gui.atlastree.JAtlasTree; import mobac.program.model.AtlasTreeModel; /** * Identifies nodes in {@link JAtlasTree} / {@link AtlasTreeModel} that can be * deleted (including sub-nodes). Nodes implementing this interface will show a * "delete" entry in it's context menu. */ public interface CapabilityDeletable { public void delete(); } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/interfaces/AtlasInterface.java0000644000175000017500000000306512122526604031567 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.interfaces; import mobac.program.model.AtlasOutputFormat; public interface AtlasInterface extends AtlasObject, Iterable { /** * @return Number of layers in this atlas */ public int getLayerCount(); /** * * @param index * 0 - ({@link #getLayerCount()}-1) * @return */ public LayerInterface getLayer(int index); public void addLayer(LayerInterface l); public void deleteLayer(LayerInterface l); public void setOutputFormat(AtlasOutputFormat atlasOutputFormat); public AtlasOutputFormat getOutputFormat(); public long calculateTilesToDownload(); public int getVersion(); public AtlasInterface deepClone(); } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/interfaces/MapSource.java0000644000175000017500000000662012122526604030600 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.interfaces; import java.awt.Color; import java.awt.image.BufferedImage; import java.io.IOException; import javax.xml.bind.annotation.XmlTransient; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import mobac.exceptions.TileException; import mobac.exceptions.UnrecoverableDownloadException; import mobac.gui.mapview.JMapViewer; import mobac.program.jaxb.MapSourceAdapter; import mobac.program.model.MapSourceLoaderInfo; import mobac.program.model.TileImageType; //License: GPL. Copyright 2008 by Jan Peter Stotz /** * * @author Jan Peter Stotz */ @XmlJavaTypeAdapter(MapSourceAdapter.class) public interface MapSource { public enum LoadMethod { DEFAULT, CACHE, SOURCE }; /** * Specifies the maximum zoom value. The number of zoom levels is [0.. {@link #getMaxZoom()}]. * * @return maximum zoom value that has to be smaller or equal to {@link JMapViewer#MAX_ZOOM} */ public int getMaxZoom(); /** * Specifies the minimum zoom value. This value is usually 0. Only for maps that cover a certain region up to a * limited zoom level this method should return a value different than 0. * * @return minimum zoom value - usually 0 */ public int getMinZoom(); /** * A tile layer name has to be unique and has to consist only of characters valid for filenames. * * @return Name of the tile layer */ public String getName(); /** * * @param zoom * @param x * @param y * @param loadMethod * TODO * @return * @throws IOException * @throws InterruptedException * @throws UnrecoverableDownloadException */ public byte[] getTileData(int zoom, int x, int y, LoadMethod loadMethod) throws IOException, TileException, InterruptedException; /** * * @param zoom * @param x * @param y * @param loadMethod * @return * @throws IOException * @throws UnrecoverableDownloadException * @throws InterruptedException */ public BufferedImage getTileImage(int zoom, int x, int y, LoadMethod loadMethod) throws IOException, TileException, InterruptedException; /** * Specifies the tile image type. For tiles rendered by Mapnik or Osmarenderer this is usually * {@link TileImageType#PNG}. * * @return file extension of the tile image type */ public TileImageType getTileImageType(); public MapSpace getMapSpace(); public Color getBackgroundColor(); @XmlTransient public MapSourceLoaderInfo getLoaderInfo(); public void setLoaderInfo(MapSourceLoaderInfo loaderInfo); } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/interfaces/TileFilter.java0000644000175000017500000000274012122526604030744 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.interfaces; /** * Basic interface that allows to filter tiles based on their position and zoom level in the map. */ public interface TileFilter { /** * Tests if the tile specified by the parameters should be included or excluded * * @param x * @param y * @param zoom * @param mapSource * @return
    *
  • true: tile did pass the filter and should be included
  • *
  • false:tile did not pass the filter and should be excluded
  • *
*/ public boolean testTile(int x, int y, int zoom, MapSource mapSource); } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/interfaces/MapInterface.java0000644000175000017500000000314412122526604031236 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.interfaces; import java.awt.Dimension; import java.awt.Point; import mobac.program.model.TileImageParameters; public interface MapInterface extends AtlasObject, CapabilityDeletable { public Point getMinTileCoordinate(); public Point getMaxTileCoordinate(); public int getZoom(); public MapSource getMapSource(); public Dimension getTileSize(); public LayerInterface getLayer(); public void setLayer(LayerInterface layer); public TileImageParameters getParameters(); public void setParameters(TileImageParameters p); public long calculateTilesToDownload(); public String getInfoText(); public TileFilter getTileFilter(); public MapInterface deepClone(LayerInterface newLayer); } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/interfaces/DownloadJobListener.java0000644000175000017500000000215512122526604032611 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.interfaces; public interface DownloadJobListener { public int getMaxDownloadRetries(); public void jobStarted(); public void jobFinishedSuccessfully(int bytesDownloaded); public void jobFinishedWithError(boolean retry); } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/interfaces/TileImageDataWriter.java0000644000175000017500000000341012122526604032523 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.interfaces; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import mobac.program.model.TileImageType; public interface TileImageDataWriter { public void initialize(); /** * Processes the image according to the implementation of this * interfaces and saves the image data in a binary representation such as * PNG, JPG, ...into the given OutputStream. * * @param image * @param out * {@link OutputStream} to write binary image data to (usually * this is a {@link FileOutputStream} or a * {@link ByteArrayOutputStream} * @throws IOException */ public void processImage(BufferedImage image, OutputStream out) throws IOException; public void dispose(); public TileImageType getType(); } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/interfaces/AtlasObject.java0000644000175000017500000000274112122526604031075 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.interfaces; import mobac.exceptions.InvalidNameException; /** * Marker interface that indicates that the implementing class/instance is an * atlas or is part of an atlas (layer or map) */ public interface AtlasObject { public String getName(); public void setName(String newName) throws InvalidNameException; /** * Called after loading the complete atlas from a profile. * * @return any problems found? true=yes */ public boolean checkData(); public double getMinLat(); public double getMaxLat(); public double getMinLon(); public double getMaxLon(); } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/Logging.java0000644000175000017500000001734012122526604026146 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program; import java.awt.Desktop; import java.awt.Desktop.Action; import java.io.File; import java.io.StringWriter; import java.util.Enumeration; import java.util.Map.Entry; import java.util.Properties; import java.util.TreeMap; import java.util.logging.Handler; import mobac.StartMOBAC; import mobac.utilities.GUIExceptionHandler; import mobac.utilities.Juli2Log4jHandler; import mobac.utilities.OSUtilities; import org.apache.log4j.ConsoleAppender; import org.apache.log4j.FileAppender; import org.apache.log4j.Layout; import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.apache.log4j.PatternLayout; import org.apache.log4j.SimpleLayout; import org.apache.log4j.xml.DOMConfigurator; public class Logging { protected static final String CONFIG_FILENAME = "log4j.xml"; protected static final String LOG_FILENAME = "Mobile Atlas Creator.log"; protected static File CONFIG_FILE = null; public static final Logger LOG = Logger.getLogger("MAC"); public static final Layout ADVANCED_LAYOUT = new PatternLayout("%d{ISO8601} %-5p [%t] %c{1}: %m%n"); protected static boolean CONFIGURED = false; public static void configureLogging() { // We test for the configuration file, if it exists we use it, otherwise // we perform simple logging to the console if (!loadLog4JConfigXml()) { configureDefaultErrorLogging(); Logger logger = Logger.getRootLogger(); logger.info("log4.xml not found - enabling default error log to console"); } } public static boolean loadLog4JConfigXml() { if (loadLog4JConfigXml(DirectoryManager.userAppDataDir)) return true; if (loadLog4JConfigXml(DirectoryManager.userSettingsDir)) return true; if (loadLog4JConfigXml(DirectoryManager.currentDir)) return true; if (loadLog4JConfigXml(DirectoryManager.programDir)) return true; return false; } public static boolean loadLog4JConfigXml(File directory) { File f = new File(directory, CONFIG_FILENAME); if (!f.isFile()) return false; try { DOMConfigurator.configure(f.getAbsolutePath()); } catch (Exception e) { System.err.println("Error loading log4j config file \"" + f.getAbsolutePath() + "\""); return false; } Logger logger = Logger.getLogger("LogSystem"); logger.setLevel(Level.INFO); logger.info("Logging configured by \"" + f.getAbsolutePath() + "\""); CONFIGURED = true; return true; } public static void configureDefaultErrorLogging() { Logger.getRootLogger().setLevel(Level.INFO); configureConsoleLogging(Level.TRACE, new SimpleLayout()); configureLogFileLogging(Level.TRACE); } public static void configureConsoleLogging() { configureConsoleLogging(Level.ERROR, new SimpleLayout()); } public static void configureConsoleLogging(Level level) { configureConsoleLogging(level, new SimpleLayout()); } public static void configureConsoleLogging(Level level, Layout layout) { Logger logger = Logger.getRootLogger(); ConsoleAppender consoleAppender = new ConsoleAppender(layout); if (level != null) consoleAppender.setThreshold(level); logger.addAppender(consoleAppender); CONFIGURED = true; } public static void configureLogFileLogging(Level level) { Logger logger = Logger.getRootLogger(); File logFileDir = DirectoryManager.userAppDataDir; String logFilename = new File(logFileDir, LOG_FILENAME).getAbsolutePath(); Layout layout = new PatternLayout("%d{ISO8601} %-5p [%t] %c{1}: %m%n"); FileAppender fileAppender; try { fileAppender = new FileAppender(layout, logFilename, false); if (level != null) fileAppender.setThreshold(level); logger.addAppender(fileAppender); } catch (Exception e) { Logger log = Logger.getLogger("LogSystem"); log.error("", e); } } public static void disableLogging() { Logger logger = Logger.getRootLogger(); logger.setLevel(Level.OFF); } public static void enableJAXBLogging() { java.util.logging.Logger logger; Handler h = new Juli2Log4jHandler(); logger = java.util.logging.Logger.getLogger("javax.xml.bind"); logger.setLevel(java.util.logging.Level.ALL); logger.addHandler(h); logger = java.util.logging.Logger.getLogger("com.sun.xml.internal.bind"); logger.setLevel(java.util.logging.Level.ALL); logger.addHandler(h); } public static void logSystemInfo() { Logger log = Logger.getLogger("SysInfo"); if (log.isInfoEnabled()) { String n = System.getProperty("line.separator"); log.info("Version: " + ProgramInfo.getCompleteTitle()); log.info("Platform: " + GUIExceptionHandler.prop("os.name") + " (" + GUIExceptionHandler.prop("os.version") + ")"); log.info("Java VM: " + GUIExceptionHandler.prop("java.vm.name") + " (" + GUIExceptionHandler.prop("java.runtime.version") + ")"); log.info("Directories:" /**/ + n + "currentDir: \t\t" + DirectoryManager.currentDir /**/ + n + "programDir: \t\t" + DirectoryManager.programDir /**/ + n + "tempDir: \t\t" + DirectoryManager.tempDir /**/ + n + "userHomeDir: \t\t" + DirectoryManager.userHomeDir /**/ + n + "userSettingsDir: \t" + DirectoryManager.userSettingsDir /**/ + n + "atlasProfilesDir: \t" + DirectoryManager.atlasProfilesDir /**/ + n + "userAppDataDir: \t" + DirectoryManager.userAppDataDir /**/ ); log.info("System console available: " + (System.console() != null)); log.info("Startup arguments (count=" + StartMOBAC.ARGS.length + "):"); for (int i = 0; i < StartMOBAC.ARGS.length; i++) log.info("\t" + i + ": " + StartMOBAC.ARGS[i]); } if (log.isDebugEnabled()) { log.debug("Detected operating system: " + OSUtilities.detectOs() + " (" + System.getProperty("os.name") + ")"); boolean desktopSupport = Desktop.isDesktopSupported(); log.debug("Desktop support: " + desktopSupport); if (desktopSupport) { Desktop d = Desktop.getDesktop(); for (Action a : Action.values()) { log.debug("Desktop action " + a + " supported: " + d.isSupported(a)); } } } if (log.isTraceEnabled()) { Properties props = System.getProperties(); StringWriter sw = new StringWriter(2 << 13); sw.write("System properties:\n"); TreeMap sortedProps = new TreeMap(props); for (Entry entry : sortedProps.entrySet()) { sw.write(entry.getKey() + " = " + entry.getValue() + "\n"); } log.trace(sw.toString()); } } /** * returns the first configured {@link FileAppender} or null. * * @return */ public static String getLogFile() { Enumeration enu = Logger.getRootLogger().getAllAppenders(); while (enu.hasMoreElements()) { Object o = enu.nextElement(); if (o instanceof FileAppender) { FileAppender fa = (FileAppender) o; return fa.getFile(); } } return null; } public static boolean isCONFIGURED() { return CONFIGURED; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/annotations/0000755000175000017500000000000012122526604026245 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/annotations/SupportedParameters.java0000644000175000017500000000317312122526604033125 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import mobac.program.atlascreators.AtlasCreator; import mobac.program.model.TileImageParameters; import mobac.program.model.TileImageParameters.Name; /** * Annotation for {@link AtlasCreator} implementations. The {@link #names()} field holds the parameter names supported * by the specific atlas format. The full list of available parameters is defined in {@link Name}. */ @Inherited @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface SupportedParameters { public TileImageParameters.Name[] names(); } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/annotations/AtlasCreatorName.java0000644000175000017500000000302612122526604032276 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import mobac.program.atlascreators.AtlasCreator; import mobac.program.model.TileImageParameters.Name; /** * Annotation for {@link AtlasCreator} implementations. The {@link #names()} field holds the parameter names supported * by the specific atlas format. The full list of available parameters is defined in {@link Name}. */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface AtlasCreatorName { String value(); String type() default ""; } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/PauseResumeHandler.java0000644000175000017500000000362012122526606030312 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program; /** * Central instance that allows to pause/resume multiple threads at once. Used * in MOBAC for pausing/resuming map tile download and map creation process. */ public class PauseResumeHandler { protected boolean paused = false; public boolean isPaused() { return paused; } /** * Enters the pause state. */ public void pause() { paused = true; } /** * End the pause state and resumes all waiting threads. */ public void resume() { paused = false; synchronized (this) { this.notifyAll(); } } /** * If {@link #isPaused()}== true this method will not return * until {@link #resume()} has been called. Otherwise this method returns * immediately. * * @throws InterruptedException * Thrown if the calling {@link Thread} is interrupted while * waiting for resume */ public void pauseWait() throws InterruptedException { if (paused) { synchronized (this) { if (paused) this.wait(); } } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/model/0000755000175000017500000000000012171650636025017 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/model/Coordinate.java0000644000175000017500000000404412122526604027744 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.model; public class Coordinate { public static final int MILISECOND = 1, SECOND = MILISECOND * 1000, MINUTE = SECOND * 60, DEGREE = MINUTE * 60; public static int doubleToInt(double value) { int degree = (int) value; int minute = (int) (value = (value - degree) * 60d); int second = (int) (value = (value - minute) * 60d); int milisecond = (int) (value = (value - second) * 1000d); return degree * DEGREE + minute * MINUTE + second * SECOND + milisecond * MILISECOND; } public static double intToDouble(int value) { double degree = value / DEGREE; double minute = (value = value % DEGREE) / MINUTE; double second = (int) (value %= MINUTE) / SECOND; double milisecond = (int) (value %= SECOND) / MILISECOND; return degree + minute / 60d + second / 3600d + milisecond / 3600000d; } public static int getDegree(int value) { return value / DEGREE; } public static int getMinute(int value) { return Math.abs(value) % DEGREE / MINUTE; } public static int getSecond(int value) { return Math.abs(value) % MINUTE / SECOND; } public static int getMilisecond(int value) { return Math.abs(value) % SECOND / MILISECOND; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/model/ProxyType.java0000644000175000017500000000313712127544344027650 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.model; import mobac.utilities.I18nUtils; public enum ProxyType { SYSTEM, // APP_SETTINGS, // CUSTOM, // CUSTOM_W_AUTH; //private String text; // private ProxyType(String text) { // this.text = text; // } @Override public String toString() { switch(this) { case SYSTEM: return I18nUtils.localizedStringForKey("set_net_proxy_settings_java"); case APP_SETTINGS: return I18nUtils.localizedStringForKey("set_net_proxy_settings_application"); case CUSTOM: return I18nUtils.localizedStringForKey("set_net_proxy_settings_custom"); case CUSTOM_W_AUTH: return I18nUtils.localizedStringForKey("set_net_proxy_settings_custom_auth"); } return I18nUtils.localizedStringForKey("Undefined"); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/model/CoordinateStringFormat.java0000644000175000017500000000654512127544344032322 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.model; import java.text.NumberFormat; import mobac.utilities.I18nUtils; import mobac.utilities.Utilities; import mobac.utilities.geo.CoordinateDm2Format; import mobac.utilities.geo.CoordinateDms2Format; import mobac.utilities.geo.CoordinateTileFormat; public enum CoordinateStringFormat { DEG_ENG(Utilities.FORMAT_6_DEC_ENG), // DEG_LOCAL(Utilities.FORMAT_6_DEC), // DEG_MIN_ENG(new CoordinateDm2Format(Utilities.DFS_ENG)), // DEG_MIN_LOCAL(new CoordinateDm2Format(Utilities.DFS_LOCAL)), // DEG_MIN_SEC_ENG(new CoordinateDms2Format(Utilities.DFS_ENG)), // DEG_MIN_SEC_LOCAL(new CoordinateDms2Format(Utilities.DFS_LOCAL)), // TILE_X_Y_Z(new CoordinateTileFormat(false), new CoordinateTileFormat(true)); /* * formatButton.addDropDownItem(new JNumberFormatMenuItem()); formatButton.addDropDownItem(new * JNumberFormatMenuItem("Deg Min Sec,2 (local)", */ //private final String displayName; private NumberFormat numberFormatLatitude; private NumberFormat numberFormatLongitude; private CoordinateStringFormat(NumberFormat numberFormat) { //this.displayName = displayName; this.numberFormatLatitude = numberFormat; this.numberFormatLongitude = numberFormat; } private CoordinateStringFormat(NumberFormat numberFormatLatitude, NumberFormat numberFormatLongitude) { //this.displayName = displayName; this.numberFormatLatitude = numberFormatLatitude; this.numberFormatLongitude = numberFormatLongitude; } // public String getDisplayName() { // return this.toString(); // } public NumberFormat getNumberFormatLatitude() { return numberFormatLatitude; } public NumberFormat getNumberFormatLongitude() { return numberFormatLongitude; } @Override public String toString() { //return displayName; switch(this) { case DEG_ENG:return I18nUtils.localizedStringForKey("lp_coords_fmt_degree_eng"); case DEG_LOCAL:return I18nUtils.localizedStringForKey("lp_coords_fmt_degree_local"); case DEG_MIN_ENG:return I18nUtils.localizedStringForKey("lp_coords_fmt_degree_min_eng"); case DEG_MIN_LOCAL:return I18nUtils.localizedStringForKey("lp_coords_fmt_degree_min_local"); case DEG_MIN_SEC_ENG:return I18nUtils.localizedStringForKey("lp_coords_fmt_degree_min_sec_eng"); case DEG_MIN_SEC_LOCAL:return I18nUtils.localizedStringForKey("lp_coords_fmt_degree_min_sec_local"); case TILE_X_Y_Z:return I18nUtils.localizedStringForKey("lp_coords_fmt_tile"); } return I18nUtils.localizedStringForKey("Undefined"); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/model/Layer.java0000644000175000017500000002342012140762730026732 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.model; import java.awt.Dimension; import java.awt.Point; import java.io.StringWriter; import java.util.Collections; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import javax.swing.tree.TreeNode; import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElements; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlTransient; import mobac.exceptions.InvalidNameException; import mobac.program.interfaces.AtlasInterface; import mobac.program.interfaces.CapabilityDeletable; import mobac.program.interfaces.LayerInterface; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSpace; import mobac.program.interfaces.ToolTipProvider; import mobac.utilities.I18nUtils; import mobac.utilities.MyMath; import mobac.utilities.Utilities; import org.apache.log4j.Logger; /** * A layer holding one or multiple maps of the same map source and the same zoom level. The number of maps depends on * the size of the covered area - if it is smaller than the specified maxMapSize then there will be only * one map. * */ @XmlRootElement public class Layer implements LayerInterface, TreeNode, ToolTipProvider, CapabilityDeletable { private static Logger log = Logger.getLogger(Layer.class); @XmlTransient private AtlasInterface atlasInterface; private String name; @XmlElements({ @XmlElement(name = "PolygonMap", type = MapPolygon.class), @XmlElement(name = "Map", type = Map.class) }) private LinkedList maps = new LinkedList(); protected Layer() { } public Layer(AtlasInterface atlasInterface, String name) throws InvalidNameException { this.atlasInterface = atlasInterface; setName(name); } public void addMapsAutocut(String mapNameBase, MapSource mapSource, EastNorthCoordinate minCoordinate, EastNorthCoordinate maxCoordinate, int zoom, TileImageParameters parameters, int maxMapSize) throws InvalidNameException { MapSpace mapSpace = mapSource.getMapSpace(); addMapsAutocut(mapNameBase, mapSource, minCoordinate.toTileCoordinate(mapSpace, zoom), maxCoordinate.toTileCoordinate(mapSpace, zoom), zoom, parameters, maxMapSize, 0); } public void addMapsAutocut(String mapNameBase, MapSource mapSource, Point minTileCoordinate, Point maxTileCoordinate, int zoom, TileImageParameters parameters, int maxMapSize, int overlapTiles) throws InvalidNameException { log.trace("Adding new map(s): \"" + mapNameBase + "\" " + mapSource + " zoom=" + zoom + " min=" + minTileCoordinate.x + "/" + minTileCoordinate.y + " max=" + maxTileCoordinate.x + "/" + maxTileCoordinate.y); int tileSize = mapSource.getMapSpace().getTileSize(); minTileCoordinate.x -= minTileCoordinate.x % tileSize; minTileCoordinate.y -= minTileCoordinate.y % tileSize; maxTileCoordinate.x += tileSize - 1 - (maxTileCoordinate.x % tileSize); maxTileCoordinate.y += tileSize - 1 - (maxTileCoordinate.y % tileSize); Dimension tileDimension; if (parameters == null) tileDimension = new Dimension(tileSize, tileSize); else tileDimension = parameters.getDimension(); // We adapt the max map size to the tile size so that we do // not get ugly cutted/incomplete tiles at the borders Dimension maxMapDimension = new Dimension(maxMapSize, maxMapSize); maxMapDimension.width -= maxMapSize % tileDimension.width; maxMapDimension.height -= maxMapSize % tileDimension.height; int mapWidth = maxTileCoordinate.x - minTileCoordinate.x; int mapHeight = maxTileCoordinate.y - minTileCoordinate.y; if (mapWidth < maxMapDimension.width && mapHeight < maxMapDimension.height) { Map s = new Map(this, mapNameBase, mapSource, zoom, minTileCoordinate, maxTileCoordinate, parameters); maps.add(s); return; } Dimension nextMapStep = new Dimension(maxMapDimension.width - (tileDimension.width * overlapTiles), maxMapDimension.height - (tileDimension.height * overlapTiles)); int maxXCounter = MyMath.divCeil(mapWidth, nextMapStep.width); int maxYCounter = MyMath.divCeil(mapHeight, nextMapStep.height); int maxMapCounter = maxXCounter * maxYCounter; int maxMapCountDigits = (int) Math.ceil(Math.log10(maxMapCounter)); String mapNameFormat = "%s (%0" + maxMapCountDigits + "d)"; int mapCounter = 0; for (int mapX = minTileCoordinate.x; mapX < maxTileCoordinate.x; mapX += nextMapStep.width) { for (int mapY = minTileCoordinate.y; mapY < maxTileCoordinate.y; mapY += nextMapStep.height) { int maxX = Math.min(mapX + maxMapDimension.width, maxTileCoordinate.x); int maxY = Math.min(mapY + maxMapDimension.height, maxTileCoordinate.y); Point min = new Point(mapX, mapY); Point max = new Point(maxX - 1, maxY - 1); String mapName = String.format(mapNameFormat, new Object[] { mapNameBase, mapCounter++ }); Map s = new Map(this, mapName, mapSource, zoom, min, max, parameters); maps.add(s); } } } public void delete() { maps.clear(); atlasInterface.deleteLayer(this); } public AtlasInterface getAtlas() { return atlasInterface; } public void addMap(MapInterface map) { // TODO: Add name collision check maps.add(map); map.setLayer(this); } public MapInterface getMap(int index) { return maps.get(index); } public int getMapCount() { return maps.size(); } @XmlAttribute public String getName() { return name; } public void setName(String newName) throws InvalidNameException { if (atlasInterface != null) { for (LayerInterface layer : atlasInterface) { if ((layer != this) && newName.equals(layer.getName())) throw new InvalidNameException("There is already a layer named \"" + newName + "\" in this atlas.\nLayer names have to unique within an atlas."); } } this.name = newName; } @Override public String toString() { return name; } public long calculateTilesToDownload() { long result = 0; for (MapInterface map : maps) result += map.calculateTilesToDownload(); return result; } public double getMinLat() { double lat = 90d; for (MapInterface m : maps) { lat = Math.min(lat, m.getMinLat()); } return lat; } public double getMaxLat() { double lat = -90d; for (MapInterface m : maps) { lat = Math.max(lat, m.getMaxLat()); } return lat; } public double getMinLon() { double lon = 180d; for (MapInterface m : maps) { lon = Math.min(lon, m.getMinLon()); } return lon; } public double getMaxLon() { double lon = -180d; for (MapInterface m : maps) { lon = Math.max(lon, m.getMaxLon()); } return lon; } public String getToolTip() { StringWriter sw = new StringWriter(1024); sw.write(""); sw.write(I18nUtils.localizedStringForKey("lp_atlas_info_layer_title")); sw.write(I18nUtils.localizedStringForKey("lp_atlas_info_layer_map_count", maps.size())); sw.write(I18nUtils.localizedStringForKey("lp_atlas_info_max_tile", calculateTilesToDownload())); sw.write(I18nUtils.localizedStringForKey("lp_atlas_info_area_start", Utilities.prettyPrintLatLon(getMaxLat(), true), Utilities.prettyPrintLatLon(getMinLon(), false))); sw.write(I18nUtils.localizedStringForKey("lp_atlas_info_area_end", Utilities.prettyPrintLatLon(getMinLat(), true), Utilities.prettyPrintLatLon(getMaxLon(), false))); sw.write(""); return sw.toString(); } public Iterator iterator() { return maps.iterator(); } public Enumeration children() { return Collections.enumeration(maps); } public boolean getAllowsChildren() { return true; } public TreeNode getChildAt(int childIndex) { return (TreeNode) maps.get(childIndex); } public int getChildCount() { return maps.size(); } public int getIndex(TreeNode node) { return maps.indexOf(node); } public TreeNode getParent() { return (TreeNode) atlasInterface; } public boolean isLeaf() { return false; } public void afterUnmarshal(Unmarshaller u, Object parent) { this.atlasInterface = (Atlas) parent; } public boolean checkData() { if (atlasInterface == null) return true; if (name == null) return true; // Check for duplicate map names HashSet names = new HashSet(maps.size()); for (MapInterface map : maps) names.add(map.getName()); if (names.size() < maps.size()) return true; // at least one duplicate name found return false; } public void deleteMap(Map map) { maps.remove(map); } public LayerInterface deepClone(AtlasInterface atlas) { Layer layer = new Layer(); layer.atlasInterface = atlas; layer.name = name; for (MapInterface map : maps) layer.maps.add(map.deepClone(layer)); return layer; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/model/UnitSystem.java0000644000175000017500000000536412127544344030015 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.model; import mobac.utilities.I18nUtils; public enum UnitSystem { Metric(6367.5d, 1000, 2.54d, "km", "m", "cm"), // Imperial(3963.192d, 5280, 1d, "mi", "ft", "in"); /** * Points per inch, default value for PDF format. */ public static final double PPI = 72d; public static double pointsToPixels(double points, int dpi) { return points / PPI * dpi; } public static double pixelsToPoints(double pixels, int dpi) { return pixels / dpi * PPI; } public final double earthRadius; public final String unitLarge; public final String unitSmall; public final String unitTiny; public final int unitFactor; public final double inchFactor; public final double maxAngularDistSmall; private UnitSystem(double earthRadius, int unitFactor, double inchFactor, String unitLarge, String unitSmall, String unitTiny) { this.earthRadius = earthRadius; this.unitFactor = unitFactor; this.inchFactor = inchFactor; this.unitLarge = unitLarge; this.unitSmall = unitSmall; this.unitTiny = unitTiny; this.maxAngularDistSmall = 1d / (earthRadius * unitFactor); } private double unitsToInches(double units) { return units / inchFactor; } private double inchesToUnits(double inches) { return inches * inchFactor; } public double unitsToPoints(double units) { return unitsToInches(units) * PPI; } public double pointsToUnits(double points) { return inchesToUnits(points / PPI); } public double unitsToPixels(double units, int dpi) { return unitsToInches(units) * dpi; } public double pixelsToUnits(double pixels, int dpi) { return inchesToUnits(pixels / dpi); } public String toString() { if (Metric.equals(this)) { return I18nUtils.localizedStringForKey("set_display_unit_system_metric"); } else { return I18nUtils.localizedStringForKey("set_display_unit_system_imperial"); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/model/TileImageType.java0000644000175000017500000000305312122526604030356 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.model; /** * Supported file extensions of all {@link TileImageFormat} enums. */ public enum TileImageType { PNG("png"), JPG("jpeg"), GIF("gif"); private final String mime; private TileImageType(String mime) { this.mime = mime; } public String getFileExt() { return name().toLowerCase(); } public String getMimeType() { return mime; } public static TileImageType getTileImageType(String type) { try { return TileImageType.valueOf(type.toUpperCase()); } catch (IllegalArgumentException e) { for (TileImageType t : TileImageType.values()) { if (t.getFileExt().equalsIgnoreCase(type)) return t; } throw e; } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/model/EastNorthCoordinate.java0000644000175000017500000000406012122526604031572 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.model; import java.awt.Point; import java.awt.geom.Point2D; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlRootElement; import mobac.program.interfaces.MapSpace; import mobac.utilities.Utilities; @XmlRootElement public class EastNorthCoordinate { @XmlAttribute public double lat; @XmlAttribute public double lon; public EastNorthCoordinate() { lat = Double.NaN; lon = Double.NaN; } public EastNorthCoordinate(MapSpace mapSpace, int zoom, int pixelCoordinateX, int pixelCoordinateY) { this.lat = mapSpace.cYToLat(pixelCoordinateY, zoom); this.lon = mapSpace.cXToLon(pixelCoordinateX, zoom); } public EastNorthCoordinate(double lat, double lon) { this.lat = lat; this.lon = lon; } public EastNorthCoordinate(Point2D.Double c) { this.lat = c.y; this.lon = c.x; } public Point toTileCoordinate(MapSpace mapSpace, int zoom) { int x = mapSpace.cLonToX(lon, zoom); int y = mapSpace.cLatToY(lat, zoom); return new Point(x, y); } @Override public String toString() { return Utilities.prettyPrintLatLon(lat, true) + " " + Utilities.prettyPrintLatLon(lon, false); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/model/Atlas.java0000644000175000017500000001371612140762730026731 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.model; import java.io.StringWriter; import java.util.Collections; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import javax.swing.tree.TreeNode; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElements; import javax.xml.bind.annotation.XmlRootElement; import mobac.program.interfaces.AtlasInterface; import mobac.program.interfaces.LayerInterface; import mobac.program.interfaces.ToolTipProvider; import mobac.utilities.I18nUtils; import mobac.utilities.Utilities; import org.apache.commons.lang3.StringEscapeUtils; @XmlRootElement public class Atlas implements AtlasInterface, ToolTipProvider, TreeNode { public static final int CURRENT_ATLAS_VERSION = 1; @XmlAttribute private int version = 0; private String name = I18nUtils.localizedStringForKey("Unnamed"); @XmlElements({ @XmlElement(name = "Layer", type = Layer.class) }) private List layers = new LinkedList(); private AtlasOutputFormat outputFormat = AtlasOutputFormat.FORMATS.get(0); public static Atlas newInstance() { Atlas atlas = new Atlas(); atlas.version = CURRENT_ATLAS_VERSION; return atlas; } private Atlas() { super(); } public void addLayer(LayerInterface l) { layers.add(l); } public void deleteLayer(LayerInterface l) { layers.remove(l); } public LayerInterface getLayer(int index) { return layers.get(index); } public int getLayerCount() { return layers.size(); } @XmlAttribute public String getName() { return name; } public void setName(String newName) { this.name = newName; } @XmlAttribute public AtlasOutputFormat getOutputFormat() { return outputFormat; } public void setOutputFormat(AtlasOutputFormat atlasOutputFormat) { if (atlasOutputFormat == null) throw new NullPointerException(); this.outputFormat = atlasOutputFormat; } @Override public String toString() { return getName() + " (" + outputFormat + ")"; } public Iterator iterator() { return layers.iterator(); } public long calculateTilesToDownload() { long tiles = 0; for (LayerInterface layer : layers) tiles += layer.calculateTilesToDownload(); return tiles; } public boolean checkData() { if (name == null) // name set? return true; // Check for duplicate layer names HashSet names = new HashSet(layers.size()); for (LayerInterface layer : layers) names.add(layer.getName()); if (names.size() < layers.size()) return true; // at least one duplicate name found return false; } public double getMinLat() { double lat = 90d; for (LayerInterface l : layers) { lat = Math.min(lat, l.getMinLat()); } return lat; } public double getMaxLat() { double lat = -90d; for (LayerInterface l : layers) { lat = Math.max(lat, l.getMaxLat()); } return lat; } public double getMinLon() { double lon = 180d; for (LayerInterface l : layers) { lon = Math.min(lon, l.getMinLon()); } return lon; } public double getMaxLon() { double lon = -180d; for (LayerInterface l : layers) { lon = Math.max(lon, l.getMaxLon()); } return lon; } public String getToolTip() { StringWriter sw = new StringWriter(1024); sw.write(""); sw.write(I18nUtils.localizedStringForKey("lp_atlas_info_atlas_title")); sw.write(I18nUtils.localizedStringForKey("lp_atlas_info_atlas_name", StringEscapeUtils.escapeHtml4(name))); sw.write(I18nUtils.localizedStringForKey("lp_atlas_info_atlas_layer", layers.size())); sw.write(I18nUtils.localizedStringForKey("lp_atlas_info_atlas_format", outputFormat.toString())); sw.write(I18nUtils.localizedStringForKey("lp_atlas_info_max_tile", calculateTilesToDownload())); sw.write(I18nUtils.localizedStringForKey("lp_atlas_info_area_start", Utilities.prettyPrintLatLon(getMaxLat(), true), Utilities.prettyPrintLatLon(getMinLon(), false))); sw.write(I18nUtils.localizedStringForKey("lp_atlas_info_area_end", Utilities.prettyPrintLatLon(getMinLat(), true), Utilities.prettyPrintLatLon(getMaxLon(), false))); sw.write(""); return sw.toString(); } public Enumeration children() { return Collections.enumeration(layers); } public boolean getAllowsChildren() { return true; } public TreeNode getChildAt(int childIndex) { return (TreeNode) layers.get(childIndex); } public int getChildCount() { return layers.size(); } public int getIndex(TreeNode node) { return layers.indexOf(node); } public TreeNode getParent() { return null; } public boolean isLeaf() { return false; } public int getVersion() { return version; } public AtlasInterface deepClone() { Atlas atlas = new Atlas(); atlas.version = version; atlas.name = name; atlas.outputFormat = outputFormat; for (LayerInterface layer : layers) { atlas.layers.add(layer.deepClone(atlas)); } return atlas; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/model/package-info.java0000644000175000017500000000272712122526604030207 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ /** * Package level definition of adapters for JAXB */ @XmlJavaTypeAdapters({ @XmlJavaTypeAdapter(value = PointAdapter.class, type = java.awt.Point.class), @XmlJavaTypeAdapter(value = DimensionAdapter.class, type = java.awt.Dimension.class), @XmlJavaTypeAdapter(value = PolygonAdapter.class, type = java.awt.Polygon.class) }) package mobac.program.model; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters; import mobac.program.jaxb.DimensionAdapter; import mobac.program.jaxb.PointAdapter; import mobac.program.jaxb.PolygonAdapter; mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/model/MercatorPixelCoordinate.java0000644000175000017500000000516312122526604032446 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.model; import mobac.gui.mapview.JMapViewer; import mobac.program.interfaces.MapSpace; /** * Coordinate point in Mercator projection regarding a world with height and * width 230 pixels (222 tiles with size 256 pixels). This * is the maximum size a int can hold. */ public class MercatorPixelCoordinate { private final MapSpace mapSpace; private final int x; private final int y; private final int zoom; public MercatorPixelCoordinate(MapSpace mapSpace, int x, int y, int zoom) { super(); this.mapSpace = mapSpace; this.x = x; this.y = y; this.zoom = zoom; } public MercatorPixelCoordinate(MapSpace mapSpace, double lat, double lon) { super(); this.mapSpace = mapSpace; this.x = mapSpace.cLonToX(lon, JMapViewer.MAX_ZOOM); this.y = mapSpace.cLatToY(lat, JMapViewer.MAX_ZOOM); this.zoom = JMapViewer.MAX_ZOOM; } public int getX() { return x; } public int getY() { return y; } public int getZoom() { return zoom; } public MapSpace getMapSpace() { return mapSpace; } public EastNorthCoordinate getEastNorthCoordinate() { double lon = mapSpace.cXToLon(x, zoom); double lat = mapSpace.cYToLat(y, zoom); return new EastNorthCoordinate(lat, lon); } public MercatorPixelCoordinate adaptToZoomlevel(int aZoomlevel) { int zoomDiff = this.zoom - aZoomlevel; int new_x = x; int new_y = y; if (zoomDiff < 0) { zoomDiff = -zoomDiff; new_x <<= zoomDiff; new_y <<= zoomDiff; } else { new_x >>= zoomDiff; new_y >>= zoomDiff; } return new MercatorPixelCoordinate(mapSpace, new_x, new_y, aZoomlevel); } @Override public String toString() { return "x=" + x + " y=" + y + " zoom=" + zoom; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/model/SelectedZoomLevels.java0000644000175000017500000000400312122526604031420 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.model; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.TreeSet; import mobac.gui.components.JZoomCheckBox; public class SelectedZoomLevels { private TreeSet zoomLevels = new TreeSet(); public SelectedZoomLevels(JZoomCheckBox[] zoomCheckboxes) { for (JZoomCheckBox cb : zoomCheckboxes) { if (cb.isSelected()) setZoomLevelSelected(cb.getZoomLevel()); } } public SelectedZoomLevels(List zoomLevelList) { zoomLevels.addAll(zoomLevelList); } protected SelectedZoomLevels() { } public void setZoomLevelSelected(int zoomLevel) { zoomLevels.add(new Integer(zoomLevel)); } public int[] getZoomLevels() { int result[] = new int[zoomLevels.size()]; int i = 0; for (Integer z : zoomLevels) { result[i++] = z.intValue(); } return result; } public List getZoomLevelList() { return new ArrayList(zoomLevels); } public int getZoomLevelCount() { return zoomLevels.size(); } @Override public String toString() { return "ZoomLevels: " + Arrays.toString(getZoomLevels()); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/model/Bookmark.java0000644000175000017500000000456112122526604027426 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.model; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; import mobac.mapsources.MapSourcesManager; import mobac.program.interfaces.MapSource; @XmlAccessorType(XmlAccessType.FIELD) public class Bookmark extends EastNorthCoordinate { @XmlAttribute protected int zoom; @XmlAttribute protected String name; @XmlAttribute protected String mapSource; /** * Needed for JAXB */ @SuppressWarnings("unused") private Bookmark() { } public Bookmark(MapSource mapSource, int zoom, int pixelCoordinateX, int pixelCoordinateY) { this(null, mapSource, zoom, pixelCoordinateX, pixelCoordinateY); } public Bookmark(String name, MapSource mapSource, int zoom, int pixelCoordinateX, int pixelCoordinateY) { super(mapSource.getMapSpace(), zoom, pixelCoordinateX, pixelCoordinateY); this.mapSource = mapSource.getName(); this.zoom = zoom; this.name = name; } public MapSource getMapSource() { return MapSourcesManager.getInstance().getSourceByName(mapSource); } public int getZoom() { return zoom; } public void setName(String name) { if (name != null && name.trim().length() == 0) name = null; this.name = name; } public String getName() { return name; } @Override public String toString() { if (name != null) return name; return String.format("%s at lat=%.3f lon=%.3f (zoom = %d)", mapSource, lat, lon, zoom); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/model/Map.java0000644000175000017500000002402312140762730026373 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.model; import java.awt.Dimension; import java.awt.Point; import java.io.StringWriter; import java.util.Enumeration; import javax.swing.tree.TreeNode; import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlTransient; import mobac.exceptions.InvalidNameException; import mobac.program.JobDispatcher.Job; import mobac.program.download.jobenumerators.DownloadJobEnumerator; import mobac.program.interfaces.CapabilityDeletable; import mobac.program.interfaces.DownloadJobListener; import mobac.program.interfaces.DownloadableElement; import mobac.program.interfaces.LayerInterface; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSpace; import mobac.program.interfaces.TileFilter; import mobac.program.interfaces.ToolTipProvider; import mobac.program.tilefilter.DummyTileFilter; import mobac.utilities.I18nUtils; import mobac.utilities.tar.TarIndexedArchive; import org.apache.commons.lang3.StringEscapeUtils; import org.apache.log4j.Logger; public class Map implements MapInterface, ToolTipProvider, CapabilityDeletable, TreeNode, DownloadableElement { protected String name; protected Layer layer; protected TileImageParameters parameters = null; @XmlAttribute protected Point maxTileCoordinate = null; @XmlAttribute protected Point minTileCoordinate = null; @XmlAttribute protected MapSource mapSource = null; protected Dimension tileDimension = null; @XmlAttribute protected int zoom; private static Logger log = Logger.getLogger(Map.class); protected Map() { } protected Map(Layer layer, String name, MapSource mapSource, int zoom, Point minTileCoordinate, Point maxTileCoordinate, TileImageParameters parameters) { this.layer = layer; this.maxTileCoordinate = maxTileCoordinate; this.minTileCoordinate = minTileCoordinate; this.name = name; this.mapSource = mapSource; this.zoom = zoom; this.parameters = parameters; calculateRuntimeValues(); } protected void calculateRuntimeValues() { if (mapSource == null) throw new RuntimeException("The map source of map " + name + " is unknown to MOBAC"); if (parameters == null) { int tileSize = mapSource.getMapSpace().getTileSize(); tileDimension = new Dimension(tileSize, tileSize); } else tileDimension = parameters.getDimension(); } public LayerInterface getLayer() { return layer; } @XmlTransient public void setLayer(LayerInterface layer) { this.layer = (Layer) layer; } public MapSource getMapSource() { return mapSource; } public Point getMaxTileCoordinate() { return maxTileCoordinate; } public Point getMinTileCoordinate() { return minTileCoordinate; } @XmlAttribute public String getName() { return name; } public int getZoom() { return zoom; } @Override public String toString() { return getName(); } public TileImageParameters getParameters() { return parameters; } public void setParameters(TileImageParameters parameters) { this.parameters = parameters; } public String getInfoText() { return "Map\n name=" + name + "\n mapSource=" + mapSource + "\n zoom=" + zoom + "\n maxTileCoordinate=" + maxTileCoordinate.x + "/" + maxTileCoordinate.y + "\n minTileCoordinate=" + minTileCoordinate.x + "/" + minTileCoordinate.y + "\n parameters=" + parameters; } public String getToolTip() { MapSpace mapSpace = mapSource.getMapSpace(); EastNorthCoordinate tl = new EastNorthCoordinate(mapSpace, zoom, minTileCoordinate.x, minTileCoordinate.y); EastNorthCoordinate br = new EastNorthCoordinate(mapSpace, zoom, maxTileCoordinate.x, maxTileCoordinate.y); StringWriter sw = new StringWriter(1024); sw.write(""); sw.write(I18nUtils.localizedStringForKey("lp_atlas_info_map_title")); sw.write(I18nUtils.localizedStringForKey("lp_atlas_info_map_source", StringEscapeUtils.escapeHtml4(mapSource.toString()), StringEscapeUtils.escapeHtml4(mapSource.getName()))); sw.write(I18nUtils.localizedStringForKey("lp_atlas_info_map_zoom_lv", zoom)); sw.write(I18nUtils.localizedStringForKey("lp_atlas_info_map_area_start", tl.toString(), minTileCoordinate.x, minTileCoordinate.y)); sw.write(I18nUtils.localizedStringForKey("lp_atlas_info_map_area_end", br.toString(), maxTileCoordinate.x, maxTileCoordinate.y)); sw.write(I18nUtils.localizedStringForKey("lp_atlas_info_map_size", (maxTileCoordinate.x - minTileCoordinate.x + 1), (maxTileCoordinate.y - minTileCoordinate.y + 1))); if (parameters != null) { sw.write(String.format(I18nUtils.localizedStringForKey("lp_atlas_info_tile_size"), parameters.getWidth(), parameters.getHeight())); sw.write(String.format(I18nUtils.localizedStringForKey("lp_atlas_info_tile_format"), parameters.getFormat() .toString())); } else { sw.write(I18nUtils.localizedStringForKey("lp_atlas_info_tile_format_origin")); } sw.write(String.format(I18nUtils.localizedStringForKey("lp_atlas_info_max_tile"), calculateTilesToDownload())); sw.write(""); return sw.toString(); } public Dimension getTileSize() { return tileDimension; } public double getMinLat() { return mapSource.getMapSpace().cYToLat(maxTileCoordinate.y, zoom); } public double getMaxLat() { return mapSource.getMapSpace().cYToLat(minTileCoordinate.y, zoom); } public double getMinLon() { return mapSource.getMapSpace().cXToLon(minTileCoordinate.x, zoom); } public double getMaxLon() { return mapSource.getMapSpace().cXToLon(maxTileCoordinate.x, zoom); } public void delete() { layer.deleteMap(this); } public void setName(String newName) throws InvalidNameException { if (layer != null) { for (MapInterface map : layer) { if ((map != this) && (newName.equals(map.getName()))) throw new InvalidNameException("There is already a map named \"" + newName + "\" in this layer.\nMap names have to unique within an layer."); } } this.name = newName; } public Enumeration children() { return null; } public boolean getAllowsChildren() { return false; } public TreeNode getChildAt(int childIndex) { return null; } public int getChildCount() { return 0; } public int getIndex(TreeNode node) { return 0; } public TreeNode getParent() { return (TreeNode) layer; } public boolean isLeaf() { return true; } public long calculateTilesToDownload() { int tileSize = mapSource.getMapSpace().getTileSize(); // This algorithm has to be identically to those used in // @DownloadJobEnumerator int xMin = minTileCoordinate.x / tileSize; int xMax = maxTileCoordinate.x / tileSize; int yMin = minTileCoordinate.y / tileSize; int yMax = maxTileCoordinate.y / tileSize; int width = xMax - xMin + 1; int height = yMax - yMin + 1; int tileCount = width * height; // TODO correct tile count in case of multi-layer maps // if (mapSource instanceof MultiLayerMapSource) { // // We have a map with two layers and for each layer we have to // // download the tiles - therefore double the tileCount // tileCount *= 2; // } return tileCount; } public boolean checkData() { boolean result = false; boolean[] checks = { name == null, // 0 layer == null, // 1 maxTileCoordinate == null, // 2 minTileCoordinate == null, // 3 mapSource == null, // 4 zoom < 0 // 5 }; for (int i = 0; i < checks.length; i++) if (checks[i]) { log.error("Problem detectected with map \"" + name + "\" check: " + i); result = true; } // Automatically correct bad ordered min/max coordinates try { if (minTileCoordinate.x > maxTileCoordinate.x) { int tmp = maxTileCoordinate.x; maxTileCoordinate.x = minTileCoordinate.x; minTileCoordinate.x = tmp; } if (minTileCoordinate.y > maxTileCoordinate.y) { int tmp = maxTileCoordinate.y; maxTileCoordinate.y = minTileCoordinate.y; minTileCoordinate.y = tmp; } } catch (Exception e) { } return result; } public MapInterface deepClone(LayerInterface newLayer) { try { Map map = this.getClass().newInstance(); map.layer = (Layer) newLayer; map.mapSource = mapSource; map.maxTileCoordinate = (Point) maxTileCoordinate.clone(); map.minTileCoordinate = (Point) minTileCoordinate.clone(); map.name = name; if (parameters != null) map.parameters = (TileImageParameters) parameters.clone(); else map.parameters = null; map.tileDimension = (Dimension) tileDimension.clone(); map.zoom = zoom; return map; } catch (Exception e) { throw new RuntimeException(e); } } /** * Needs to be public - otherwise it will be kicked by ProGuard! */ public void afterUnmarshal(Unmarshaller u, Object parent) { this.layer = (Layer) parent; calculateRuntimeValues(); } public Enumeration getDownloadJobs(TarIndexedArchive tileArchive, DownloadJobListener listener) { return new DownloadJobEnumerator(this, mapSource, tileArchive, listener); } public TileFilter getTileFilter() { return new DummyTileFilter(); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/model/AnyAttributeMap.java0000644000175000017500000000357212122526604030733 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.model; import java.util.Comparator; import java.util.TreeMap; import javax.xml.bind.annotation.XmlAnyAttribute; import javax.xml.namespace.QName; /** * A map implementation for catching all attributes via {@link XmlAnyAttribute} */ public class AnyAttributeMap extends TreeMap { public AnyAttributeMap() { super(new QNameComparator()); } public static class QNameComparator implements Comparator { public int compare(QName o1, QName o2) { return o1.getLocalPart().compareTo(o2.getLocalPart()); } } public String getAttr(String key) { return (String) get(new QName(key)); } public void setAttr(String key, String value) { put(new QName(key), value); } public int getInt(TileImageParameters.Name key) { return Integer.parseInt(getAttr(key.name())); } public int getInt(String key) { return Integer.parseInt(getAttr(key)); } public void setInt(String key, int value) { put(new QName(key), Integer.toString(value)); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/model/SettingsWgsGrid.java0000644000175000017500000000465712122526604030756 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.model; import java.awt.Color; import java.awt.Font; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import mobac.gui.mapview.WgsGrid.WgsDensity; import mobac.program.jaxb.ColorAdapter; import mobac.program.jaxb.FontAdapter; public class SettingsWgsGrid implements Cloneable { public static final Color DEFAULT_COLOR = Color.BLUE; public static final WgsDensity DEFAULT_DENSITY = WgsDensity.SECOND_1; public static final Font DEFAULT_FONT = new Font(Font.SANS_SERIF, Font.PLAIN, 12); public static final float WIDTH_DEFAULT = 1f; public static final float WIDTH_MIN = 0.5f; public static final float WIDTH_MAX = 5f; @XmlElement(defaultValue = "#0000FF") @XmlJavaTypeAdapter(ColorAdapter.class) public Color color = DEFAULT_COLOR; public boolean compressLabels = false; public WgsDensity density = DEFAULT_DENSITY; public boolean enabled = false; @XmlElement(defaultValue = "SansSerif-PLAIN-12") @XmlJavaTypeAdapter(FontAdapter.class) public Font font = DEFAULT_FONT; public float width = WIDTH_DEFAULT; @Override public SettingsWgsGrid clone() { try { return (SettingsWgsGrid) super.clone(); } catch (Exception e) { return new SettingsWgsGrid(); } } public void checkValues() { if (width < WIDTH_MIN || width > WIDTH_MAX) { width = WIDTH_DEFAULT; } if (density == null) { density = DEFAULT_DENSITY; } if (color == null) { color = DEFAULT_COLOR; } if (font == null) { font = DEFAULT_FONT; } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/model/PaperSize.java0000644000175000017500000000633412122526604027563 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.model; import com.itextpdf.text.PageSize; import com.itextpdf.text.Rectangle; public class PaperSize { public static enum Format { A0(PageSize.A0), A1(PageSize.A1), A2(PageSize.A2), A3(PageSize.A3), A4(PageSize.A4), A5(PageSize.A5), A6( PageSize.A6), A7(PageSize.A7), A8(PageSize.A8), A9(PageSize.A9), A10(PageSize.A10), ARCH_A( PageSize.ARCH_A), ARCH_B(PageSize.ARCH_B), ARCH_C(PageSize.ARCH_C), ARCH_D(PageSize.ARCH_D), ARCH_E( PageSize.ARCH_E), B0(PageSize.B0), B1(PageSize.B1), B2(PageSize.B2), B3(PageSize.B3), B4(PageSize.B4), B5( PageSize.B5), B6(PageSize.B6), B7(PageSize.B7), B8(PageSize.B8), B9(PageSize.B9), B10(PageSize.B10), // CROWN_OCTAVO(PageSize.CROWN_OCTAVO), // CROWN_QUARTO(PageSize.CROWN_QUARTO), // DEMY_OCTAVO(PageSize.DEMY_OCTAVO), // DEMY_QUARTO(PageSize.DEMY_QUARTO), // EXECUTIVE(PageSize.EXECUTIVE), // FLSA(PageSize.FLSA), // FLSE(PageSize.FLSE), // HALFLETTER(PageSize.HALFLETTER), // ID_1(PageSize.ID_1), // ID_2(PageSize.ID_2), // ID_3(PageSize.ID_3), // LARGE_CROWN_OCTAVO(PageSize.LARGE_CROWN_OCTAVO), // LARGE_CROWN_QUARTO(PageSize.LARGE_CROWN_QUARTO), // LEDGER(PageSize.LEDGER), // LEGAL(PageSize.LEGAL), // LETTER(PageSize.LETTER), // NOTE(PageSize.NOTE), // PENGUIN_LARGE_PAPERBACK(PageSize.PENGUIN_LARGE_PAPERBACK), // PENGUIN_SMALL_PAPERBACK(PageSize.PENGUIN_SMALL_PAPERBACK), // POSTCARD(PageSize.POSTCARD), // ROYAL_OCTAVO(PageSize.ROYAL_OCTAVO), // ROYAL_QUARTO(PageSize.ROYAL_QUARTO), // SMALL_PAPERBACK(PageSize.SMALL_PAPERBACK), // TABLOID(PageSize.TABLOID) ; public final float width, height; private Format(final Rectangle rectangle) { width = rectangle.getWidth(); height = rectangle.getHeight(); } } public final double width, height; public final boolean landscape; public final Format format; public PaperSize(Format format, boolean landscape) { if (landscape) { width = format.height; height = format.width; } else { width = format.width; height = format.height; } this.landscape = landscape; this.format = format; } public PaperSize(double width, double height) { this.width = width; this.height = height; format = null; landscape = width > height; } public Rectangle createRectangle() { return new Rectangle((float) width, (float) height); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/model/SettingsPaperAtlas.java0000644000175000017500000000627012122526604031435 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.model; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import mobac.gui.mapview.WgsGrid.WgsDensity; import mobac.program.jaxb.PaperSizeAdapter; import mobac.program.model.PaperSize.Format; @XmlRootElement public class SettingsPaperAtlas implements Cloneable { public static final int COMPRESSION_DEFAULT = 6, COMPRESSION_MAX = 9, COMPRESSION_MIN = 0, CROP_DEFAULT = 15, CROP_MAX = 100, CROP_MIN = 0, DPI_DEFAULT = 96, DPI_MAX = 300, DPI_MIN = 72; public static final double MARGIN_DEFAULT = 22.6d, MARGIN_MAX = 144d, MARGIN_MIN = 0.0d, OVERLAP_DEFAULT = 28.2d, OVERLAP_MIN = 0d, OVERLAP_MAX = 144d, PAPER_SIZE_MAX = 16384d, PAPER_SIZE_MIN = 1d; public static final PaperSize PAPER_SIZE_DEFAULT = new PaperSize(Format.A4, false); public int compression = COMPRESSION_DEFAULT, crop = CROP_DEFAULT, dpi = DPI_DEFAULT; public double marginBottom = MARGIN_DEFAULT, marginLeft = MARGIN_DEFAULT, marginRight = MARGIN_DEFAULT, marginTop = MARGIN_DEFAULT, overlap = OVERLAP_DEFAULT; public boolean compass = true, pageNumbers = true, scaleBar = true, wgsEnabled = true; @XmlElement(defaultValue = "A4") @XmlJavaTypeAdapter(PaperSizeAdapter.class) public PaperSize paperSize = PAPER_SIZE_DEFAULT; public WgsDensity wgsDensity = SettingsWgsGrid.DEFAULT_DENSITY; @Override public SettingsPaperAtlas clone() { try { return (SettingsPaperAtlas) super.clone(); } catch (Exception e) { throw new InternalError(); } } public void checkValues() { if (compression < COMPRESSION_MIN || compression > COMPRESSION_MAX) { compression = COMPRESSION_DEFAULT; } if (crop < CROP_MIN || crop > CROP_MAX) { crop = CROP_DEFAULT; } if (dpi < DPI_MIN || dpi > DPI_MAX) { dpi = DPI_DEFAULT; } if (marginBottom < MARGIN_MIN || marginBottom > MARGIN_MAX) { marginBottom = MARGIN_DEFAULT; } if (marginLeft < MARGIN_MIN || marginLeft > MARGIN_MAX) { marginLeft = MARGIN_DEFAULT; } if (marginRight < MARGIN_MIN || marginRight > MARGIN_MAX) { marginRight = MARGIN_DEFAULT; } if (marginTop < MARGIN_MIN || marginTop > MARGIN_MAX) { marginTop = MARGIN_DEFAULT; } if (paperSize == null) { paperSize = PAPER_SIZE_DEFAULT; } if (wgsDensity == null) { wgsDensity = SettingsWgsGrid.DEFAULT_DENSITY; } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/model/MapSourcesListModel.java0000644000175000017500000000503212122526604031551 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.model; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Vector; import javax.swing.AbstractListModel; import mobac.program.interfaces.MapSource; public class MapSourcesListModel extends AbstractListModel { ArrayList mapSources; public MapSourcesListModel(Vector source) { this.mapSources = new ArrayList(source); } public Object getElementAt(int index) { return mapSources.get(index); } public int getSize() { return mapSources.size(); } public Vector getVector() { return new Vector(mapSources); } public MapSource removeElement(int index) { fireIntervalRemoved((Object) this, index, index); return mapSources.remove(index); } public void addElement(MapSource element) { mapSources.add(element); fireIntervalAdded((Object) this, mapSources.size(), mapSources.size()); } public boolean moveUp(int index) { if (index < 1) return false; MapSource ms = mapSources.remove(index - 1); mapSources.add(index, ms); fireContentsChanged(this, index - 1, index); return true; } public boolean moveDown(int index) { if (index + 1 >= mapSources.size()) return false; MapSource ms = mapSources.remove(index + 1); mapSources.add(index, ms); fireContentsChanged(this, index, index + 1); return true; } public void sort() { Collections.sort(mapSources, new Comparator() { public int compare(MapSource o1, MapSource o2) { return o1.toString().compareTo(o2.toString()); } }); fireContentsChanged(mapSources, 0, mapSources.size()); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/model/Settings.java0000644000175000017500000003662612171650636027477 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.model; import java.awt.Dimension; import java.awt.Point; import java.awt.Toolkit; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.net.Authenticator; import java.net.PasswordAuthentication; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Locale; import java.util.Vector; import java.util.concurrent.TimeUnit; import javax.swing.JOptionPane; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import javax.xml.bind.ValidationEvent; import javax.xml.bind.ValidationEventHandler; import javax.xml.bind.annotation.XmlAccessOrder; import javax.xml.bind.annotation.XmlAccessorOrder; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlTransient; import mobac.gui.actions.GpxLoad; import mobac.gui.panels.JCoordinatesPanel; import mobac.mapsources.MapSourcesManager; import mobac.program.DirectoryManager; import mobac.program.ProgramInfo; import mobac.utilities.I18nUtils; import mobac.utilities.Utilities; import mobac.utilities.stream.ThrottledInputStream; import org.apache.log4j.Logger; @XmlRootElement @XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL) public class Settings { private static Logger log = Logger.getLogger(Settings.class); private static Settings instance = new Settings(); public static final File FILE = new File(DirectoryManager.userSettingsDir, "settings.xml"); private static long SETTINGS_LAST_MODIFIED = 0; private static final String SYSTEM_PROXY_HOST = System.getProperty("http.proxyHost"); private static final String SYSTEM_PROXY_PORT = System.getProperty("http.proxyPort"); @XmlElement(defaultValue = "") private String version; public int maxMapSize = 65536; public int mapOverlapTiles = 0; public boolean tileStoreEnabled = true; /** * Mapview related settings */ public int mapviewZoom = 3; public int mapviewGridZoom = -1; public EastNorthCoordinate mapviewCenterCoordinate = new EastNorthCoordinate(50, 9); public Point mapviewSelectionMax = null; public Point mapviewSelectionMin = null; @XmlElementWrapper(name = "selectedZoomLevels") @XmlElement(name = "zoomLevel") public List selectedZoomLevels = null; @XmlElement(nillable = false) public String mapviewMapSource = null; public String elementName = null; private String userAgent = null; public int downloadThreadCount = 2; public int downloadRetryCount = 1; private boolean customTileProcessing = false; private Dimension tileSize = new Dimension(256, 256); private TileImageFormat tileImageFormat = TileImageFormat.PNG; public CoordinateStringFormat coordinateNumberFormat = CoordinateStringFormat.DEG_LOCAL; public final Directories directories = new Directories(); public static class Directories { @XmlElement private String atlasOutputDirectory = null; @XmlElement public String tileStoreDirectory; @XmlElement private String mapSourcesDirectory; } @XmlElementWrapper(name = "placeBookmarks") @XmlElement(name = "bookmark") public List placeBookmarks = new ArrayList(); /** * Connection timeout in seconds (default 10 seconds) */ public int httpConnectionTimeout = 10; /** * Read timeout in seconds (default 10 seconds) */ public int httpReadTimeout = 10; /** * Maximum expiration (in milliseconds) acceptable. If a server sets an expiration time larger than this value it is * truncated to this value on next download. */ public long tileMaxExpirationTime = TimeUnit.DAYS.toMillis(365); /** * Minimum expiration (in milliseconds) acceptable. If a server sets an expiration time smaller than this value it * is truncated to this value on next download. */ public long tileMinExpirationTime = TimeUnit.DAYS.toMillis(5); /** * Expiration time (in milliseconds) of a tile if the server does not provide an expiration time */ public long tileDefaultExpirationTime = TimeUnit.DAYS.toMillis(28); public String googleLanguage = "en"; public String osmHikingTicket = ""; /** * Development mode enabled/disabled *

* In development mode one additional map source is available for using MOBAC Debug TileServer *

*/ @XmlElement public boolean devMode = false; /** * Saves the last used directory of the GPX file chooser dialog. Used in {@link GpxLoad}. */ public String gpxFileChooserDir = ""; public final AtlasFormatSpecificSettings atlasFormatSpecificSettings = new AtlasFormatSpecificSettings(); public static class AtlasFormatSpecificSettings { @XmlElement public Integer garminCustomMaxMapCount = 100; } public final MainWindowSettings mainWindow = new MainWindowSettings(); public static class MainWindowSettings { public Dimension size = new Dimension(); public Point position = new Point(-1, -1); public boolean maximized = true; public boolean leftPanelVisible = true; public boolean rightPanelVisible = true; @XmlElementWrapper(name = "collapsedPanels") @XmlElement(name = "collapsedPanel") public Vector collapsedPanels = new Vector(); } /** * Network settings */ private ProxyType proxyType = ProxyType.CUSTOM; private String customProxyHost = ""; private String customProxyPort = ""; private String customProxyUserName = ""; private String customProxyPassword = ""; private long bandwidthLimit = 0; @XmlElementWrapper(name = "mapSourcesDisabled") @XmlElement(name = "mapSource") public Vector mapSourcesDisabled = new Vector(); @XmlElementWrapper(name = "mapSourcesEnabled") @XmlElement(name = "mapSource") public Vector mapSourcesEnabled = new Vector(); @XmlElement(name = "MapSourcesUpdate") public final MapSourcesUpdate mapSourcesUpdate = new MapSourcesUpdate(); public static class MapSourcesUpdate { /** * Last ETag value retrieved while online map source update. * * @see MapSourcesManager#mapsourcesOnlineUpdate() * @see http://en.wikipedia.org/wiki/HTTP_ETag */ public String etag; public Date lastUpdate; } public transient UnitSystem unitSystem = UnitSystem.Metric; public final SettingsPaperAtlas paperAtlas = new SettingsPaperAtlas(); public final SettingsWgsGrid wgsGrid = new SettingsWgsGrid(); public boolean ignoreDlErrors = false; public String localeLanguage = null; public String localeCountry = null; private Settings() { elementName = "Layer";// no need i18n for it Dimension dScreen = Toolkit.getDefaultToolkit().getScreenSize(); mainWindow.size.width = (int) (0.9f * dScreen.width); mainWindow.size.height = (int) (0.9f * dScreen.height); mainWindow.collapsedPanels.add(JCoordinatesPanel.NAME); mainWindow.collapsedPanels.add("Gpx"); Locale defaultLocale = Locale.getDefault(); if (defaultLocale.equals(new Locale("zh", "CN"))) { localeLanguage = "zh"; localeCountry = "CN"; } else if (defaultLocale.equals(new Locale("zh", "TW"))) { localeLanguage = "zh"; localeCountry = "TW"; } else if (defaultLocale.equals(new Locale("ja", "JP"))) { localeLanguage = "ja"; localeCountry = "JP"; } else if (defaultLocale.equals(new Locale("fr", "FR"))) { localeLanguage = "fr"; localeCountry = "FR"; } else { localeLanguage = "en"; localeCountry = ""; } } public static Settings getInstance() { return instance; } public static void load() throws JAXBException { try { JAXBContext context = JAXBContext.newInstance(Settings.class); Unmarshaller um = context.createUnmarshaller(); um.setEventHandler(new ValidationEventHandler() { public boolean handleEvent(ValidationEvent event) { log.warn("Problem on loading settings.xml: " + event.getMessage()); return true; } }); instance = (Settings) um.unmarshal(FILE); instance.wgsGrid.checkValues(); instance.paperAtlas.checkValues(); SETTINGS_LAST_MODIFIED = FILE.lastModified(); // Settings 重新加载之后,必须更新语言资源 I18nUtils.updateLocalizedStringFormSettings(); } finally { Settings s = getInstance(); s.applyProxySettings(); } } public static boolean checkSettingsFileModified() { if (SETTINGS_LAST_MODIFIED == 0) return false; // Check if the settings.xml has been modified // since it has been loaded long lastModified = FILE.lastModified(); return (SETTINGS_LAST_MODIFIED != lastModified); } public static void save() throws JAXBException { getInstance().version = ProgramInfo.getVersion(); JAXBContext context = JAXBContext.newInstance(Settings.class); Marshaller m = context.createMarshaller(); m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); ByteArrayOutputStream bo = null; FileOutputStream fo = null; try { // First we write to a buffer and if that works be write the buffer // to disk. Direct writing to file may result in an defect xml file // in case of an error bo = new ByteArrayOutputStream(); m.marshal(getInstance(), bo); fo = new FileOutputStream(FILE); fo.write(bo.toByteArray()); fo.close(); SETTINGS_LAST_MODIFIED = FILE.lastModified(); } catch (IOException e) { throw new JAXBException(e); } finally { Utilities.closeStream(fo); } } public static void loadOrQuit() { try { load(); } catch (JAXBException e) { log.error(e); JOptionPane .showMessageDialog(null, I18nUtils.localizedStringForKey(I18nUtils .localizedStringForKey("msg_settings_file_can_not_parse")), I18nUtils .localizedStringForKey("Error"), JOptionPane.ERROR_MESSAGE); System.exit(0); } } public String getUserAgent() { if (userAgent != null) return userAgent; else return ProgramInfo.getUserAgent(); } public void setUserAgent(String userAgent) { if (userAgent != null) { userAgent = userAgent.trim(); if (userAgent.length() == 0) userAgent = null; } this.userAgent = userAgent; } public boolean isCustomTileSize() { return customTileProcessing; } public void setCustomTileSize(boolean customTileSize) { this.customTileProcessing = customTileSize; } public Dimension getTileSize() { return tileSize; } public void setTileSize(Dimension tileSize) { this.tileSize = tileSize; } public TileImageFormat getTileImageFormat() { return tileImageFormat; } public void setTileImageFormat(TileImageFormat tileImageFormat) { this.tileImageFormat = tileImageFormat; } public ProxyType getProxyType() { return proxyType; } public void setProxyType(ProxyType proxyType) { this.proxyType = proxyType; } public String getCustomProxyHost() { return customProxyHost; } public String getCustomProxyPort() { return customProxyPort; } public void setCustomProxyHost(String proxyHost) { this.customProxyHost = proxyHost; } public void setCustomProxyPort(String proxyPort) { this.customProxyPort = proxyPort; } public String getCustomProxyUserName() { return customProxyUserName; } public void setCustomProxyUserName(String customProxyUserName) { this.customProxyUserName = customProxyUserName; } public String getCustomProxyPassword() { return customProxyPassword; } public void setCustomProxyPassword(String customProxyPassword) { this.customProxyPassword = customProxyPassword; } public void applyProxySettings() { boolean useSystemProxies = false; String newProxyHost = null; String newProxyPort = null; Authenticator newAuthenticator = null; switch (proxyType) { case SYSTEM: log.info("Applying proxy configuration: system settings"); useSystemProxies = true; break; case APP_SETTINGS: newProxyHost = SYSTEM_PROXY_HOST; newProxyPort = SYSTEM_PROXY_PORT; log.info("Applying proxy configuration: host=" + newProxyHost + " port=" + newProxyPort); break; case CUSTOM: newProxyHost = customProxyHost; newProxyPort = customProxyPort; log.info("Applying proxy configuration: host=" + newProxyHost + " port=" + newProxyPort); break; case CUSTOM_W_AUTH: newProxyHost = customProxyHost; newProxyPort = customProxyPort; newAuthenticator = new Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(customProxyUserName, customProxyPassword.toCharArray()); } }; log.info("Applying proxy configuration: host=" + newProxyHost + " port=" + newProxyPort + " user=" + customProxyUserName); break; } Utilities.setHttpProxyHost(newProxyHost); Utilities.setHttpProxyPort(newProxyPort); Authenticator.setDefault(newAuthenticator); System.setProperty("java.net.useSystemProxies", Boolean.toString(useSystemProxies)); } public long getBandwidthLimit() { return bandwidthLimit; } public void setBandwidthLimit(long bandwidthLimit) { this.bandwidthLimit = bandwidthLimit; ThrottledInputStream.setBandwidth(bandwidthLimit); } @XmlElement public void setUnitSystem(UnitSystem unitSystem) { if (unitSystem == null) unitSystem = UnitSystem.Metric; this.unitSystem = unitSystem; } public UnitSystem getUnitSystem() { return unitSystem; } @XmlTransient public File getMapSourcesDirectory() { String mapSourcesDirCfg = directories.mapSourcesDirectory; File mapSourcesDir; if (mapSourcesDirCfg == null || mapSourcesDirCfg.trim().length() == 0) mapSourcesDir = DirectoryManager.mapSourcesDir; else mapSourcesDir = new File(mapSourcesDirCfg); return mapSourcesDir; } @XmlTransient public File getAtlasOutputDirectory() { if (directories.atlasOutputDirectory != null) return new File(directories.atlasOutputDirectory); return new File(DirectoryManager.currentDir, "atlases"); } public String getAtlasOutputDirectoryString() { if (directories.atlasOutputDirectory == null) return ""; return directories.atlasOutputDirectory; } /** * * @param dir * null or empty string resets to default directory otherwise set the new atlas output * directory. */ public void setAtlasOutputDirectory(String dir) { if (dir != null && dir.trim().length() == 0) dir = null; directories.atlasOutputDirectory = dir; } public String getVersion() { return version; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/model/TileImageParameters.java0000644000175000017500000000476512122526604031553 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.model; import java.awt.Dimension; import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAnyAttribute; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public final class TileImageParameters implements Cloneable { public static enum Name { width, height, format, format_png, format_jpg } @XmlAnyAttribute protected AnyAttributeMap attr = new AnyAttributeMap(); /** * Default constructor as required by JAXB */ protected TileImageParameters() { super(); } private TileImageParameters(AnyAttributeMap attrMap) { attr.putAll(attrMap); } protected void afterUnmarshal(Unmarshaller u, Object parent) { // read all values once for detecting problems attr.getInt(Name.height.name()); attr.getInt(Name.width.name()); TileImageFormat.valueOf(attr.getAttr("format")); } public TileImageParameters(int width, int height, TileImageFormat format) { super(); attr.setAttr("format", format.name()); attr.setInt("height", height); attr.setInt("width", width); } public int getWidth() { return attr.getInt("width"); } public int getHeight() { return attr.getInt("height"); } public Dimension getDimension() { return new Dimension(getWidth(), getHeight()); } public TileImageFormat getFormat() { return TileImageFormat.valueOf(attr.getAttr("format")); } @Override public String toString() { return "Tile size: (" + getWidth() + "/" + getHeight() + ") " + getFormat().toString() + ")"; } @Override public Object clone() throws CloneNotSupportedException { return new TileImageParameters(attr); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/model/Profile.java0000644000175000017500000001511012127544344027257 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.model; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FilenameFilter; import java.util.Collections; import java.util.HashSet; import java.util.Set; import java.util.Vector; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.swing.JOptionPane; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import javax.xml.bind.ValidationEvent; import javax.xml.bind.ValidationEventHandler; import javax.xml.bind.ValidationEventLocator; import mobac.gui.panels.JProfilesPanel; import mobac.program.DirectoryManager; import mobac.program.interfaces.AtlasInterface; import mobac.program.interfaces.AtlasObject; import mobac.utilities.I18nUtils; import mobac.utilities.Utilities; import org.apache.log4j.Logger; /** * A profile is a saved atlas. The available profiles ({@link Profile} instances) are visible in the * profilesCombo in the {@link JProfilesPanel}. */ public class Profile implements Comparable { private static Logger log = Logger.getLogger(Profile.class); public static final String PROFILE_NAME_REGEX = "[\\w _-]+"; public static final String PROFILE_FILENAME_PREFIX = "mobac-profile-"; public static final Pattern PROFILE_FILENAME_PATTERN = Pattern.compile(PROFILE_FILENAME_PREFIX + "(" + PROFILE_NAME_REGEX + ").xml"); public static final Profile DEFAULT = new Profile(); private File file; private String name; private static Vector profiles = new Vector(); /** * Profiles management method */ public static void updateProfiles() { File profilesDir = DirectoryManager.atlasProfilesDir; final Set deletedProfiles = new HashSet(); deletedProfiles.addAll(profiles); profilesDir.list(new FilenameFilter() { public boolean accept(File dir, String fileName) { Matcher m = PROFILE_FILENAME_PATTERN.matcher(fileName); if (m.matches()) { String profileName = m.group(1); Profile profile = new Profile(new File(dir, fileName), profileName); if (!deletedProfiles.remove(profile)) profiles.add(profile); } return false; } }); for (Profile p : deletedProfiles) profiles.remove(p); Collections.sort(profiles); } /** * Profiles management method */ public static Vector getProfiles() { updateProfiles(); return profiles; } /** * Load a profile by it's name * * @param name */ public Profile(String name) { this(new File(DirectoryManager.atlasProfilesDir, getProfileFileName(name)), name); } /** * Default profile */ protected Profile() { this(new File(DirectoryManager.atlasProfilesDir, "mobac-profile.xml"), ""); } protected Profile(File file, String name) { super(); this.file = file; this.name = name; } @Override public String toString() { return name; } public File getFile() { return file; } public String getName() { return name; } public boolean exists() { return file.isFile(); } public void delete() { if (!file.delete()) file.deleteOnExit(); } public int compareTo(Profile o) { return file.compareTo(o.file); } @Override public boolean equals(Object obj) { if (!(obj instanceof Profile)) return false; Profile p = (Profile) obj; return file.equals(p.file); } @Override public int hashCode() { assert false : "hashCode not designed"; return -1; } public void save(AtlasInterface atlasInterface) throws JAXBException { JAXBContext context = JAXBContext.newInstance(Atlas.class); Marshaller m = context.createMarshaller(); m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); FileOutputStream fo = null; try { fo = new FileOutputStream(file); m.marshal(atlasInterface, fo); } catch (FileNotFoundException e) { throw new JAXBException(e); } finally { Utilities.closeStream(fo); } } public AtlasInterface load() throws JAXBException { JAXBContext context = JAXBContext.newInstance(Atlas.class); Unmarshaller um = context.createUnmarshaller(); um.setEventHandler(new ValidationEventHandler() { public boolean handleEvent(ValidationEvent event) { ValidationEventLocator loc = event.getLocator(); String file = loc.getURL().getFile(); int lastSlash = file.lastIndexOf('/'); if (lastSlash > 0) file = file.substring(lastSlash + 1); int ret = JOptionPane.showConfirmDialog( null, String.format(I18nUtils.localizedStringForKey("msg_error_load_atlas_profile"), event.getMessage(), file, loc.getLineNumber(), loc.getColumnNumber()), I18nUtils.localizedStringForKey("msg_error_load_atlas_profile_title"), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.ERROR_MESSAGE); log.error(event.toString()); return (ret == JOptionPane.YES_OPTION); } }); try { AtlasInterface newAtlas = (AtlasInterface) um.unmarshal(file); return newAtlas; } catch (Exception e) { throw new JAXBException(e.getMessage(), e); } } public static boolean checkAtlas(AtlasInterface atlasInterface) { return checkAtlasObject(atlasInterface); } public static String getProfileFileName(String profileName) { return PROFILE_FILENAME_PREFIX + profileName + ".xml"; } private static boolean checkAtlasObject(Object o) { boolean result = false; if (o instanceof AtlasObject) { result |= ((AtlasObject) o).checkData(); } if (o instanceof Iterable) { Iterable it = (Iterable) o; for (Object ao : it) { result |= checkAtlasObject(ao); } } return result; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/model/MapPolygon.java0000644000175000017500000002150612127544344027752 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.model; import java.awt.Point; import java.awt.Polygon; import java.awt.Rectangle; import java.awt.geom.Area; import java.awt.geom.Line2D; import java.awt.geom.Path2D; import java.awt.geom.PathIterator; import java.io.StringWriter; import java.util.ArrayList; import java.util.Arrays; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import mobac.program.Logging; import mobac.program.interfaces.LayerInterface; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSpace; import mobac.program.interfaces.TileFilter; import mobac.program.tilefilter.PolygonTileFilter; import mobac.utilities.I18nUtils; import mobac.utilities.MyMath; @XmlRootElement public class MapPolygon extends Map { @XmlElement protected Polygon polygon; protected long calculatedTileCount = -1; protected MapPolygon() { } public static MapPolygon createFromTrack(Layer layer, String name, MapSource mapSource, int zoom, EastNorthCoordinate[] trackPoints, int pixelDistance, TileImageParameters parameters) { MapSpace mapSpace = mapSource.getMapSpace(); Area area = new Area(); for (int i = 1; i < trackPoints.length; i++) { EastNorthCoordinate point1 = trackPoints[i - 1]; EastNorthCoordinate point2 = trackPoints[i]; int y1 = mapSpace.cLatToY(point1.lat, zoom); int y2 = mapSpace.cLatToY(point2.lat, zoom); int x1 = mapSpace.cLonToX(point1.lon, zoom); int x2 = mapSpace.cLonToX(point2.lon, zoom); Line2D.Double ln = new Line2D.Double(x1, y1, x2, y2); double indent = pixelDistance; // distance from central line double length = ln.getP1().distance(ln.getP2()); double dx_li = (ln.getX2() - ln.getX1()) / length * indent; double dy_li = (ln.getY2() - ln.getY1()) / length * indent; // moved p1 point double p1X = ln.getX1() - dx_li; double p1Y = ln.getY1() - dy_li; // line moved to the left double lX1 = ln.getX1() - dy_li; double lY1 = ln.getY1() + dx_li; double lX2 = ln.getX2() - dy_li; double lY2 = ln.getY2() + dx_li; // moved p2 point double p2X = ln.getX2() + dx_li; double p2Y = ln.getY2() + dy_li; // line moved to the right double rX1_ = ln.getX1() + dy_li; double rY1 = ln.getY1() - dx_li; double rX2 = ln.getX2() + dy_li; double rY2 = ln.getY2() - dx_li; Path2D p = new Path2D.Double(); p.moveTo(lX1, lY1); p.lineTo(lX2, lY2); p.lineTo(p2X, p2Y); p.lineTo(rX2, rY2); p.lineTo(rX1_, rY1); p.lineTo(p1X, p1Y); p.lineTo(lX1, lY1); area.add(new Area(p)); } PathIterator pi = area.getPathIterator(null); ArrayList xPoints = new ArrayList(100); ArrayList yPoints = new ArrayList(100); double coords[] = new double[6]; while (!pi.isDone()) { int type = pi.currentSegment(coords); switch (type) { case PathIterator.SEG_MOVETO: case PathIterator.SEG_LINETO: case PathIterator.SEG_CLOSE: xPoints.add((int) coords[0]); yPoints.add((int) coords[1]); break; default: Logging.LOG.warn("Area to polygon conversion: unexpected segment type found: " + type + " " + Arrays.toString(coords)); } pi.next(); } int[] xp = new int[xPoints.size()]; int[] yp = new int[yPoints.size()]; for (int i = 0; i < xp.length; i++) { xp[i] = xPoints.get(i); yp[i] = yPoints.get(i); } Polygon polygon = new Polygon(xp, yp, xp.length); return new MapPolygon(layer, name, mapSource, zoom, polygon, parameters); } public static MapPolygon createFromMapPolygon(Layer layer, String name, int newZoom, MapPolygon map) { Polygon oldPolygon = map.getPolygon(); int oldZoom = map.getZoom(); MapSpace mapSpace = map.getMapSource().getMapSpace(); int xPoints[] = new int[oldPolygon.npoints]; int yPoints[] = new int[oldPolygon.npoints]; Point p = new Point(); for (int i = 0; i < xPoints.length; i++) { p.x = oldPolygon.xpoints[i]; p.y = oldPolygon.ypoints[i]; Point nP = mapSpace.changeZoom(p, oldZoom, newZoom); xPoints[i] = nP.x; yPoints[i] = nP.y; } Polygon newPolygon = new Polygon(xPoints, yPoints, xPoints.length); return new MapPolygon(layer, name, map.getMapSource(), newZoom, newPolygon, map.getParameters()); } public MapPolygon(Layer layer, String name, MapSource mapSource, int zoom, Polygon polygon, TileImageParameters parameters) { super(layer, name, mapSource, zoom, null, null, parameters); this.polygon = polygon; Rectangle bounds = polygon.getBounds(); int mapSourceTileSize = mapSource.getMapSpace().getTileSize(); // Make sure the minimum tile coordinate starts/ends on the edge of a tile from the map source int minx = MyMath.roundDownToNearest(bounds.x, mapSourceTileSize); int miny = MyMath.roundDownToNearest(bounds.y, mapSourceTileSize); int maxx = MyMath.roundUpToNearest(bounds.x + bounds.width, mapSourceTileSize) - 1; int maxy = MyMath.roundUpToNearest(bounds.y + bounds.height, mapSourceTileSize) - 1; minTileCoordinate = new Point(minx, miny); maxTileCoordinate = new Point(maxx, maxy); internalCalculateTilesToDownload(); } @Override public long calculateTilesToDownload() { if (calculatedTileCount < 0) internalCalculateTilesToDownload(); return calculatedTileCount; } protected void internalCalculateTilesToDownload() { int tileSize = mapSource.getMapSpace().getTileSize(); double tileSizeD = tileSize; int xMin = minTileCoordinate.x; int xMax = maxTileCoordinate.x; int yMin = minTileCoordinate.y; int yMax = maxTileCoordinate.y; int count = 0; for (int x = xMin; x <= xMax; x += tileSize) { for (int y = yMin; y <= yMax; y += tileSize) { if (polygon.intersects(x, y, tileSizeD, tileSizeD)) count++; } } calculatedTileCount = count; } @Override public String getToolTip() { MapSpace mapSpace = mapSource.getMapSpace(); EastNorthCoordinate tl = new EastNorthCoordinate(mapSpace, zoom, minTileCoordinate.x, minTileCoordinate.y); EastNorthCoordinate br = new EastNorthCoordinate(mapSpace, zoom, maxTileCoordinate.x, maxTileCoordinate.y); StringWriter sw = new StringWriter(1024); sw.write(""); sw.write(I18nUtils.localizedStringForKey("lp_atlas_info_polygon_map_title")); sw.write(String.format(I18nUtils.localizedStringForKey("lp_atlas_info_map_source_short"), mapSource.getName())); sw.write(String.format(I18nUtils.localizedStringForKey("lp_atlas_info_map_zoom_lv"), zoom)); sw.write(String.format(I18nUtils.localizedStringForKey("lp_atlas_info_polygon_map_point"), polygon.npoints)); sw.write(String.format(I18nUtils.localizedStringForKey("lp_atlas_info_map_area_start"), tl, minTileCoordinate.x, minTileCoordinate.y)); sw.write(String.format(I18nUtils.localizedStringForKey("lp_atlas_info_map_area_end"), br, maxTileCoordinate.x, maxTileCoordinate.y)); sw.write(String.format(I18nUtils.localizedStringForKey("lp_atlas_info_map_size"), (maxTileCoordinate.x - minTileCoordinate.x + 1), (maxTileCoordinate.y - minTileCoordinate.y + 1))); if (parameters != null) { sw.write(String.format(I18nUtils.localizedStringForKey("lp_atlas_info_tile_size"), parameters.getWidth(), parameters.getHeight())); sw.write(String.format(I18nUtils.localizedStringForKey("lp_atlas_info_tile_format"), parameters.getFormat())); } else sw.write(I18nUtils.localizedStringForKey("lp_atlas_info_tile_format_origin")); sw.write(String.format(I18nUtils.localizedStringForKey("lp_atlas_info_max_tile"),calculateTilesToDownload())); sw.write(""); return sw.toString(); } public Polygon getPolygon() { return polygon; } public TileFilter getTileFilter() { return new PolygonTileFilter(this); } @Override public MapInterface deepClone(LayerInterface newLayer) { MapPolygon map = (MapPolygon) super.deepClone(newLayer); map.polygon = new Polygon(polygon.xpoints, polygon.ypoints, polygon.npoints); return map; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/model/NumericDocument.java0000644000175000017500000000300412122526604030751 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.model; import java.awt.Toolkit; import javax.swing.text.AttributeSet; import javax.swing.text.BadLocationException; import javax.swing.text.PlainDocument; public class NumericDocument extends PlainDocument { private static final long serialVersionUID = 1L; public static final String NUMERIC = "0123456789"; public void insertString(int offset, String str, AttributeSet attr) throws BadLocationException { if (str == null) return; for (char c : str.toCharArray()) { if (NUMERIC.indexOf(c) == -1) { Toolkit.getDefaultToolkit().beep(); return; } } super.insertString(offset, str, attr); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/model/MapSourceLoaderInfo.java0000644000175000017500000000324412122526604031517 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.model; import java.io.File; public class MapSourceLoaderInfo { public enum LoaderType { MAPPACK, // map pack file XML, // custom map xml BSH // BeanShell script ; }; protected final LoaderType loaderType; protected final File sourceFile; protected final String revision; public MapSourceLoaderInfo(LoaderType loaderType, File sourceFile) { this(loaderType, sourceFile, null); } public MapSourceLoaderInfo(LoaderType loaderType, File sourceFile, String revision) { super(); this.loaderType = loaderType; this.sourceFile = sourceFile; this.revision = revision; } public LoaderType getLoaderType() { return loaderType; } public File getSourceFile() { return sourceFile; } public String getRevision() { return revision; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/model/TileImageFormat.java0000644000175000017500000001261512127544344030677 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.model; import java.io.OutputStream; import java.util.ArrayList; import javax.swing.JComboBox; import mobac.gui.MainGUI; import mobac.program.interfaces.TileImageDataWriter; import mobac.program.tiledatawriter.TileImageJpegDataWriter; import mobac.program.tiledatawriter.TileImagePng4DataWriter; import mobac.program.tiledatawriter.TileImagePng8DataWriter; import mobac.program.tiledatawriter.TileImagePngDataWriter; import mobac.utilities.I18nUtils; /** * Defines all available image formats selectable in the {@link JComboBox} in the {@link MainGUI}. Each element of this * enumeration contains one instance of an {@link TileImageDataWriter} instance that can perform one or more image * operations (e.g. color reduction) and then saves the image to an {@link OutputStream}. * * @see TileImageDataWriter * @see TileImagePngDataWriter * @see TileImagePng4DataWriter * @see TileImagePng8DataWriter * @see TileImageJpegDataWriter */ public enum TileImageFormat { // PNG("PNG", new TileImagePngDataWriter()), // // PNG8Bit(MainGUI.localizedStringForKey("lp_tile_param_image_fmt_png_8bit"), new TileImagePng8DataWriter()), // // PNG4Bit(MainGUI.localizedStringForKey("lp_tile_param_image_fmt_png_4bit"), new TileImagePng4DataWriter()), // // JPEG100(MainGUI.localizedStringForKey("lp_tile_param_image_fmt_jpg_q100"), new TileImageJpegDataWriter(1.00)), // // JPEG99(MainGUI.localizedStringForKey("lp_tile_param_image_fmt_jpg_q99"), new TileImageJpegDataWriter(0.99)), // // JPEG95(MainGUI.localizedStringForKey("lp_tile_param_image_fmt_jpg_q100"), new TileImageJpegDataWriter(0.95)), // // JPEG90(MainGUI.localizedStringForKey("lp_tile_param_image_fmt_jpg_q90"), new TileImageJpegDataWriter(0.90)), // // JPEG85(MainGUI.localizedStringForKey("lp_tile_param_image_fmt_jpg_q85"), new TileImageJpegDataWriter(0.85)), // // JPEG80(MainGUI.localizedStringForKey("lp_tile_param_image_fmt_jpg_q80"), new TileImageJpegDataWriter(0.80)), // // JPEG70(MainGUI.localizedStringForKey("lp_tile_param_image_fmt_jpg_q70"), new TileImageJpegDataWriter(0.70)), // // JPEG60(MainGUI.localizedStringForKey("lp_tile_param_image_fmt_jpg_q60"), new TileImageJpegDataWriter(0.60)), // // JPEG50(MainGUI.localizedStringForKey("lp_tile_param_image_fmt_jpg_q50"), new TileImageJpegDataWriter(0.50)); // PNG(new TileImagePngDataWriter(), "lp_tile_param_image_fmt_png"), // PNG8Bit(new TileImagePng8DataWriter(), "lp_tile_param_image_fmt_png_8bit"), // PNG4Bit(new TileImagePng4DataWriter(), "lp_tile_param_image_fmt_png_4bit"), // JPEG100(new TileImageJpegDataWriter(1.00), "lp_tile_param_image_fmt_jpg_q100"), // JPEG99(new TileImageJpegDataWriter(0.99), "lp_tile_param_image_fmt_jpg_q99"), // JPEG95(new TileImageJpegDataWriter(0.95), "lp_tile_param_image_fmt_jpg_q95"), // JPEG90(new TileImageJpegDataWriter(0.90), "lp_tile_param_image_fmt_jpg_q90"), // JPEG85(new TileImageJpegDataWriter(0.85), "lp_tile_param_image_fmt_jpg_q85"), // JPEG80(new TileImageJpegDataWriter(0.80), "lp_tile_param_image_fmt_jpg_q80"), // JPEG70(new TileImageJpegDataWriter(0.70), "lp_tile_param_image_fmt_jpg_q70"), // JPEG60(new TileImageJpegDataWriter(0.60), "lp_tile_param_image_fmt_jpg_q60"), // JPEG50(new TileImageJpegDataWriter(0.50), "lp_tile_param_image_fmt_jpg_q50"); // // private final String description; private final TileImageDataWriter dataWriter; private final String translationKey; private TileImageFormat(TileImageDataWriter dataWriter, String translationKey) { // this.description = description; this.dataWriter = dataWriter; this.translationKey = translationKey; } @Override public String toString() { return I18nUtils.localizedStringForKey(translationKey); } public TileImageDataWriter getDataWriter() { return dataWriter; } public TileImageType getType() { return dataWriter.getType(); } /** * File extension * * @return */ public String getFileExt() { return dataWriter.getType().getFileExt(); } public static TileImageFormat[] getPngFormats() { return getFormats(TileImageType.PNG); } public static TileImageFormat[] getJpgFormats() { return getFormats(TileImageType.JPG); } protected static TileImageFormat[] getFormats(TileImageType tileImageType) { ArrayList list = new ArrayList(); for (TileImageFormat format : values()) { if (tileImageType.equals(format.getType())) list.add(format); } TileImageFormat[] result = new TileImageFormat[0]; result = list.toArray(result); return result; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/model/MapSelection.java0000644000175000017500000001776712122526604030260 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.model; import java.awt.Point; import mobac.gui.mapview.JMapViewer; import mobac.mapsources.AbstractMultiLayerMapSource; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSpace; public class MapSelection { public static final int LAT_MAX = 85; public static final int LAT_MIN = -85; public static final int LON_MAX = 179; public static final int LON_MIN = -179; private final MapSource mapSource; private final MapSpace mapSpace; private final int mapSourceTileSize; private final int zoom; private int minTileCoordinate_x; private int minTileCoordinate_y; private int maxTileCoordinate_x; private int maxTileCoordinate_y; public MapSelection(MapSource mapSource, EastNorthCoordinate max, EastNorthCoordinate min) { super(); this.mapSource = mapSource; this.mapSpace = mapSource.getMapSpace(); mapSourceTileSize = this.mapSpace.getTileSize(); zoom = JMapViewer.MAX_ZOOM; int x1 = mapSpace.cLonToX(min.lon, zoom); int x2 = mapSpace.cLonToX(max.lon, zoom); int y1 = mapSpace.cLatToY(min.lat, zoom); int y2 = mapSpace.cLatToY(max.lat, zoom); setCoordinates(x1, x2, y1, y2); } public MapSelection(MapInterface map) { this(map.getMapSource(), map.getMaxTileCoordinate(), map.getMinTileCoordinate(), map.getZoom()); } /** * @param mapSource * @param p1 * tile coordinate * @param p2 * tile coordinate * @param zoom */ public MapSelection(MapSource mapSource, Point p1, Point p2, int zoom) { super(); this.mapSource = mapSource; this.mapSpace = mapSource.getMapSpace(); mapSourceTileSize = mapSpace.getTileSize(); this.zoom = zoom; setCoordinates(p1.x, p2.x, p1.y, p2.y); } public MapSelection(MapSource mapSource, MercatorPixelCoordinate c1, MercatorPixelCoordinate c2) { if (c1.getZoom() != c2.getZoom()) throw new RuntimeException("Different zoom levels - unsuported!"); this.mapSource = mapSource; this.mapSpace = mapSource.getMapSpace(); mapSourceTileSize = mapSpace.getTileSize(); this.zoom = c1.getZoom(); setCoordinates(c1.getX(), c2.getX(), c1.getY(), c2.getY()); } protected void setCoordinates(int x1, int x2, int y1, int y2) { maxTileCoordinate_x = Math.max(x1, x2); minTileCoordinate_x = Math.min(x1, x2); maxTileCoordinate_y = Math.max(y1, y2); minTileCoordinate_y = Math.min(y1, y2); } /** * Is an area selected or only one point? * * @return */ public boolean isAreaSelected() { boolean result = maxTileCoordinate_x != minTileCoordinate_x && maxTileCoordinate_y != minTileCoordinate_y; return result; } /** * Warning: maximum lat/lon is the top right corner of the map selection! * * @return maximum lat/lon */ public EastNorthCoordinate getMax() { return new EastNorthCoordinate(mapSpace, zoom, maxTileCoordinate_x, minTileCoordinate_y); } /** * Warning: minimum lat/lon is the bottom left corner of the map selection! * * @return minimum lat/lon */ public EastNorthCoordinate getMin() { return new EastNorthCoordinate(mapSpace, zoom, minTileCoordinate_x, maxTileCoordinate_y); } /** * Returns the top left tile x- and y-tile-number (minimum) of the selected area marked by the {@link MapSelection}. * * @param aZoomLevel * @return tile number [0..2zoom] */ public Point getTopLeftTileNumber(int aZoomlevel) { Point tlc = getTopLeftPixelCoordinate(aZoomlevel); tlc.x /= mapSourceTileSize; tlc.y /= mapSourceTileSize; return tlc; } public MercatorPixelCoordinate getTopLeftPixelCoordinate() { return new MercatorPixelCoordinate(mapSpace, minTileCoordinate_x, minTileCoordinate_y, zoom); } /** * Returns the top left tile x- and y-tile-coordinate (minimum) of the selected area marked by the * {@link MapSelection}. * * @param aZoomlevel * @return tile coordinate [0..(256 * 2zoom)] */ public Point getTopLeftPixelCoordinate(int aZoomlevel) { int zoomDiff = this.zoom - aZoomlevel; int x = minTileCoordinate_x; int y = minTileCoordinate_y; if (zoomDiff < 0) { zoomDiff = -zoomDiff; x <<= zoomDiff; y <<= zoomDiff; } else { x >>= zoomDiff; y >>= zoomDiff; } return new Point(x, y); } /** * Returns the bottom right tile x- and y-tile-number (minimum) of the selected area marked by the * {@link MapSelection}. * * @param aZoomlevel * @return tile number [0..2zoom] */ public Point getBottomRightTileNumber(int aZoomlevel) { Point brc = getBottomRightPixelCoordinate(aZoomlevel); brc.x = brc.x / mapSourceTileSize; brc.y = brc.y / mapSourceTileSize; return brc; } /** * Returns the bottom right tile x- and y-tile-coordinate (minimum) of the selected area regarding the zoom level * specified at creation time of this {@link MapSelection} instance. * * @return tile coordinate [0..(256 * 2zoom)] */ public MercatorPixelCoordinate getBottomRightPixelCoordinate() { return new MercatorPixelCoordinate(mapSpace, maxTileCoordinate_x, maxTileCoordinate_y, zoom); } /** * Returns the bottom right tile x- and y-tile-coordinate (minimum) of the selected area marked by the * {@link MapSelection}. * * @param aZoomlevel * @return tile coordinate [0..(256 * 2zoom)] */ public Point getBottomRightPixelCoordinate(int aZoomlevel) { int zoomDiff = this.zoom - aZoomlevel; int x = maxTileCoordinate_x; int y = maxTileCoordinate_y; if (zoomDiff < 0) { zoomDiff = -zoomDiff; x <<= zoomDiff; y <<= zoomDiff; } else { x >>= zoomDiff; y >>= zoomDiff; } return new Point(x, y); } /** * Return the amount of tiles for the current selection in the specified zoom level. * * @param zoom * is the zoom level to calculate the amount of tiles for * @return the amount of tiles in the current selection in the supplied zoom level */ public long calculateNrOfTiles(int zoom) { Point max = getBottomRightTileNumber(zoom); Point min = getTopLeftTileNumber(zoom); long width = max.x - min.x + 1; long height = max.y - min.y + 1; long tileCount = width * height; if (mapSource instanceof AbstractMultiLayerMapSource) { int mapLayerCount = ((AbstractMultiLayerMapSource) mapSource).getLayerMapSources().length; tileCount *= mapLayerCount; } return tileCount; } public long[] calculateNrOfTilesEx(int zoom) { Point max = getBottomRightTileNumber(zoom); Point min = getTopLeftTileNumber(zoom); long width = max.x - min.x + 1; long height = max.y - min.y + 1; long tileCount = width * height; if (mapSource instanceof AbstractMultiLayerMapSource) { int mapLayerCount = ((AbstractMultiLayerMapSource) mapSource).getLayerMapSources().length; tileCount *= mapLayerCount; } return new long[] { tileCount, width, height }; } @Override public String toString() { EastNorthCoordinate max = getMax(); EastNorthCoordinate min = getMin(); return String.format("lat/lon: max(%6f/%6f) min(%6f/%6f)", new Object[] { max.lat, max.lon, min.lat, min.lon }); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/model/AtlasOutputFormat.java0000644000175000017500000001773512122526604031326 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.model; import java.util.ArrayList; import java.util.List; import java.util.NoSuchElementException; import java.util.Vector; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import mobac.program.annotations.AtlasCreatorName; import mobac.program.atlascreators.AFTrack; import mobac.program.atlascreators.AlpineQuestMap; import mobac.program.atlascreators.AndNav; import mobac.program.atlascreators.AtlasCreator; import mobac.program.atlascreators.BackCountryNavigator; import mobac.program.atlascreators.BigPlanetTracks; import mobac.program.atlascreators.CacheBox; import mobac.program.atlascreators.CacheWolf; import mobac.program.atlascreators.GCLive; import mobac.program.atlascreators.Galileo; import mobac.program.atlascreators.GarminCustom; import mobac.program.atlascreators.Glopus; import mobac.program.atlascreators.GlopusMapFile; import mobac.program.atlascreators.GoogleEarthOverlay; import mobac.program.atlascreators.GpsSportsTracker; import mobac.program.atlascreators.IPhone3MapTiles5; import mobac.program.atlascreators.MBTiles; import mobac.program.atlascreators.MGMaps; import mobac.program.atlascreators.MagellanRmp; import mobac.program.atlascreators.Maplorer; import mobac.program.atlascreators.Maverick; import mobac.program.atlascreators.MobileTrailExplorer; import mobac.program.atlascreators.MobileTrailExplorerCache; import mobac.program.atlascreators.NFComPass; import mobac.program.atlascreators.NaviComputer; import mobac.program.atlascreators.OSMAND; import mobac.program.atlascreators.OSMAND_SQlite; import mobac.program.atlascreators.OSMTracker; import mobac.program.atlascreators.OruxMaps; import mobac.program.atlascreators.OruxMapsSqlite; import mobac.program.atlascreators.Osmdroid; import mobac.program.atlascreators.OsmdroidGEMF; import mobac.program.atlascreators.OsmdroidSQLite; import mobac.program.atlascreators.Ozi; import mobac.program.atlascreators.PNGWorldfile; import mobac.program.atlascreators.PaperAtlasPdf; import mobac.program.atlascreators.PaperAtlasPng; import mobac.program.atlascreators.PathAway; import mobac.program.atlascreators.RMapsSQLite; import mobac.program.atlascreators.RunGPSAtlas; import mobac.program.atlascreators.SportsTracker; import mobac.program.atlascreators.TTQV; import mobac.program.atlascreators.TileStoreDownload; import mobac.program.atlascreators.TomTomRaster; import mobac.program.atlascreators.TrekBuddy; import mobac.program.atlascreators.TrekBuddyTared; import mobac.program.atlascreators.TwoNavRMAP; import mobac.program.atlascreators.Ublox; import mobac.program.atlascreators.Viewranger; import mobac.program.jaxb.AtlasOutputFormatAdapter; @XmlRootElement @XmlJavaTypeAdapter(AtlasOutputFormatAdapter.class) public class AtlasOutputFormat implements Comparable { public static List FORMATS; public static final AtlasOutputFormat TILESTORE = createByClass(TileStoreDownload.class); static { FORMATS = new ArrayList(40); FORMATS.add(createByClass(AFTrack.class)); FORMATS.add(createByClass(AlpineQuestMap.class)); FORMATS.add(createByClass(AndNav.class)); FORMATS.add(createByClass(BackCountryNavigator.class)); FORMATS.add(createByClass(BigPlanetTracks.class)); FORMATS.add(createByClass(CacheBox.class)); FORMATS.add(createByClass(CacheWolf.class)); FORMATS.add(createByClass(Galileo.class)); FORMATS.add(createByClass(GarminCustom.class)); FORMATS.add(createByClass(GCLive.class)); FORMATS.add(createByClass(Glopus.class)); FORMATS.add(createByClass(GlopusMapFile.class)); FORMATS.add(createByClass(GoogleEarthOverlay.class)); FORMATS.add(createByClass(GpsSportsTracker.class)); FORMATS.add(createByClass(IPhone3MapTiles5.class)); FORMATS.add(createByClass(MagellanRmp.class)); FORMATS.add(createByClass(Maplorer.class)); FORMATS.add(createByClass(Maverick.class)); FORMATS.add(createByClass(MBTiles.class)); FORMATS.add(createByClass(MGMaps.class)); FORMATS.add(createByClass(MobileTrailExplorer.class)); FORMATS.add(createByClass(MobileTrailExplorerCache.class)); FORMATS.add(createByClass(NaviComputer.class)); FORMATS.add(createByClass(NFComPass.class)); FORMATS.add(createByClass(OruxMaps.class)); FORMATS.add(createByClass(OruxMapsSqlite.class)); FORMATS.add(createByClass(OSMAND.class)); FORMATS.add(createByClass(OSMAND_SQlite.class)); FORMATS.add(createByClass(Osmdroid.class)); FORMATS.add(createByClass(OsmdroidGEMF.class)); FORMATS.add(createByClass(OsmdroidSQLite.class)); FORMATS.add(createByClass(OSMTracker.class)); FORMATS.add(createByClass(Ozi.class)); FORMATS.add(createByClass(PaperAtlasPdf.class)); FORMATS.add(createByClass(PaperAtlasPng.class)); FORMATS.add(createByClass(PathAway.class)); FORMATS.add(createByClass(PNGWorldfile.class)); FORMATS.add(createByClass(RMapsSQLite.class)); FORMATS.add(createByClass(RunGPSAtlas.class)); FORMATS.add(createByClass(SportsTracker.class)); FORMATS.add(createByClass(TomTomRaster.class)); FORMATS.add(createByClass(TTQV.class)); FORMATS.add(createByClass(TrekBuddyTared.class)); FORMATS.add(createByClass(TrekBuddy.class)); FORMATS.add(createByClass(TwoNavRMAP.class)); FORMATS.add(createByClass(Ublox.class)); FORMATS.add(createByClass(Viewranger.class)); FORMATS.add(TILESTORE); } public static Vector getFormatsAsVector() { return new Vector(FORMATS); } public static AtlasOutputFormat getFormatByName(String Name) { for (AtlasOutputFormat af : FORMATS) { if (af.getTypeName().equals(Name)) return af; } throw new NoSuchElementException("Unknown atlas format: \"" + Name + "\""); } private Class atlasCreatorClass; private String typeName; private String name; private static AtlasOutputFormat createByClass(Class atlasCreatorClass) { AtlasCreatorName acName = atlasCreatorClass.getAnnotation(AtlasCreatorName.class); if (acName == null) throw new RuntimeException("AtlasCreator " + atlasCreatorClass.getName() + " has no name"); String typeName = acName.type(); if (typeName == null || typeName.length() == 0) typeName = atlasCreatorClass.getSimpleName(); String name = acName.value(); return new AtlasOutputFormat(atlasCreatorClass, typeName, name); } private AtlasOutputFormat(Class atlasCreatorClass, String typeName, String name) { this.atlasCreatorClass = atlasCreatorClass; this.typeName = typeName; this.name = name; } public String toString() { return name; } public Class getMapCreatorClass() { return atlasCreatorClass; } public String getTypeName() { return typeName; } public AtlasCreator createAtlasCreatorInstance() { if (atlasCreatorClass == null) return null; try { return atlasCreatorClass.newInstance(); } catch (Throwable t) { throw new RuntimeException(t); } } public int compareTo(AtlasOutputFormat o) { return getTypeName().compareTo(o.toString()); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/program/model/AtlasTreeModel.java0000644000175000017500000001462112122526604030524 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.program.model; import java.awt.Toolkit; import java.util.HashSet; import java.util.LinkedList; import java.util.Set; import javax.swing.JOptionPane; import javax.swing.event.TreeModelEvent; import javax.swing.event.TreeModelListener; import javax.swing.tree.TreeModel; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; import mobac.exceptions.InvalidNameException; import mobac.program.interfaces.AtlasInterface; import mobac.program.interfaces.AtlasObject; import mobac.program.interfaces.LayerInterface; import mobac.program.interfaces.MapInterface; import org.apache.log4j.Logger; public class AtlasTreeModel implements TreeModel { private static Logger log = Logger.getLogger(AtlasTreeModel.class); protected AtlasInterface atlasInterface; protected Set listeners = new HashSet(); public AtlasTreeModel() { super(); atlasInterface = Atlas.newInstance(); } public void addTreeModelListener(TreeModelListener l) { listeners.add(l); } public void removeTreeModelListener(TreeModelListener l) { listeners.remove(l); } public void notifyStructureChanged() { notifyStructureChanged((TreeNode) atlasInterface); } public void notifyStructureChanged(TreeNode root) { notifyStructureChanged(new TreeModelEvent(this, new Object[] { root })); } /** * IMPORTANT: This method have to be called BEFORE deleting the element in * the data model!!! Otherwise the child index can not be retrieved anymore * which is important. * * @param node */ public void notifyNodeDelete(TreeNode node) { TreeNode parent = node.getParent(); Object[] children = new Object[] { node }; int childrenIdx = parent.getIndex(node); if (childrenIdx == -1) { // A problem detected - use fall back solution notifyStructureChanged(); return; } TreePath path = getNodePath(parent); TreeModelEvent event = new TreeModelEvent(this, path, new int[] { childrenIdx }, children); for (TreeModelListener l : listeners) l.treeNodesRemoved(event); } protected void notifyStructureChanged(TreeModelEvent event) { for (TreeModelListener l : listeners) l.treeStructureChanged(event); } public void notifyNodeInsert(TreeNode insertedNode) { TreeNode parent = insertedNode.getParent(); TreePath path = getNodePath(parent); TreeNode[] childs = new TreeNode[] { insertedNode }; int childId = parent.getIndex(insertedNode); assert (childId <= 0); TreeModelEvent event = new TreeModelEvent(this, path, new int[] { childId }, childs); for (TreeModelListener l : listeners) l.treeNodesInserted(event); } public TreePath getNodePath(TreeNode node) { LinkedList path = new LinkedList(); TreeNode n = node; while (n != null) { path.addFirst(n); n = n.getParent(); } return new TreePath(path.toArray()); } public Object getChild(Object parent, int index) { return ((TreeNode) parent).getChildAt(index); } public int getChildCount(Object parent) { return ((TreeNode) parent).getChildCount(); } public int getIndexOfChild(Object parent, Object child) { return ((TreeNode) parent).getIndex((TreeNode) child); } public Object getRoot() { return atlasInterface; } public boolean isLeaf(Object node) { return ((TreeNode) node).isLeaf(); } public void valueForPathChanged(TreePath path, Object newValue) { Object o = path.getLastPathComponent(); boolean success = false; try { AtlasObject sel = (AtlasObject) o; String newName = (String) newValue; if (newName.length() == 0) return; sel.setName(newName); success = true; } catch (ClassCastException e) { log.error("", e); } catch (InvalidNameException e) { log.error(e.getLocalizedMessage()); JOptionPane.showMessageDialog(null, e.getLocalizedMessage(), "Renaming failed", JOptionPane.ERROR_MESSAGE); } finally { if (!success) { Toolkit.getDefaultToolkit().beep(); } } } public void mergeLayers(LayerInterface source, LayerInterface target) throws InvalidNameException { boolean sourceFound = false; boolean targetFound = false; for (LayerInterface l : atlasInterface) { if (l.equals(source)) sourceFound = true; if (l.equals(target)) targetFound = true; } if (!targetFound) return; // Check for duplicate names HashSet names = new HashSet(); for (MapInterface map : source) names.add(map.getName()); for (MapInterface map : target) names.add(map.getName()); if (names.size() < (source.getMapCount() + target.getMapCount())) throw new InvalidNameException("Map naming conflict:\n" + "The layers to be merged contain map(s) of the same name."); if (sourceFound) atlasInterface.deleteLayer(source); for (MapInterface map : source) { target.addMap(map); } notifyNodeDelete((TreeNode) source); notifyStructureChanged((TreeNode) target); } public void moveMap(MapInterface map, LayerInterface targetLayer) { notifyNodeDelete((TreeNode) map); map.delete(); targetLayer.addMap(map); notifyNodeInsert((TreeNode) map); } public AtlasInterface getAtlas() { return atlasInterface; } public void setAtlas(Atlas atlas) { this.atlasInterface = atlas; notifyStructureChanged(); } public void save(Profile profile) throws Exception { profile.save(atlasInterface); } public void load(Profile profile) throws Exception { atlasInterface = profile.load(); notifyStructureChanged(); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/StartMOBAC.java0000644000175000017500000000562212127544344024756 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac; import javax.swing.JOptionPane; import javax.swing.UIManager; import mobac.utilities.I18nUtils; /** * Main class for starting Mobile Atlas Creator. * * This class performs the Java Runtime version check and if the correct version is installed it creates a new instance * of the class specified by {@link #MAIN_CLASS}. The class to be instantiated is specified by it's name intentionally * as this allows to compile this class without any further class dependencies. * */ public class StartMOBAC { public static final String MAIN_CLASS = "mobac.Main"; public static String[] ARGS; /** * @param args */ public static void main(String[] args) { ARGS = args; setLookAndFeel(); checkVersion(); try { Class.forName(MAIN_CLASS).newInstance(); } catch (Exception e) { e.printStackTrace(); JOptionPane.showMessageDialog(null, I18nUtils.localizedStringForKey("msg_environment_unable_to_start") + e.getMessage(), I18nUtils.localizedStringForKey("Error"), JOptionPane.ERROR_MESSAGE); } } public static void setLookAndFeel() { try { if (System.getProperty("swing.defaultlaf") != null) return; UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); //MainGUI.setDefaultFontOfAllUIComponents(MainGUI.customFont()); } catch (Exception e) { } } protected static void checkVersion() { String ver = System.getProperty("java.specification.version"); if (ver == null) ver = "Unknown"; String[] v = ver.split("\\."); int major = 0; int minor = 0; try { major = Integer.parseInt(v[0]); minor = Integer.parseInt(v[1]); } catch (Exception e) { } int version = (major * 1000) + minor; // 1.5 -> 1005; 1.6 -> 1006; 1.7 -> 1007 if (version < 1006) { JOptionPane.showMessageDialog(null, String.format(I18nUtils.localizedStringForKey("msg_environment_jre_bellow"), ver), I18nUtils.localizedStringForKey("msg_environment_jre_bellow_title"), JOptionPane.ERROR_MESSAGE); System.exit(1); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/exceptions/0000755000175000017500000000000012127544344024430 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/exceptions/TileException.java0000644000175000017500000000211612122526602030037 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.exceptions; public class TileException extends Exception { public TileException(String message, Throwable cause) { super(message, cause); } public TileException(String message) { super(message); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/exceptions/AtlasTestException.java0000644000175000017500000000313212122526602031045 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.exceptions; import mobac.program.interfaces.LayerInterface; import mobac.program.interfaces.MapInterface; public class AtlasTestException extends Exception { public AtlasTestException(String message, MapInterface map) { super(message + "\nError caused by map \"" + map.getName() + "\" on layer \"" + map.getLayer().getName() + "\""); } public AtlasTestException(String message, LayerInterface layer) { super(message + "\nError caused by layer \"" + layer.getName() + "\""); } public AtlasTestException(String message) { super(message); } public AtlasTestException(Throwable cause) { super(cause); } public AtlasTestException(String message, Throwable cause) { super(message, cause); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/exceptions/UnrecoverableDownloadException.java0000644000175000017500000000336712127544344033447 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.exceptions; /** * An {@link UnrecoverableDownloadException} indicates that there has been a * problem on client side that made it impossible to download a certain file * (usually a map tile image). Therefore the error is independent of the network * connection between client and server and the server itself. */ public class UnrecoverableDownloadException extends TileException { private static final long serialVersionUID = 1L; public static int ERROR_CODE_NORMAL = 0; public static int ERROR_CODE_CONTENT_TYPE = 1; private int errorCode = ERROR_CODE_NORMAL; public UnrecoverableDownloadException(String message) { super(message); errorCode = ERROR_CODE_NORMAL; } public UnrecoverableDownloadException(String message, int errorCode) { super(message); this.errorCode = errorCode; } public int getErrorCode() { return errorCode; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/exceptions/MapSourcesUpdateException.java0000644000175000017500000000255312122526602032373 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.exceptions; import mobac.mapsources.MapSourcesManager; /** * Encapsulates several other exceptions that may occur while performing an * mapsources online update. * * @see MapSourcesManager#mapsourcesOnlineUpdate() */ public class MapSourcesUpdateException extends Exception { private static final long serialVersionUID = 1L; public MapSourcesUpdateException(String message) { super(message); } public MapSourcesUpdateException(Throwable cause) { super(cause); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/exceptions/MapSourceCreateException.java0000644000175000017500000000215712122526602032171 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.exceptions; public class MapSourceCreateException extends Exception { public MapSourceCreateException(String message) { super(message); } public MapSourceCreateException(String message, Throwable cause) { super(message, cause); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/exceptions/StopAllDownloadsException.java0000644000175000017500000000216612122526602032400 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.exceptions; public class StopAllDownloadsException extends TileException { public StopAllDownloadsException(String message, Throwable cause) { super(message, cause); } public StopAllDownloadsException(String message) { super(message); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/exceptions/MapDownloadSkippedException.java0000644000175000017500000000236712122526602032677 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.exceptions; import mobac.program.AtlasThread; /** * Thrown in {@link AtlasThread#createMap(mobac.program.interfaces.MapInterface)} * if the user chose to skip that map because of download problems. */ public class MapDownloadSkippedException extends Exception { private static final long serialVersionUID = 1L; public MapDownloadSkippedException() { super(); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/exceptions/MOBACOutOfMemoryException.java0000644000175000017500000000321112122526602032126 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.exceptions; import mobac.utilities.Utilities; public class MOBACOutOfMemoryException extends RuntimeException { long requiredMemory; long heapAvailable; public MOBACOutOfMemoryException(long requiredMemory, String message) { super(message); Runtime r = Runtime.getRuntime(); heapAvailable = r.maxMemory() - r.totalMemory() + r.freeMemory(); this.requiredMemory = requiredMemory; } @Override public String getMessage() { return super.getMessage() + "\nRequired memory: " + getFormattedRequiredMemory() + "\nAvailable free memory: " + Utilities.formatBytes(heapAvailable); } public long getRequiredMemory() { return requiredMemory; } public String getFormattedRequiredMemory() { return Utilities.formatBytes(requiredMemory); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/exceptions/InvalidNameException.java0000644000175000017500000000206712122526602031336 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.exceptions; public class InvalidNameException extends Exception { private static final long serialVersionUID = 1L; public InvalidNameException(String message) { super(message); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/exceptions/MapCreationException.java0000644000175000017500000000442112122526602031345 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.exceptions; import java.io.StringWriter; import mobac.program.interfaces.ExceptionExtendedInfo; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSource; import mobac.program.model.MapSourceLoaderInfo; public class MapCreationException extends Exception implements ExceptionExtendedInfo { private static final long serialVersionUID = 1L; private MapInterface map; public MapCreationException(String message, MapInterface map, Throwable cause) { super(message, cause); this.map = map; } public MapCreationException(String message, MapInterface map) { super(message); this.map = map; } public MapCreationException(MapInterface map, Throwable cause) { super(cause); this.map = map; } public String getExtendedInfo() { StringWriter sw = new StringWriter(); if (map != null) { sw.append(map.getInfoText()); MapSource mapSource = map.getMapSource(); if (mapSource != null) { MapSourceLoaderInfo loaderInfo = map.getMapSource().getLoaderInfo(); if (loaderInfo != null) { sw.append("\nMap type: " + loaderInfo.getLoaderType()); if (loaderInfo.getSourceFile() != null) sw.append("\nMap implementation: " + loaderInfo.getSourceFile().getName()); sw.append("\nMap revision: " + loaderInfo.getRevision()); } } } return sw.toString(); } public MapInterface getMap() { return map; } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/exceptions/TileStoreException.java0000644000175000017500000000231212122526602031052 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.exceptions; import com.sleepycat.je.DatabaseException; public class TileStoreException extends DatabaseException { public TileStoreException(Throwable t) { super(t); } public TileStoreException(String message) { super(message); } public TileStoreException(String message, Throwable t) { super(message, t); } } ././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/exceptions/MapSourceInitializationException.javamobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/exceptions/MapSourceInitializationException.ja0000644000175000017500000000241712122526602033425 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.exceptions; public class MapSourceInitializationException extends Exception { public MapSourceInitializationException() { } public MapSourceInitializationException(String message) { super(message); } public MapSourceInitializationException(Throwable cause) { super(cause); } public MapSourceInitializationException(String message, Throwable cause) { super(message, cause); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/exceptions/DownloadFailedException.java0000644000175000017500000000277612122526602032032 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.exceptions; import java.io.IOException; import java.net.HttpURLConnection; public class DownloadFailedException extends IOException { private final int httpResponseCode; private HttpURLConnection connection; public DownloadFailedException(HttpURLConnection connection, int httpResponseCode) throws IOException { super("Invaild HTTP response: " + httpResponseCode); this.connection = connection; this.httpResponseCode = httpResponseCode; } public int getHttpResponseCode() { return httpResponseCode; } @Override public String getMessage() { return super.getMessage() + "\n" + connection.getURL(); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/exceptions/UpdateFailedException.java0000644000175000017500000000214612122526602031474 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.exceptions; public class UpdateFailedException extends Exception { public UpdateFailedException(String message) { super(message); } public UpdateFailedException(String message, Throwable cause) { super(message, cause); } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/externaltools/0000755000175000017500000000000012127544346025154 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/externaltools/ToolParameters.java0000644000175000017500000000232512122526602030750 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.externaltools; public enum ToolParameters { MAX_LAT, MIN_LAT, MAX_LON, MIN_LON, // MIN_ZOOM, MAX_ZOOM, // minimum and maximum of selected zoom levels check-boxes MAPSOURCE_NAME, MAPSOURCE_DISPLAYNAME, // Currently select map source internal or display name NAME_EDITBOX // content of the edit box "Name" in the side panel "Atlas Content" } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/externaltools/ExternalToolsLoader.java0000644000175000017500000000737612122526602031754 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.externaltools; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.util.LinkedList; import java.util.List; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import mobac.program.DirectoryManager; import mobac.utilities.GUIExceptionHandler; import mobac.utilities.Utilities; import mobac.utilities.file.FileExtFilter; import org.w3c.dom.Document; public class ExternalToolsLoader { public static List tools = null; static { load(); } public static boolean load() { try { File dir = DirectoryManager.toolsDir; if (!dir.isDirectory()) return false; File[] files = dir.listFiles(new FileExtFilter(".xml")); tools = new LinkedList(); for (File f : files) { tools.add(loadFile(f)); } return true; } catch (Exception e) { GUIExceptionHandler.showExceptionDialog("Failed to load external tools definition", e); return false; } } public static ExternalToolDef loadFile(File f) throws JAXBException { JAXBContext context = JAXBContext.newInstance(ExternalToolDef.class); Unmarshaller unmarshaller = context.createUnmarshaller(); InputStream is = null; try { is = new FileInputStream(f); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); DocumentBuilder loader = factory.newDocumentBuilder(); Document document = loader.parse(is); return (ExternalToolDef) unmarshaller.unmarshal(document); } catch (JAXBException e) { throw e; } catch (Exception e) { throw new JAXBException(e); } finally { Utilities.closeStream(is); } } public static void save(ExternalToolDef toolsDef, File f) throws JAXBException { JAXBContext context = JAXBContext.newInstance(ExternalToolDef.class); Marshaller marshaller = context.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); OutputStream os = null; try { os = new FileOutputStream(f); marshaller.marshal(toolsDef, os); } catch (FileNotFoundException e) { throw new JAXBException(e); } finally { Utilities.closeStream(os); } } public static final void main(String[] args) { try { ExternalToolDef t = new ExternalToolDef(); t.command = "command"; t.name = "test"; t.parameters.add(ToolParameters.MAX_LAT); t.parameters.add(ToolParameters.MAX_LON); t.parameters.add(ToolParameters.MIN_LAT); t.parameters.add(ToolParameters.MIN_LON); save(t, new File("tools/test.xml")); } catch (Exception e) { e.printStackTrace(); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/java/mobac/externaltools/ExternalToolDef.java0000644000175000017500000001007712127544346031063 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.externaltools; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.List; import javax.swing.JOptionPane; import javax.xml.bind.annotation.XmlList; import javax.xml.bind.annotation.XmlRootElement; import mobac.gui.MainGUI; import mobac.program.model.MapSelection; import mobac.utilities.GUIExceptionHandler; import mobac.utilities.I18nUtils; import org.apache.log4j.Logger; @XmlRootElement(name = "ExternalTool") public class ExternalToolDef implements ActionListener { private static final Logger log = Logger.getLogger(ExternalToolDef.class); /** * Name used for the menu entry in MOBAC */ public String name; /** * For starting a commandline-script on Windows use cmd /c start mybatch.cmd */ public String command; public boolean debug = false; @XmlList public List parameters = new ArrayList(); public void actionPerformed(ActionEvent e) { try { String executeCommand = command; MainGUI gui = MainGUI.getMainGUI(); MapSelection mapSel = gui.getMapSelectionCoordinates(); int[] zooms = gui.getSelectedZoomLevels().getZoomLevels(); for (ToolParameters param : parameters) { String add = ""; switch (param) { case MAX_LAT: add = Double.toString(mapSel.getMax().lat); break; case MIN_LAT: add = Double.toString(mapSel.getMin().lat); break; case MAX_LON: add = Double.toString(mapSel.getMax().lon); break; case MIN_LON: add = Double.toString(mapSel.getMin().lon); break; case MAX_ZOOM: if (zooms.length == 0) { JOptionPane.showMessageDialog(gui, I18nUtils.localizedStringForKey("msg_no_zoom_level_selected"), I18nUtils.localizedStringForKey("Error"), JOptionPane.ERROR_MESSAGE); return; } add = Integer.toString(zooms[zooms.length - 1]); break; case MIN_ZOOM: if (zooms.length == 0) { JOptionPane.showMessageDialog(gui, I18nUtils.localizedStringForKey("msg_no_zoom_level_selected"), I18nUtils.localizedStringForKey("Error"), JOptionPane.ERROR_MESSAGE); return; } add = Integer.toString(zooms[0]); break; case MAPSOURCE_NAME: add = gui.previewMap.getMapSource().getName(); break; case MAPSOURCE_DISPLAYNAME: add = gui.previewMap.getMapSource().toString(); break; case NAME_EDITBOX: add = gui.getUserText(); break; default: throw new RuntimeException("Unsupported parameter type: " + param); } if (add.indexOf(' ') >= 0) add = "\"" + add + "\""; executeCommand += " " + add; } if (debug) { int r = JOptionPane.showConfirmDialog(gui, String.format(I18nUtils.localizedStringForKey("msg_tools_exec_command_ask"), executeCommand), I18nUtils.localizedStringForKey("msg_tools_exec_command_ask_title"), JOptionPane.OK_CANCEL_OPTION); if (r != JOptionPane.OK_OPTION) return; } log.debug("Executing " + executeCommand); Runtime.getRuntime().exec(executeCommand); } catch (Exception e1) { GUIExceptionHandler.processException(e1); } } } mobile-atlas-creator-1.9.14+dfsg1/src/main/resources/0000755000175000017500000000000012122526606022253 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/resources/mobac/0000755000175000017500000000000012175454364023345 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/resources/mobac/mobac.properties0000644000175000017500000000041612175454054026541 0ustar paulliupaulliumobac.version=1.9.14 mobac.revision.fallback=$Revision: 2139 $ mobac.revision.hide=false mobac.updateurl=http://mobac.sourceforge.net/mapsources-update/v2/mappacks-md5.txt mobac.updatebaseurl=http://mobac.sourceforge.net/mapsources-update/v2/ mobac.mappackversion=1mobile-atlas-creator-1.9.14+dfsg1/src/main/resources/mobac/mobac-rev.properties0000644000175000017500000000007112175454364027334 0ustar paulliupaulliu#Mon, 29 Jul 2013 19:58:42 +0200 mobac.revision=2140 mobile-atlas-creator-1.9.14+dfsg1/src/main/resources/mobac/resources/0000755000175000017500000000000012122526606025346 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/resources/mobac/resources/xsl/0000755000175000017500000000000012122526606026154 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/resources/mobac/resources/xsl/gpx10to11.xsl0000644000175000017500000000646112122526606030357 0ustar paulliupaulliu xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" Transformation changes from GPX version 1.0 to version 1.1 are as follows: All gpx element child elements except wpt, rte and trk regrouped under newly created metadata element author and email re-written, author child link element and copyright elements not created. all occurances of url and urlname elements re-written as Link element, extensions element, trk and rte child elements not created. trk child elements course and speed disregarded as they are obsolete in version 1.1 by William A Slabbekoorn aka Cybarber, August 2005. mobile-atlas-creator-1.9.14+dfsg1/src/main/resources/mobac/resources/text/0000755000175000017500000000000012171650636026337 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/resources/mobac/resources/text/localize.properties0000644000175000017500000010215512150552674032263 0ustar paulliupaulliu#---------- Version ------------------------- mobac_version_subfix=International Edition mobac_version_subfix_dev= #---------- Basic ------------------------- OK=OK Cancel=Cancel Close=Close Error=Error Unnamed=Unnamed Warning=Warning minute=minute minutes=minutes second=second seconds=seconds Information=Information Continue=Continue Abort=Abort Skip=Skip Retry=Retry Undefined=Unknown Exit=Exit Bytes=Bytes KiByte=KiByte MiByte=MiByte GiByte=GiByte #---------- On map controls ------------------------- map_ctrl_zoom_level_title= Zoom: map_ctrl_zoom_level_title_tips=The current zoom level map_ctrl_zoom_grid_tips=Projects a grid of the specified zoom level over the map map_ctrl_zoom_grid_prefix_fmt=Grid Zoom %d map_ctrl_zoom_grid_disable=Grid disabled map_ctrl_wgs_grid_title=WGS 84 Grid map_ctrl_wgs_grid_tips=Projects WGS 84 Grid on map preview (not included in atlas) map_ctrl_wgs_grid_density_tips=Specifies density for WGS 84 Grid map_ctrl_wgs_grid_density_prefix=Every map_ctrl_wgs_grid_density_degree=Degree map_ctrl_wgs_grid_density_degrees=Degrees map_ctrl_wgs_grid_density_minute=Minute map_ctrl_wgs_grid_density_minutes=Minutes map_ctrl_wgs_grid_density_seconds=Second map_ctrl_wgs_grid_density_second=Seconds map_loading_wait=Please wait - loading map data #---------- Left Panel ------------------------- #coordinate lp_coords_title=Selection coordinates (min/max) lp_coords_select_btn_title=Select entered coordinates lp_coords_label_N=N lp_coords_label_E=E lp_coords_label_W=W lp_coords_label_S=S lp_coords_fmt_list_title=Fmt lp_coords_fmt_degree_eng=Degree (eng) lp_coords_fmt_degree_local=Degree (local) lp_coords_fmt_degree_min_eng=Deg Min (eng) lp_coords_fmt_degree_min_local=Deg Min (local) lp_coords_fmt_degree_min_sec_eng=Deg Min Sec (eng) lp_coords_fmt_degree_min_sec_local=Deg Min Sec (local) lp_coords_fmt_tile=Tile (x or y / zoom) lp_coords_invalid_text=Invalid coordinate!
Please enter a number between %s and %s #map source lp_map_source_title=Map Source lp_map_source_combo_tips=Select map source #zoom level lp_zoom_title=Zoom Levels lp_zoom_total_tile_count_tips=Total amount of tiles to download lp_zoom_number_tips=Select zoom level %d for atlas lp_zoom_total_tile_title=%s tiles lp_zoom_total_tile_hint_head=Total amount of tiles to download: lp_zoom_total_tile_hint_row=
Level %d: %d (%dx%d) #Tile parameters settings lp_tile_param_title=Layer settings: custom tile processing lp_tile_param_recreate_checkbox_title=Recreate/adjust map tiles (CPU intensive) lp_tile_param_recreate_checkbox_tips=If this option is disabled, each map tile (size: 256x256) is used exactly as downloaded from the server (faster).
\ Otherwise each tile is newly created which allows to use custom tile size (slower / CPU intensive). lp_tile_param_width_title=Width: lp_tile_param_width_tips=Tile width lp_tile_param_height_title=Height: lp_tile_param_height_tips=Tile height lp_tile_param_image_fmt_title=Tile format: lp_tile_param_image_fmt_png=PNG lp_tile_param_image_fmt_png_8bit=PNG 256 colors (8 bit) lp_tile_param_image_fmt_png_4bit=PNG 16 colors (4 bit) lp_tile_param_image_fmt_jpg_q100=JPEG - quality 100 lp_tile_param_image_fmt_jpg_q99=JPEG - quality 99 lp_tile_param_image_fmt_jpg_q95=JPEG - quality 95 lp_tile_param_image_fmt_jpg_q90=JPEG - quality 90 lp_tile_param_image_fmt_jpg_q85=JPEG - quality 85 lp_tile_param_image_fmt_jpg_q80=JPEG - quality 80 lp_tile_param_image_fmt_jpg_q70=JPEG - quality 70 lp_tile_param_image_fmt_jpg_q60=JPEG - quality 60 lp_tile_param_image_fmt_jpg_q50=JPEG - quality 50 lp_tile_param_msg_valid_height=Value of "Tile Size Height" must be between %d and %d.\n lp_tile_param_msg_valid_width=Value of "Tile Size Width" must be between %d and %d.\n #atlas content lp_atlas_title=Atlas Content lp_atlas_new_btn_title=New lp_atlas_add_selection_btn_title=Add selection lp_atlas_name_label_title=Name: lp_atlas_name_field_tips=Enter a name for the atlas here # this one only support English #lp_atlas_element_default_name=Layer name #atlas content detail - Atlas lp_atlas_info_atlas_title=Atlas
lp_atlas_info_atlas_name=Name: %s
lp_atlas_info_atlas_layer=Layer count: %d
lp_atlas_info_atlas_format=Atlas format: %s
lp_atlas_info_max_tile=Maximum tiles to download: %d
lp_atlas_info_area_start=Area start: %s %s
lp_atlas_info_area_end=Area end: %s %s
#atlas content detail - Layer lp_atlas_info_layer_title=Layer
lp_atlas_info_layer_map_count=Map count: %d
#atlas content detail - Map lp_atlas_info_map_title=Map
lp_atlas_info_polygon_map_title=Polygonal Map
lp_atlas_info_polygon_map_point=Polygon points:
lp_atlas_info_map_source_short=Map source: %s
lp_atlas_info_map_source=Map source: %s (%s)
lp_atlas_info_map_zoom_lv=Zoom Level: %d
lp_atlas_info_map_area_start=Area start: %s (%d / %d)
lp_atlas_info_map_area_end=Area end: %s (%d / %d)
lp_atlas_info_map_size=Map size: %d x %d pixel
lp_atlas_info_tile_size=Tile size: %d x %d
lp_atlas_info_tile_format=Tile format: %s
lp_atlas_info_tile_format_origin=Tile format: 256x256 (no processing)
#atlas content node pop menu lp_atlas_pop_menu_show_detail=Show item details lp_atlas_pop_menu_display_select_area=Display selected areas lp_atlas_pop_menu_select_map_box=Select map bounding box lp_atlas_pop_menu_zoom_to_map_box=Zoom to map bounding box lp_atlas_pop_menu_zoom_to=Zoom to lp_atlas_pop_menu_rename=Rename lp_atlas_pop_menu_apply_tile_process=Apply tile processing options lp_atlas_pop_menu_clear_atals=Clear atlas lp_atlas_pop_menu_delete_node=Delete lp_atlas_default_tip=Use context menu of the entries to see all available commands. #Profile lp_atlas_profile_title=Saved profiles lp_atlas_profile_combo_tips=Select an atlas creation profile\n or enter a name for a new profile lp_atlas_profile_delete_btn_title=Delete lp_atlas_profile_delete_btn_tips=Delete atlas profile from list lp_atlas_profile_save_btn_title=Save lp_atlas_profile_save_btn_tips=Save atlas profile lp_atlas_profile_load_btn_title=Load lp_atlas_profile_load_btn_tips=Load the selected profile lp_atlas_profile_refresh_btn_tips=reload the profiles list lp_atlas_profile_msg_ask_name=Please enter a profile name lp_atlas_profile_msg_overwrite_confirm_title=Please confirm lp_atlas_profile_msg_overwrite_confirm=Profile %s already exists. Overwrite? #main button lp_mian_create_btn_title=Create Atlas lp_main_create_btn_tips=Create the atlas lp_main_setting_button_title=Settings lp_main_setting_button_tips=Open the preferences dialogue panel #tile store coverage lp_tile_store_title=Map source tile store coverage lp_tile_store_title_tips=Displays the regions for the currently selected map source that has been
\ downloaded and which are therefore offline available in the tile store (tile cache) lp_tile_store_show_coverage_btn_title=Show coverage lp_tile_store_show_coverage_btn_tips=Display tile store coverage for the current map source,
\ the selected zoom level and the current visible map region.
\ Green regions are present in the cache, gray regions are not covered. lp_tile_store_hide_coverage_btn_title=Hide coverage lp_tile_store_zoom_combo_tips=Select the zoom level you wish to display tile store coverage lp_tile_store_zoom_title=Zoom level: lp_tile_store_layer_title=Layer: #---------- GPX Panel ------------------------- rp_gpx_new_gpx=New Gpx rp_gpx_load_gpx=Load Gpx rp_gpx_save_gpx=Save Gpx rp_gpx_clear_gpx=Clear List rp_gpx_add_wpt=Add wpt rp_gpx_default_node_name=loaded gpx files... rp_gpx_pop_menu_delete_element=delete element rp_gpx_pop_menu_rename_element=rename element rp_gpx_menu_rename=rename rp_gpx_menu_delete=delete rp_gpx_msg_confim_delete_title=Delete node rp_gpx_msg_confim_delete=Do you really want to delete this node? rp_gpx_rename_element_title=Please input the name: rp_gpx_msg_can_not_rename_track=Track segments cannot be named. rp_gpx_msg_ask_create_new=No GPX file selected.\nDo you want to create a new GPX file? rp_gpx_msg_ask_create_new_title=Add point to new GPX file? rp_gpx_msg_add_point_failed=Way points can only be added to the gpx file, routes or track segments rp_gpx_root_default_name_nofile=unnamed (new gpx) rp_gpx_root_default_name_hasfile=unnamed (file %s) rp_gpx_unname_route_name=unnamed route rp_gpx_unname_track_name=unnamed track rp_gpx_unname_wpt_name=unnamed waypoint rp_gpx_msg_confirm_reopen_file=One or more Gpx files are already opened.\nDo you want to open new instances of these files? rp_gpx_msg_error_save_gpx_file=Error saving Gpx file rp_gpx_msg_no_select_file=No Gpx file selected rp_gpx_node_seg_name=segment %s #---------- Main Menu ------------------------- #Atlas menu_atlas=Atlas menu_atlas_new=New Atlas menu_atlas_convert_format=Convert Atlas Format menu_atlas_create=Create Atlas #Maps menu_maps=Maps menu_maps_selection=Selection Mode menu_maps_selection_rect=Rectangle menu_maps_selection_polygon=Polygon menu_maps_selection_circle=Circle menu_maps_selection_add=Add selection menu_maps_selection_add_by_gpx=Add selection by GPX track #Bookmark menu_bookmark=Bookmarks menu_bookmark_save=Save current view menu_bookmark_manage=Manage Bookmarks #Panels menu_panels=Panels menu_show_hide_left_panel=Show/hide left panel menu_show_hide_gpx_panel=Show/hide GPX panel #Debug menu_debug=Debug menu_debug_show_hide_tile_border=Show/Hide map tile borders menu_debug_show_all_map_source=Show all map source names menu_debug_refresh_map_source=Refresh custom map sources menu_debug_show_log_file=Show log file menu_debug_log_level=General log level menu_debug_system_report=Generate system report #help menu_help=Help menu_help_readme=Show Readme menu_help_how_to_preview=How to use preview map menu_help_licenses=Licenses menu_help_about=About #tools menu_tool=Tools #---------- Dialog ------------------------- #About dlg_about_title=About dlg_about_version=Version: dlg_about_program_version=Program revision: dlg_about_download_mapplus=Download Map Plus dlg_about_download_mapplus_url=http://itunes.apple.com/us/app/map-plus/id438868200?mt=8&ls=1 #Font choose dlg_font_choose_title=Choose font dlg_font_choose_preview=Preview dlg_font_choose_name=Name dlg_font_choose_style=Style dlg_font_choose_size=Size #Licenses dlg_license_title=Licenses #Help dlg_help_title=Help #Manager Bookmark dlg_mgn_bookmark_title=Manage Bookmarks dlg_mgn_bookmark_delete=Delete Bookmark #Bookmark Add dlg_add_bookmark_msg=please select a name for the new bookmark #New Atlas dlg_new_atlas_title=Settings for new Atlas dlg_new_atlas_name_title=Name of the new atlas: dlg_new_atlas_default_atlas_name=Unnamed atlas dlg_new_atlas_select_format_title=Please select the desired atlas format #Working Progress dlg_progress_title=Progress dlg_progress_about_btn=About dlg_progress_count=Count: 0 dlg_progress_count_i=Count: %d #Select GPX Track dlg_gpx_track_select_title=Selected distance around track dlg_gpx_track_select_distance=Selected distance around track: %d %s #Add GPS point dlg_gpx_inpu_point_name=Please input a name for the new point: #Show All Map Source dlg_show_source_title=Map source names dlg_show_source_column_name=Name dlg_show_source_column_display_text=Display text dlg_show_source_column_rev=Revision dlg_show_source_column_type=Type #Select Dir dlg_select_dir_title=Select Directory dlg_select_dir_description=Directories #Atlas download progress dlg_download_title=Atlas creation in progress dlg_download_zoom_level_progress=Collecting tiles for zoom level dlg_download_map_progress=Processing maps of atlas: dlg_download_atlas_progress=%d%% done - processing atlas %s of type %s dlg_download_done_percent=%d%% done dlg_download_done_tenthpercent=%.1f%% done dlg_download_window_title=

ATLAS CREATION IN PROGRESS...

dlg_download_map_info_label_default=Processing map ABCDEFGHIJKLMNOPQRSTUVWXYZ-nn of layer ABCDEFGHIJKLMNOPQRSTUVWXYZ from map source ABCDEFGHIJKLMNOPQRSTUVWXYZ dlg_download_map_info_label=Processing map %s of layer %s from map source %s dlg_download_map_done_count_default=000 of 000 done dlg_download_map_done_count=%d of %d done dlg_download_remain_time_default=Time remaining: 00000 minutes 00 seconds dlg_download_remain_time=Time remaining: %s dlg_download_tile_done_count_default=1000000 of 1000000 tiles done dlg_download_tile_done_count=%d of %d tiles done dlg_download_map_create_title=Map Creation dlg_download_avg_speed=Average download speed dlg_download_avg_speed_value=: %s / second dlg_download_total_bytes=Downloaded dlg_download_bytes_from_cache=Loaded from tile store dlg_download_thread_count=Active tile fetcher threads dlg_download_retry_count=Transient download errors dlg_download_retry_count_value=: current map: %d, total: %d dlg_download_failed_count=Unrecoverable download errors dlg_download_failed_count_value=: current map: %d, total: %d dlg_download_error_tips=

Download errors for the current map and for the total atlas (transient/unrecoverable)

\

Mobile Atlas Creator retries failed tile downloads up to two times.
\ If the tile downloads fails the second time the tile will be counted as
\ unrecoverable error and not tried again during the current map creation run.

dlg_download_total_time=Total creation time dlg_download_checkbox_ignore_error=Ignore download errors and continue automatically dlg_download_status_title=Status: dlg_download_status_running=RUNNING dlg_download_status_aborted=ABORTED dlg_download_status_finished=FINISHED dlg_download_status_paused=PAUSED dlg_download_btn_abort=Abort creation dlg_download_btn_abort_tips=Abort current Atlas download dlg_download_btn_close_win=Close Window dlg_download_btn_close_win_tips_disable=Atlas creation in progress... dlg_download_btn_close_win_tips_enable=Close atlas creation progress window dlg_download_btn_open_folder=Open Atlas Folder dlg_download_btn_open_folder_tips_disabled=Atlas creation in progress... dlg_download_btn_open_folder_tips_enabled=Open folder where atlas output folder dlg_download_btn_pause_resume=Pause/Resume dlg_download_time_unknown=unknown dlg_download_abort_title=Atlas creation aborted dlg_download_abort_window_title=

ATLAS CREATION HAS BEEN ABORTED BY USER

dlg_download_succeed_title=Atlas creation finished successfully dlg_download_succeed_window_title=

ATLAS CREATION FINISHED SUCCESSFULLY

dlg_download_errors_todo=Multiple download errors - how to proceed? dlg_download_errors_todo_msg=Multiple tile downloads have failed. \ Something may be wrong with your connection to the download server or your selected area. \
Do you want to:

\ Continue map download and ignore the errors? (results in blank/missing tiles)
\ Retry to download this map, by starting over?
\ Skip the current map and continue to process other maps in the atlas?
\ Abort the current map and atlas creation process?
dlg_download_errors_missing_tile=Error - tiles are missing - do you want to continue anyway? dlg_download_errors_missing_tile_msg=Something is wrong with download of atlas tiles.\n\ The amount of downloaded tiles is not as high as it was calculated.\nTherefore tiles \ will be missing in the created atlas.\n %d tiles are missing.\n\n\ Are you sure you want to continue and create the atlas anyway? dlg_download_show_error_report=Show error report dlg_download_erro_head=An error occured: #Splash Frame splash_title=Mobile Atlas Creator is starting up... #---------- Setting ------------------------- set_title=Settings #Display set_display_title=Display set_display_unit_system_title=Unit System set_display_unit_system_metric=Metric set_display_unit_system_imperial=Imperial set_display_unit_system_scale_bar=Unit system for map scale bar: set_display_language=Language set_display_language_choose=Choose Language: set_display_language_choose_tips=Choose a language and restart MOBAC to take effect. set_display_language_restart_desc=You need to restart MOBAC after language changes. set_display_language_msg_title=Restart Required set_display_language_msg=Please restart MOBAC to make the new language take effect. set_display_grid=WGS 84 Grid set_display_grid_compress=Compress labels set_display_grid_compress_tips=If selected, the coordinate labels will not contain explicit information. set_display_grid_title=Choose grid color set_display_grid_width=Width: set_display_grid_width_tips=The width of the lines. set_display_grid_color=Color: set_display_grid_color_tips=The color of the lines and coordinate labels. set_display_grid_font=Font: set_display_grid_font_tips=Chooses the font to be used for the coordinate labels. #Map sources config set_mapsrc_config_title=Map sources config set_mapsrc_config_online_update=Map packs online update set_mapsrc_config_online_update_btn=Perform online update set_mapsrc_config_online_update_no_update=No updates available set_mapsrc_config_online_update_done=Updates has been downloaded set_mapsrc_config_online_update_failed=Update failed set_mapsrc_config_online_update_msg_outdate=This version of MOBAC is no longer supported for online updates.\ Please upgrade to the most recent version. set_mapsrc_config_online_update_msg_noneed=You have already the latest map packs installed. set_mapsrc_config_online_update_msg_done=%d map packs has been updated.\n\ Please restart MOBAC for installing the updates. set_mapsrc_config_osmhiking=Reit- und Wanderkarte ($Abo) set_mapsrc_config_osmhiking_purchased=Purchased ticket ID: set_mapsrc_config_osmhiking_howto=How to get a ticket (German) set_mapsrc_config_osmhiking_howto_url=http://www.wanderreitkarte.de/shop_abo_de.php #Map sources set_mapsrc_mgr_title=Map sources set_mapsrc_mgr_title_enabled=Enabled Map Sources set_mapsrc_mgr_title_disabled=Disabled Map Sources set_mapsrc_mgr_move_up_tips=Move selected enabled map
source(s) one position up set_mapsrc_mgr_move_down_tips=Move selected enabled map
source(s) one position down set_mapsrc_mgr_move_left_tips=Enable the selected disabled map source(s) set_mapsrc_mgr_move_right_tips=Disable the selected enabled map source(s) #Tile Update set_tile_update_title=Tile update set_tile_update_desc=Tiles are updated automatically base on the settings below. \ Each map tile has
an expiry date that is sometimes provided by \ the server. If the server does
not provide one, the default expiration time is used. set_tile_update_default_expiration=Default expiration time set_tile_update_default_expiration_desc=The default expiration time is used for map sources that do not
\ provide an expiration time for each map tile. set_tile_update_max_expiration=Maximum expiration time set_tile_update_min_expiration=Minimum expiration time #Tile Store set_tile_store_title=Tile store set_tile_store_enable_checkbox=Enable tile store for map preview and atlas download set_tile_store_settings=Tile store settings set_tile_store_information=Information set_tile_store_info_mapsrc=Map source set_tile_store_info_tiles=Tiles set_tile_store_info_size=Size set_tile_store_info_disabled_subfix= (unused) set_tile_store_info_delete_tips=Delete all stored %s tiles. set_tile_store_info_deleteing_tips=Deleting in progress - please wait set_tile_store_info_total=Total #Map Size set_map_size_title=Map size set_map_size_settings=Map size settings set_map_size_max_size_of_rect=Maximum size (width & height) of rectangular maps: set_map_size_overlap_tiles=Number of tiles to overlap maps regions: set_map_size_desc=If the area of the selected rectangular region to download\ is larger in height or width than
the map size it will be splitted into \ several maps when adding the map selection.
\ Each map is no larger than the specified maximum map size.
\ Note that polygonal maps are not affected by this setting!
\ You can see the number of maps and their region in the atlas content tree.
\ Changing the maximum map size after an area has been added the atlas has no effect on the atlas.

\ Note for TrekBuddy users:
TrekBuddy versions before v0.9.88 \ do not support map sizes larger than 32767.
\ Newer versions can handle maps up to a size of 1048575. #Directory set_directory_title=Directories set_directory_output=Atlas output directory set_directory_output_tips=If empty the default directory is used:
%s set_directory_output_select=Select set_directory_output_select_dlg_title=Select Directory #Network set_net_title=Network set_net_connection=Network connections set_net_connection_desc=Number of parallel network connections for tile downloading set_net_bandwidth_desc=Bandwidth limitation for tile downloading set_net_bandwidth_unlimited=Unlimited set_net_proxy=HTTP Proxy set_net_proxy_settings=Proxy settings: set_net_proxy_settings_java=Use standard Java proxy settings set_net_proxy_settings_application=Use application properties set_net_proxy_settings_custom=Use custom proxy (user defined) set_net_proxy_settings_custom_auth=Use custom proxy with Authentication set_net_proxy_host=Proxy host name: set_net_proxy_port=Proxy port: set_net_proxy_username=Proxy user: set_net_proxy_password=Proxy password: set_net_default=Default set_net_default_ignore_error=Ignore download errors and continue automatically #Paper Atlas set_paper_title=Paper Atlas #Paper Atlas - Size set_paper_size=Size set_paper_size_default=Default set_paper_size_default_tips=If selected, paper size will be determined by the specifed format. set_paper_size_default_combo_tips=Chooses a default page format. set_paper_size_default_landscape=Landscape set_paper_size_default_landscape_tips=If selected, the paper format will be positioned landscape. set_paper_size_custom=Custom set_paper_size_custom_tips=If selected, user can specify the paper size manualy. set_paper_size_custom_width=Width: set_paper_size_custom_width_tips=Specified the page width. set_paper_size_custom_height=Height: set_paper_size_custom_height_tips=Specified the page height. set_paper_size_selection=Selection set_paper_size_selection_tips=If selected, paper size will be determined by the map size. #Paper Atlas - Additions set_paper_additions=Additions set_paper_wgs_grid=WGS 84 Grid set_paper_wgs_grid_tips=If selected, WGS-84 grid will be painted on the map. set_paper_wgs_grid_density_tips=Chooses the density for the WGS-84 Grid. set_paper_paper_nubmer=Page numbers set_paper_paper_nubmer_tips=If selected, page numbers will be painted on each page. set_paper_scale_bar=Scale bar set_paper_scale_tips=If selected, scale bar will be painted on the map. set_paper_compass=Compass set_paper_compass_tips=If selected, compass will be painted on the map. #Paper Atlas - Margins set_paper_margins=Margins set_paper_margins_tips=Specifies the margin size. set_paper_margins_top=Top: set_paper_margins_left=Left: set_paper_margins_bottom=Bottom: set_paper_margins_right=Right: #Paper Atlas - Advanced set_paper_advanced=Advanced set_paper_advanced_compression=Compression: set_paper_advanced_compression_tips=Specifies the compression level used for PDF document.
\ Zero means no compression and 9 means best compression.
\ The higher number the better compression. The default value is 6. set_paper_advanced_dpi=Resolution set_paper_advanced_dpi_tips=Specifies the resolution (DPI) to be used for images.
\ Generally higher values means better quality,
but smaller pixel based objects
\ ( such as scale bar, WGS-84 grid, compass and page numbers).
\ Default value is 96, better quality can be achieved width 120.
\ Notice: Make sure, your PDF viewer displays the page with the
\ selected resolution. set_paper_advanced_overlap=Overlap: set_paper_advanced_overlap_tips=Specifies the size of overlap for two neighboring pages. set_paper_advanced_crop=Crop: set_paper_advanced_crop_tips=Specifies the number of crop percentage.
\ If any edge page is covered less than the crop percentage,
\ it will not be processed. #Paper Atlas - Actions set_paper_actions=Actions set_paper_actions_import_xml=Import from XML set_paper_actions_import_xml_tip=Imports all Paper Atlas settings from a XML file. set_paper_actions_export_xml=Export to XML set_paper_actions_export_xml_tip=Exports all Paper Atlas settings to a XML file. set_paper_actions_restore_default=Reset to defaults set_paper_actions_restore_default_tips=Resets Paper Atlas settings to default.
\ All previous changes will be lost. set_paper_actions_error_import=Unable to import Paper Atlas settings from file: set_paper_actions_error_export=Unable to export Paper Atlas settings to file: set_paper_actions_error_reason=Reason: set_paper_actions_error_title=An error occured! set_paper_actions_xml_filter=XML Files (*.xml) #Error set_error_saving_title=Error saving settings to file set_error_saving_msg=Error saving settings to file:\n ( %s ) #---------- Message ------------------------- #common msg_no_zoom_level_selected=No zoom level selected msg_no_select_area=Please select an area #Add GPX Track Polygon msg_add_gpx_polygon_too_many_track=The select gpx file contains more than one track.\nPlease select the desired track or track segment. msg_add_gpx_polygon_too_many_segment=The select track contains more than one track segment.\nPlease select the desired track segment. msg_add_gpx_polygon_no_select=No GPX track segment selected x=Maximum map size violated msg_add_gpx_polygon_maxsize=At least one map that has been added violates the maximum map size.\n\ Splitting a polygonal map into smaller pieces is not yet supported.\n\nDo you want to proceed anyway? #Convert Atlas msg_convert_atlas_format=Convert atlas format msg_convert_incompatible_format=Map incompatible with atlas format #Log file msg_no_log_file_config=No file logger configured msg_no_log_file=Log file does not exists:

%s #Setting msg_settings_write_error=Error on writing program settings to "settings.xml" #Refresh msg_refresh_all_map_source_done=%d custom file based map sources have been refreshed #Help msg_no_found_readme_file=Unable to find README.HTM #Merge Layer msg_confirm_merge_layer_title=Confirm layer merging msg_confirm_merge_layer=Are you sure you want to merge the maps of layer\n %s into layer %s? msg_merge_layer_failed=Layer merging failed #Tile Size select msg_invalid_tile_size=Invalid tile size!
Please enter a number between %d and %d #Tile Store Coverage msg_tile_store_failed_retrieve_coverage=Failed to retrieve tile store coverage data.\n\ May be the selected area and zoom is too large. #Atlas download thread msg_out_of_memory_title=Out of memory. msg_out_of_memory_head=Mobile Atlas Creator has run out of memory. msg_out_of_memory_detail=\nCurrent maximum memory associated to MOBAC %d MB msg_atlas_download_abort=Atlas download aborted msg_too_many_tiles_title=Atlas download prohibited msg_too_many_tiles_msg=Mobile Atlas Creator has detected that you are trying to\n\ download an extra ordinary large atlas with a very high number of tiles.\n\ Please reduce the selected areas on high zoom levels and try again.\n\ The maximum allowed amount of tiles per atlas is %d\n\ The number of tile in the currently selected atlas is: %d msg_atlas_version_mismatch=The loaded atlas belongs to an older version Mobile Atlas Creator.This old version\n\ used a somehow different atlas profile format which is incompatible to this version.\n\n\ It is recommended to clear the loaded atlas and delete the affected profile.\n\ Otherwise various exceptions may be thrown while working with this atlas. msg_atlas_data_check_failed=At least one problem was detected while loading the saved atlas profile.\n\ Usually this indicates that the profile file is inconsistent or the file format has changed.\n\n\ It is recommended to clear the loaded atlas and delete the affected profile.\n\ Otherwise various exceptions may be thrown while working with this atlas. #Settings msg_setting_file_is_changed_by_other_title=Overwrite changes? msg_setting_file_is_changed_by_other=The settings.xml files has been changed by another application.\n\ Do you want to overwrite these changes?\n\ All changes made by the other application will be lost! msg_settings_file_can_not_parse=Could not read file settings.xml program will exit. #Others msg_atlas_is_empty=Atlas is empty - please add at least one selection to atlas content. msg_environment_not_support_title=Unsupported environment msg_environment_not_support=Your environment is not supported.
Desktop: %s
Operating system: %s msg_environment_failed_open_output_title=Failed Open Atlas Directory msg_environment_failed_open_output=Failed to open atlas output directory.
msg_environment_use_commond=
Used command: %s
msg_environment_commond_param=Parameter: %d : %s msg_environment_lack_memory_title=Warning: low memory msg_environment_lack_memory=WARNING: Mobile Atlas Creator has been started \ with a very small amount of memory assigned.
\ The current maximum usable amount of memory to Mobile Atlas Creator is %s.

\ Please make sure to start Mobile Atlas Creator in \ the future via the provided start scripts Mobile Atlas Creator.exe
\ on Windows or start.sh on Linux/Unix/OSX or add the \ parameter -Xmx 512M to your startup command.

\ Example: java -Xmx512M -jar Mobile_Atlas_Creator.jar
\
Press OK to continue and start Mobile Atlas Creator
msg_environment_error_create_dir=Error while creating %s directory %s\n Program will exit. msg_environment_error_write_file=Unable to write to %s \n %s \n directory\n Please correct file permissions and restart MOBAC. msg_environment_error_create_setting=Could not create file settings.xml - program will exit. msg_environment_error_init_mapsrc_dir=Error on initializing map sources directory:\n msg_environment_error_load_cloudmade=Unable to load custom CloudMade map source. Please make sure the openstreetmap map source bundle is available. msg_environment_mapsrc_dir_not_exist=Map sources directory does not exist - path:\n %s \n\ Please make sure you extracted the release zip file\n\ of MOBAC correctly including all subdirectories! msg_environment_unable_to_start=Unable to start Mobile Atlas Creator: \n msg_environment_jre_bellow=The used Java Runtime Environment does not meet the minimum requirements.\n\ Mobile Atlas Creator requires at least Java 6 (1.6) or higher.\n\ Please update your Java Runtime before starting Mobile Atlas Creator.\n\n\ Detected Java Runtime Version: %@ msg_environment_jre_bellow_title=Java Runtime version problem detected msg_environment_invalid_source_folder=The specified source folder does not exist:\nMap name: %s\ \nSource folder: %s msg_environment_invalid_source_folder_zoom=No zoom directories found:\nMap name: %s\ \nSource folder: %s msg_environment_invalid_source_folder_title=Invalid source folder msg_tools_exec_command_ask=Command to be executed:
%s msg_tools_exec_command_ask_title=Do you want to execute the command? msg_custom_map_invalid_source_file_title=Invalid source file msg_custom_map_invalid_source_file=No database file specified.\nMap name: %s \nFilename: %s msg_custom_map_invalid_source_zip_title=Invalid source zip msg_custom_map_invalid_source_zip=The specified source zip does not exist:\nMap name: %s \nZip file: %s msg_custom_map_failed_open_source_zip_title=Error reading zip file msg_custom_map_failed_open_source_zip=The specified source zip can not be read:\nMap name: %s \nZip file: %s msg_custom_map_invalid_source_sqlitedb=The specified source SQLite database does not exist:\nMap name: %s \nFilename: %s msg_custom_map_source_failed_load_sqlitedb_title=Error loading database msg_custom_map_source_failed_load_sqlitedb=The specified source SQLite database could not be loaded:\nMap name: %s\ \nFilename: %s \nError: %s msg_update_map_pack_error_title=Error loading updated map package msg_update_map_pack_error=An error occured while installing the updated map package.Please restart MOBAC for restoring the previous version. msg_error_load_atlas_profile_title=Error loading atlas - continue loading? msg_error_load_atlas_profile=Error loading atlas:
 %s 
\
file: %s line/column: %d / %d
\ Do you want to continue loading the current atlas?
\ Continue loading may result in an incomplete or non-working atlas.
msg_environment_slqite_lib_missing_title="Error - SQLite not available" msg_environment_slqite_lib_missing=Unable to find the SQLite libraries. \ These are required for the currently selected atlas format.
Please read the README.HTM \ section "SQLite atlas formats". " msg_environment_image_format_not_available_title=Image format not available - libraries missing msg_environment_image_format_not_available=This image format is requires additional libraries to be installed:
\ Java Advanced Image library (jai_core.jar & jai_codec.jar)
\ For more details please see the file README.HTM \ in section Requirements. msg_tile_store_access_conflict_title=Multiple instances of Mobile Atlas Creator running msg_tile_store_access_conflict=Multiple instances of Mobile Atlas Creator are trying \ to access the same tile store.\n\ The tile store can only be used by used by one instance at a time.\n\ Please close the other instance and try again. mobile-atlas-creator-1.9.14+dfsg1/src/main/resources/mobac/resources/text/apache-2.0.txt0000644000175000017500000002613612122526606030621 0ustar paulliupaulliu Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. mobile-atlas-creator-1.9.14+dfsg1/src/main/resources/mobac/resources/text/help_dialog_ja.html0000644000175000017500000000235312171650636032151 0ustar paulliupaulliu

キーボードとマウスによる操作

F5 地図の再表示 (タイルの再読込)
<カーソルキー> 地図の移動
[マウス 右ボタン ドラッグ] 地図の移動
<ctrl> + <マウス 左ボタン> 地図の移動 (MacOS X のみ)
<ctrl> + <カーソル 上> ズームイン
[マウス 左ボタン ダブルクリック] ズームイン
[マウス スクロールアップ] ズームイン
<ctrl> + <カーソル 下> ズームアウト
[マウス スクロールダウン] ズームアウト
<ctrl> + <カーソル 左> 前の地図の取得元
<ctrl> + <カーソル 右> 次の地図の取得元
[マウス 左ボタン ドラッグ] タイルの矩形選択
mobile-atlas-creator-1.9.14+dfsg1/src/main/resources/mobac/resources/text/help_dialog.html0000644000175000017500000000201212122526606031462 0ustar paulliupaulliu

Keyboard & Mouse commands

F5 Refresh map display (reloads missing tiles)
<any cursor key> move map
[right mouse drag] move map
<ctrl> + <left mousebutton> move map (OS X only)
<ctrl> + <cursor up> zoom in
[left mouse double click] zoom in
[mouse scroll up] zoom in
<ctrl> + <cursor down> zoom out
[mouse scroll down] zoom out
<ctrl> + <cursor left> previous map source
<ctrl> + <cursor right> next map source
[left mouse drag] select area for download
mobile-atlas-creator-1.9.14+dfsg1/src/main/resources/mobac/resources/text/lgpl-3.0.txt0000644000175000017500000001674312122526606030342 0ustar paulliupaulliu GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. mobile-atlas-creator-1.9.14+dfsg1/src/main/resources/mobac/resources/text/help_dialog_fr.html0000644000175000017500000000255012150552674032165 0ustar paulliupaulliu

Commandes clavier & souris

F5 Rafraîchit l'affichage (recharge les dalles manquantes)
<flèches de direction> Déplace la carte
[Déplacement de la souris avec bouton gauche appuyé] Déplace la carte
<Ctrl> + <bouton gauche de la souris> Déplace la carte (OS X seulement)
<Ctrl> + <flèche vers le haut> Zoom +
[Double clic du bouton gauche de la souris] Zoom +
[Molette de la souris vers le haut] Zoom +
<Ctrl> + <flèche vers le bas> Zoom -
[Molette de la souris vers le bas] Zoom -
<Ctrl> + <flèche gauche> Source de carte précédente
<Ctrl> + <flèche droite> Source de carte suivante
[Déplacement de la souris avec bouton gauche appuyé] Sélectionne la zone à télécharger
mobile-atlas-creator-1.9.14+dfsg1/src/main/resources/mobac/resources/text/gpl.txt0000644000175000017500000004361612122526606027667 0ustar paulliupaulliuGNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License.mobile-atlas-creator-1.9.14+dfsg1/src/main/resources/mobac/resources/text/localize_ja_JP.properties0000644000175000017500000011634612171650636033335 0ustar paulliupaulliu#---------- Version ------------------------- mobac_version_subfix=多言語版 mobac_version_subfix_dev= #---------- Basic ------------------------- OK=確定 Cancel=キャンセル Close=閉じる Error=エラー Unnamed=名称未設定 Warning=警告 minute=分 minutes=分 second=秒 seconds=秒 Information=情報 Continue=続行 Abort=中断 Skip=スキップ Retry=再度 Undefined=未定義 Exit=終了 Bytes=バイト KiByte=キロバイト MiByte=メガバイト GiByte=ギガバイト #---------- On map controls ------------------------- map_ctrl_zoom_level_title=ズーム値 map_ctrl_zoom_level_title_tips=現在のズーム値 map_ctrl_zoom_grid_tips=グリッドの表示レベル map_ctrl_zoom_grid_prefix_fmt=グリッド値 : %d map_ctrl_zoom_grid_disable=グリッド 非表示 map_ctrl_wgs_grid_title=WGS 84 グリッド map_ctrl_wgs_grid_tips=WGS 84 グリッドの表示/非表示 map_ctrl_wgs_grid_density_tips=WGS 84 グリッドの表示密度 map_ctrl_wgs_grid_density_prefix= map_ctrl_wgs_grid_density_degree=° map_ctrl_wgs_grid_density_degrees=° map_ctrl_wgs_grid_density_minute=′ map_ctrl_wgs_grid_density_minutes=′ map_ctrl_wgs_grid_density_seconds=″ map_ctrl_wgs_grid_density_second=″ map_loading_wait=お待ちください - マップデータの読み込み中... #---------- Left Panel ------------------------- #coordinate lp_coords_title=選択範囲の座標値 (最大値/最小値) lp_coords_select_btn_title=座標の範囲を選択 lp_coords_label_N=北 lp_coords_label_E=東 lp_coords_label_W=西 lp_coords_label_S=南 lp_coords_fmt_list_title=単位 lp_coords_fmt_degree_eng=度 (英語) lp_coords_fmt_degree_local=度 lp_coords_fmt_degree_min_eng=度 分 (英語) lp_coords_fmt_degree_min_local=度 分 lp_coords_fmt_degree_min_sec_eng=度 分 秒 (英語) lp_coords_fmt_degree_min_sec_local=度 分 秒 lp_coords_fmt_tile=タイル ( X または Y 座標 / ズーム ) lp_coords_invalid_text=無効な座標値です!
%s と %s の間の数値を入力してください #map source lp_map_source_title=地図データの取得元 lp_map_source_combo_tips=地図データの取得元を選択します #zoom level lp_zoom_title=ズームレベル lp_zoom_total_tile_count_tips=ダウンロードされるタイルの総数 lp_zoom_number_tips=ズームレベル %d のタイルを取得します lp_zoom_total_tile_title=タイルの総数 : %s lp_zoom_total_tile_hint_head=ダウンロードされるタイルの総数 lp_zoom_total_tile_hint_row=
ズームレベル %d : %d (%dx%d) #Tile parameters settings lp_tile_param_title=レイヤ設定 (タイル処理設定) lp_tile_param_recreate_checkbox_title=タイルのサイズ変更とファイル形式変換 lp_tile_param_recreate_checkbox_tips=\ 有効化するとタイルのサイズ変更とファイル形式変換を実行します。
\ 作成する地図(アトラス)全体に同じ条件のタイル処理を適用したり、
\ レイヤやマップ毎に別条件のタイル処理を適用することもできます。
\ なお、この処理には CPU パワーが必要なので時間が掛かります。 lp_tile_param_width_title=幅 : lp_tile_param_width_tips=タイルの幅 lp_tile_param_height_title=高さ : lp_tile_param_height_tips=タイルの高さ lp_tile_param_image_fmt_title=ファイル形式 : lp_tile_param_image_fmt_png=PNG lp_tile_param_image_fmt_png_8bit=PNG 256 色 (8 ビット) lp_tile_param_image_fmt_png_4bit=PNG 16 色 (4 ビット) lp_tile_param_image_fmt_jpg_q100=JPEG - 品質 100 lp_tile_param_image_fmt_jpg_q99=JPEG - 品質 99 lp_tile_param_image_fmt_jpg_q95=JPEG - 品質 95 lp_tile_param_image_fmt_jpg_q90=JPEG - 品質 90 lp_tile_param_image_fmt_jpg_q85=JPEG - 品質 85 lp_tile_param_image_fmt_jpg_q80=JPEG - 品質 80 lp_tile_param_image_fmt_jpg_q70=JPEG - 品質 70 lp_tile_param_image_fmt_jpg_q60=JPEG - 品質 60 lp_tile_param_image_fmt_jpg_q50=JPEG - 品質 50 lp_tile_param_msg_valid_height=タイルの高さの許容範囲は %d 以上 %d 以下です。\n lp_tile_param_msg_valid_width=タイルの幅の許容範囲は %d 以上 %d 以下です。\n #atlas content lp_atlas_title=地図 (アトラス) lp_atlas_new_btn_title=新規作成 lp_atlas_add_selection_btn_title=選択範囲を地図に追加 lp_atlas_name_label_title=レイヤ名 : lp_atlas_name_field_tips=選択範囲を地図に追加する際のレイヤ名を入力します # this one only support English #lp_atlas_element_default_name=Layer name #atlas content detail - Atlas lp_atlas_info_atlas_title=アトラス
lp_atlas_info_atlas_name=名称 : %s
lp_atlas_info_atlas_layer=レイヤ数 : %d
lp_atlas_info_atlas_format=地図形式 : %s
lp_atlas_info_max_tile=最大タイル数 : %d
lp_atlas_info_area_start=開始座標 : %s %s
lp_atlas_info_area_end=終了座標 : %s %s
#atlas content detail - Layer lp_atlas_info_layer_title=レイヤ
lp_atlas_info_layer_map_count=マップ数 : %d
#atlas content detail - Map lp_atlas_info_map_title=矩形マップ
lp_atlas_info_polygon_map_title=ポリゴンマップ
lp_atlas_info_polygon_map_point=ポリゴンポイント :
lp_atlas_info_map_source_short=地図データ : %s
lp_atlas_info_map_source=地図データ : %s (%s)
lp_atlas_info_map_zoom_lv=ズームレベル : %d
lp_atlas_info_map_area_start=開始座標 : %s (%d / %d)
lp_atlas_info_map_area_end=終了座標 : %s (%d / %d)
lp_atlas_info_map_size=マップサイズ : %d x %d ピクセル
lp_atlas_info_tile_size=タイルサイズ : %d x %d
lp_atlas_info_tile_format=タイル形式 : %s
lp_atlas_info_tile_format_origin=タイル形式 : 256x256 (タイル処理なし)
#atlas content node pop menu lp_atlas_pop_menu_show_detail=詳細表示 lp_atlas_pop_menu_display_select_area=エリアを地図上に表示 lp_atlas_pop_menu_select_map_box=エリアを選択 lp_atlas_pop_menu_zoom_to_map_box=エリアをズーム表示 lp_atlas_pop_menu_zoom_to=ズーム表示 lp_atlas_pop_menu_rename=名称変更 lp_atlas_pop_menu_apply_tile_process=タイル処理の適用 lp_atlas_pop_menu_clear_atals=地図(アトラス)の消去 lp_atlas_pop_menu_delete_node=削除 lp_atlas_default_tip=右クリックでメニューを表示します #Profile lp_atlas_profile_title=プロファイル lp_atlas_profile_combo_tips=プロファイルを選択またはプロファイル名を入力します lp_atlas_profile_delete_btn_title=削除 lp_atlas_profile_delete_btn_tips=プロファイルを削除します lp_atlas_profile_save_btn_title=保存 lp_atlas_profile_save_btn_tips=プロファイルを保存します lp_atlas_profile_load_btn_title=読み込み lp_atlas_profile_load_btn_tips=プロファイルを読み込みます lp_atlas_profile_refresh_btn_tips=プロファイルリストを再読み込みします lp_atlas_profile_msg_ask_name=プロファイル名を入力してください lp_atlas_profile_msg_overwrite_confirm_title=確認 lp_atlas_profile_msg_overwrite_confirm=プロファイル %s は既に存在します。上書きしますか? #main button lp_mian_create_btn_title=地図(アトラス)の構築処理の実行 lp_main_create_btn_tips=地図データの取得元からタイルをダウンロードして
\地図(アトラス)の構築処理を実行します lp_main_setting_button_title=設定 lp_main_setting_button_tips=設定画面を開きます #tile store coverage lp_tile_store_title=タイル取得済みエリアの表示 lp_tile_store_title_tips=\ 選択した地図データの取得元について、
\ タイルを既に取得したエリアを表示します lp_tile_store_show_coverage_btn_title=表示 lp_tile_store_show_coverage_btn_tips=\ タイルを既に取得したエリアを表示します。
\ 緑色のエリアはタイル取得済みで、
\ 灰色のエリアはタイル未取得です。 lp_tile_store_hide_coverage_btn_title=非表示 lp_tile_store_zoom_combo_tips=タイル取得済みエリアを表示するズームレベルを選択します lp_tile_store_zoom_title=ズームレベル : lp_tile_store_layer_title=地図データ : #---------- GPX Panel ------------------------- rp_gpx_new_gpx=新規作成 rp_gpx_load_gpx=読み込み rp_gpx_save_gpx=保存 rp_gpx_clear_gpx=リストの消去 rp_gpx_add_wpt=ポイントの追加 rp_gpx_default_node_name=GPX ファイルの読み込み中... rp_gpx_pop_menu_delete_element=削除 rp_gpx_pop_menu_rename_element=名称変更 rp_gpx_menu_rename=名称変更 rp_gpx_menu_delete=削除 rp_gpx_msg_confim_delete_title=削除 rp_gpx_msg_confim_delete=本当に削除しますか? rp_gpx_rename_element_title=名称を入力してください : rp_gpx_msg_can_not_rename_track=トラックに名称を付けることはできません。 rp_gpx_msg_ask_create_new=GPX ファイルが選択されていません。\n作成しますか? rp_gpx_msg_ask_create_new_title=GPX ファイルにポイントを追加しますか? rp_gpx_msg_add_point_failed=ポイントの追加は、GPX ファイル, ルート, トラックに対してのみ可能です rp_gpx_root_default_name_nofile=新規 GPX rp_gpx_root_default_name_hasfile=ファイル %s rp_gpx_unname_route_name=ルート rp_gpx_unname_track_name=トラック rp_gpx_unname_wpt_name=ポイント rp_gpx_msg_confirm_reopen_file=一つ以上の GPX ファイルが既に読み込まれています。\nこれらのファイルを新たに読み込みますか? rp_gpx_msg_error_save_gpx_file=GPX ファイルの保存エラーが発生しました rp_gpx_msg_no_select_file=Gpx ファイルが選択されていません rp_gpx_node_seg_name=トラック %s #---------- Main Menu ------------------------- #Atlas menu_atlas=地図(アトラス) menu_atlas_new=地図(アトラス)の新規作成 menu_atlas_convert_format=地図形式の変更 menu_atlas_create=地図(アトラス)の構築処理の実行 #Maps menu_maps=タイル選択 menu_maps_selection=選択モード menu_maps_selection_rect=矩形選択 menu_maps_selection_polygon=ポリゴン選択 menu_maps_selection_circle=円形選択 menu_maps_selection_add=選択範囲を地図に追加 menu_maps_selection_add_by_gpx=GPX に基づいて地図に追加 #Bookmark menu_bookmark=ブックマーク menu_bookmark_save=地図の表示状態のブックマーク menu_bookmark_manage=ブックマークの管理 #Panels menu_panels=パネル menu_show_hide_left_panel=左パネルの表示/非表示 menu_show_hide_gpx_panel=右パネルの表示/非表示 #Debug menu_debug=Debug menu_debug_show_hide_tile_border=タイルの境界線の表示/非表示 menu_debug_show_all_map_source=地図データの取得元のリスト表示 menu_debug_refresh_map_source=地図データの取得元の再読み込み menu_debug_show_log_file=ログファイルの表示 menu_debug_log_level=ログレベルの変更 menu_debug_system_report=システムレポートの作成 #help menu_help=ヘルプ menu_help_readme=Readme の表示 menu_help_how_to_preview=キーボードとマウスによる操作 menu_help_licenses=ライセンス menu_help_about=このソフトウェアについて #tools menu_tool=ツール #---------- Dialog ------------------------- #About dlg_about_title=このソフトウェアについて dlg_about_version=バージョン : dlg_about_program_version=リビジョン : dlg_about_download_mapplus=Map Plus のダウンロード dlg_about_download_mapplus_url=http://itunes.apple.com/us/app/map-plus/id438868200?mt=8&ls=1 #Font choose dlg_font_choose_title=フォントの選択 dlg_font_choose_preview=プレビュー dlg_font_choose_name=名称 dlg_font_choose_style=スタイル dlg_font_choose_size=サイズ #Licenses dlg_license_title=ライセンス #Help dlg_help_title=ヘルプ #Manager Bookmark dlg_mgn_bookmark_title=ブックマークの管理 dlg_mgn_bookmark_delete=ブックマークの削除 #Bookmark Add dlg_add_bookmark_msg=ブックマーク名を入力してください #New Atlas dlg_new_atlas_title=地図(アトラス)の設定 dlg_new_atlas_name_title=地図(アトラス)の名称 dlg_new_atlas_default_atlas_name=アトラス dlg_new_atlas_select_format_title=地図形式を選択してください #Working Progress dlg_progress_title=進捗状況 dlg_progress_about_btn=アバウト dlg_progress_count=カウント : 0 dlg_progress_count_i=カウント : %d #Select GPX Track dlg_gpx_track_select_title=幅の設定 dlg_gpx_track_select_distance=トラックに沿って選択するエリアの幅 : %d %s #Add GPS point dlg_gpx_inpu_point_name=ポイントの名称を入力してください : #Show All Map Source dlg_show_source_title=地図データの取得元のリスト dlg_show_source_column_name=名称 dlg_show_source_column_display_text=表示テキスト dlg_show_source_column_rev=リビジョン dlg_show_source_column_type=タイプ #Select Dir dlg_select_dir_title=フォルダの選択 dlg_select_dir_description=フォルダ #Atlas download progress dlg_download_title=地図(アトラス)の作成中... dlg_download_zoom_level_progress=タイル取得 : ズームレベル dlg_download_map_progress=マップ処理 dlg_download_atlas_progress=%d%% 実行中 - 名称 "%s", 地図形式 "%s" の処理中 dlg_download_done_percent=%d%% dlg_download_done_tenthpercent=%.1f%% dlg_download_window_title=

地図(アトラス)の作成中...

dlg_download_map_info_label_default=Processing map ABCDEFGHIJKLMNOPQRSTUVWXYZ-nn of layer ABCDEFGHIJKLMNOPQRSTUVWXYZ from map source ABCDEFGHIJKLMNOPQRSTUVWXYZ dlg_download_map_info_label=処理中 : マップ %s , レイヤ %s , 地図データ %s dlg_download_map_done_count_default=000 of 000 done dlg_download_map_done_count=%d / %d dlg_download_remain_time_default=Time remaining: 00000 minutes 00 seconds dlg_download_remain_time=残り時間 : %s dlg_download_tile_done_count_default=1000000 of 1000000 tiles done dlg_download_tile_done_count=%d / %d タイル dlg_download_map_create_title=地図(アトラス)の構築 dlg_download_avg_speed=平均 DL 速度 dlg_download_avg_speed_value=: %s / 秒 dlg_download_total_bytes=ダウンロード dlg_download_bytes_from_cache=保管タイルの読込 dlg_download_thread_count=DL スレッド数 dlg_download_retry_count=一時的エラー dlg_download_retry_count_value=: 処理中: %d, 全体: %d dlg_download_failed_count=修復不能エラー dlg_download_failed_count_value=: 処理中: %d, 全体: %d dlg_download_error_tips=

処理中のマップと地図全体におけるダウンロードの一時的エラーと修復不能エラー

\

Mobile Atlas Creator はタイルのダウンロードの失敗を一時的エラーとして扱い、
\ さらにタイルの再ダウンロードにも失敗すると修復不能エラーとして扱います。
\ この場合、現在の地図作成中に再びダウンロードを試みることはありません。

dlg_download_total_time=所要時間 dlg_download_checkbox_ignore_error=ダウンロードエラーを無視して処理を続行する dlg_download_status_title=状態 : dlg_download_status_running=処理中 dlg_download_status_aborted=中断 dlg_download_status_finished=終了 dlg_download_status_paused=停止 dlg_download_btn_abort=処理中断 dlg_download_btn_abort_tips=地図(アトラス)作成を中断します dlg_download_btn_close_win=ウィンドウを閉じる dlg_download_btn_close_win_tips_disable=地図(アトラス)の作成中... dlg_download_btn_close_win_tips_enable=地図作成の進捗状況表示ウィンドウを閉じる dlg_download_btn_open_folder=地図(アトラス)フォルダを開く dlg_download_btn_open_folder_tips_disabled=地図(アトラス)の作成中... dlg_download_btn_open_folder_tips_enabled=地図(アトラス)が作成されたフォルダを開く dlg_download_btn_pause_resume=停止/再開 dlg_download_time_unknown=不明 dlg_download_abort_title=地図(アトラス)の作成を中断しました dlg_download_abort_window_title=

ユーザーにより地図(アトラス)の作成が中断されました

dlg_download_succeed_title=地図(アトラス)の作成に成功しました dlg_download_succeed_window_title=

地図(アトラス)の作成に成功しました

dlg_download_errors_todo=ダウンロードエラーが多数発生しました - 続行しますか? dlg_download_errors_todo_msg=複数のタイルのダウンロードに失敗しました。\ サーバーへの接続またはエリアの選択に問題があると思われます。\
どうしますか? :

\ エラーを無視してダウンロードを 続行 する。(タイルに空白部分が生じます)
\ ダウンロードを 再試行 する。?
\ 現在のマップを スキップ して他のマップの構築処理を続行する。
\ 地図(アトラス)の構築処理を 中断 する。
dlg_download_errors_missing_tile=エラー - タイルがありません - とにかく続行しますか? dlg_download_errors_missing_tile_msg=タイルのダウンロードに問題があります。\n\ タイルのダウンロード数が試算したほど多くありません。\nしたがって、構築した地図(アトラス)ではタイルの不足があると思われます。\n タイルの不足数は %d です。\n\n\ とにかく続行して地図(アトラス)を構築しますか? dlg_download_show_error_report=エラーレポートの表示 dlg_download_erro_head=エラーが発生しました : #Splash Frame splash_title=Mobile Atlas Creator の起動中... #---------- Setting ------------------------- set_title=設定 #Display set_display_title=表示 set_display_unit_system_title=単位系 set_display_unit_system_metric=キロメートル・メートル set_display_unit_system_imperial=マイル・フィート set_display_unit_system_scale_bar=距離目盛りの単位 : set_display_language=言語 set_display_language_choose=言語の選択 : set_display_language_choose_tips=言語を選択します。その後 MOBAC を再起動してください set_display_language_restart_desc=言語を変更した後は MOBAC の再起動が必要です set_display_language_msg_title=再起動の要求 set_display_language_msg=言語の変更を有効にするには MOBAC を再起動してください set_display_grid=WGS 84 グリッド set_display_grid_compress=ラベルの短縮表示 set_display_grid_compress_tips=有効にすると、座標ラベルが短縮して表示されます set_display_grid_title=グリッドの色の選択 set_display_grid_width=幅 : set_display_grid_width_tips=グリッド線の幅を指定します set_display_grid_color=色 : set_display_grid_color_tips=グリッド線と座標ラベルの色を選択します set_display_grid_font=フォント : set_display_grid_font_tips=座標ラベルに使用するフォントを選択します #Map sources config set_mapsrc_config_title=地図パック set_mapsrc_config_online_update=地図パックのオンライン更新 set_mapsrc_config_online_update_btn=オンライン更新の実行 set_mapsrc_config_online_update_no_update=更新はありません set_mapsrc_config_online_update_done=更新をダウンロードしました set_mapsrc_config_online_update_failed=更新に失敗しました set_mapsrc_config_online_update_msg_outdate=このバージョンの MOBAC ではオンライン更新がサポートされません。\ MOBAC 最新のバージョンを使用してください set_mapsrc_config_online_update_msg_noneed=最新の地図パックが既にインストールされています set_mapsrc_config_online_update_msg_done=地図パックが更新されました : %d\n\ 更新をインストールするには MOBAC を再起動してください set_mapsrc_config_osmhiking=Reit- und Wanderkarte ($Abo) set_mapsrc_config_osmhiking_purchased=購入済みチケットの ID: set_mapsrc_config_osmhiking_howto=チケットの取得方法 (ドイツ語) set_mapsrc_config_osmhiking_howto_url=http://www.wanderreitkarte.de/shop_abo_de.php #Map sources set_mapsrc_mgr_title=地図データ set_mapsrc_mgr_title_enabled=有効 set_mapsrc_mgr_title_disabled=無効 set_mapsrc_mgr_move_up_tips=選択した地図を一つ上に移動します set_mapsrc_mgr_move_down_tips=選択した地図を一つ上に移動します set_mapsrc_mgr_move_left_tips=選択した地図を有効化します set_mapsrc_mgr_move_right_tips=選択した地図を無効化します #Tile Update set_tile_update_title=タイルの更新 set_tile_update_desc=タイルは、設定した有効期限に基づいて自動的に更新されます。\ タイルには、ときにサーバーで指定されている
有効期限があります。\ もしサーバーで有効期限が指定されていない場合はデフォルトの有効期限が適用されます。

set_tile_update_default_expiration=デフォルトの有効期限 set_tile_update_default_expiration_desc=デフォルトの有効期限は、タイルの有効期限が地図データの取得元で指定されていない場合に適用されます。 set_tile_update_max_expiration=最長有効期限 set_tile_update_min_expiration=最短有効期限 #Tile Store set_tile_store_title=タイルの保管 set_tile_store_enable_checkbox=タイルの保管を有効にして、地図のプレビューとダウンロードに使用する set_tile_store_settings=タイルの保管設定 set_tile_store_information=情報 set_tile_store_info_mapsrc=地図データの取得元 set_tile_store_info_tiles=タイル数 set_tile_store_info_size=容量 set_tile_store_info_disabled_subfix= (未使用) set_tile_store_info_delete_tips=%s のタイルを全削除します set_tile_store_info_deleteing_tips=削除しています - しばらくお待ちください set_tile_store_info_total=合計 #Map Size set_map_size_title=マップサイズ set_map_size_settings=マップサイズの設定 set_map_size_max_size_of_rect=マップの最大サイズ (幅と高さ) : set_map_size_overlap_tiles=マップの重複部分のタイル数 : set_map_size_desc=\ 矩形選択エリアの幅や高さがマップの最大サイズを超える場合、\ 地図に追加する際に複数のマップに分割されます。
\ 各マップは最大サイズより大きくなりません。\ ポリゴンで選択したマップには適用されないことに注意してください!
\ マップの数とマップのエリアは地図(アトラス)のツリー表示で確認できます。
\ 選択範囲を地図に追加した後で最大サイズを変更しても効果はありません。

\ TrekBuddy ユーザーへの注意 :
\ バージョン 0.9.88 以前の TrekBuddy では 32767 より大きいマップサイズをサポートしていません。
\ これより新しいバージョンでは、最大でサイズが 1048575 のマップを取り扱えます。 #Directory set_directory_title=フォルダ set_directory_output=地図(アトラス)の出力フォルダ set_directory_output_tips=空欄の場合はデフォルトのフォルダに出力されます :
%s set_directory_output_select=選択 set_directory_output_select_dlg_title=フォルダを選択 #Network set_net_title=ネットワーク set_net_connection=ネットワーク接続 set_net_connection_desc=タイルのダウンロード時の並列ネットワーク接続数 set_net_bandwidth_desc=タイルのダウンロードの帯域制限 set_net_bandwidth_unlimited=無制限 set_net_proxy=HTTP プロキシ set_net_proxy_settings=プロキシ設定: set_net_proxy_settings_java=Java の標準プロキシ設定を使用する set_net_proxy_settings_application=アプリケーションの設定を使用する set_net_proxy_settings_custom=(ユーザーが定義した)カスタムプロキシを使用する set_net_proxy_settings_custom_auth=認証カスタムプロキシを使用する set_net_proxy_host=ホスト名 : set_net_proxy_port=ポート : set_net_proxy_username=ユーザー名 : set_net_proxy_password=パスワード : set_net_default=デフォルト set_net_default_ignore_error=ダウンロードエラーを無視して自動的に続行する #Paper Atlas set_paper_title=ペーパーアトラス #Paper Atlas - Size set_paper_size=サイズ set_paper_size_default=デフォルト set_paper_size_default_tips=ページサイズを規定値から選択します set_paper_size_default_format_tips=ページサイズを選択します set_paper_size_default_landscape=ランドスケープ set_paper_size_default_landscape_tips=用紙方向をランドスケープ(横置き)にします set_paper_size_custom=カスタム set_paper_size_custom_tips=任意のページサイズを指定します set_paper_size_custom_width=幅 : set_paper_size_custom_width_tips=ページの幅 set_paper_size_custom_height=高さ : set_paper_size_custom_height_tips=ページの高さ set_paper_size_selection=地図全体 set_paper_size_selection_tips=地図全体を1ページにします #Paper Atlas - Additions set_paper_additions=追加の項目 set_paper_wgs_grid=WGS 84 グリッド set_paper_wgs_grid_tips=WGS 84 グリッドを表示します set_paper_wgs_grid_density_tips=WGS 84 グリッドの表示密度を選択します set_paper_paper_nubmer=ページ番号 set_paper_paper_nubmer_tips=ページ番号を表示します set_paper_scale_bar=距離目盛り set_paper_scale_tips=距離目盛りを表示します set_paper_compass=コンパス set_paper_compass_tips=コンパスを表示します #Paper Atlas - Margins set_paper_margins=マージン set_paper_margins_tips=マージンを指定します set_paper_margins_top=上 : set_paper_margins_left=左 : set_paper_margins_bottom=下 : set_paper_margins_right=右 : #Paper Atlas - Advanced set_paper_advanced=詳細設定 set_paper_advanced_compression=圧縮レベル set_paper_advanced_compression_tips=PDF ファイルに使用する圧縮レベルを指定します。
圧縮レベル 0 は無圧縮で、圧縮レベルの数値が大きいほど高圧縮となり、
圧縮レベル 9 が最高値です。デフォルトの圧縮レベルは 6 です。 set_paper_advanced_dpi=解像度 set_paper_advanced_dpi_tips=画像の解像度(DPI)を指定します。
一般的に数値が大きいほど高品質になりますが、
グリッドや距離目盛り等が小さく表示されます。
デフォルトの解像度は 96 DPI で、
120 DPI の指定でより高品質になります。 set_paper_advanced_overlap=のりしろ set_paper_advanced_overlap_tips=隣接ページとの重ね合わせ部分(のりしろ)のサイスを指定します set_paper_advanced_crop=クロップ set_paper_advanced_crop_tips=\ クロップ率を指定します。地図の周辺部が表示されるページにおいて、
\ ページ面積に対する地図の表示面積がクロップ割合より小さい場合、
\ このページを地図の構築処理に使用しないようにします。 #Paper Atlas - Actions set_paper_actions=設定のインポートとエクスポート set_paper_actions_import_xml=XML ファイルをインポート set_paper_actions_import_xml_tip=ペーパーアトラスの設定を XML ファイルからインポートします set_paper_actions_export_xml=XML ファイルにエクスポート set_paper_actions_export_xml_tip=ペーパーアトラスの設定を XML ファイルにエクスポートします set_paper_actions_restore_default=デフォルト値にリセット set_paper_actions_restore_default_tips=ペーパーアトラスの各設定をデフォルト値に戻します。
\ 以前の変更は失われます。 set_paper_actions_error_import=ペーパーアトラスの設定をインポートできません : set_paper_actions_error_export=ペーパーアトラスの設定をエクスポートできません : set_paper_actions_error_reason=理由 : set_paper_actions_error_title=エラー発生! set_paper_actions_xml_filter=XML ファイル (*.xml) #Error set_error_saving_title=設定の保存エラー set_error_saving_msg=設定の保存エラー :\n ( %s ) #---------- Message ------------------------- #common msg_no_zoom_level_selected=ズームレベルが選択されていません msg_no_select_area=タイルを選択してください #Add GPX Track Polygon msg_add_gpx_polygon_too_many_track=選択された GPX ファイルには複数のトラックが含まれています。\n必要なトラックまたはトラックセグメントを選択してください。 msg_add_gpx_polygon_too_many_segment=選択されたトラックには複数のトラックセグメントが含まれています。\n必要なトラックセグメントを選択してください。 msg_add_gpx_polygon_no_select=GPX トラックが選択されていません x=最大マップサイズを超えています msg_add_gpx_polygon_maxsize=少なくとも一つのマップが最大サイズを超えています。\n\ ポリゴンマップを小さく分割する機能はまだサポートされていません。\n\n構わずに続行しますか? #Convert Atlas msg_convert_atlas_format=地図形式の変更 msg_convert_incompatible_format=このマップは地図形式と互換性がありません #Log file msg_no_log_file_config=ファイルロガーが設定されていません msg_no_log_file=ログファイルがありません :

%s #Setting msg_settings_write_error=プログラム設定を "settings.xml" に書き込む際にエラーが発生しました #Refresh msg_refresh_all_map_source_done=地図データの取得元を再読み込みしました : %d ファイル #Help msg_no_found_readme_file=README.HTM が見つかりません #Merge Layer msg_confirm_merge_layer_title=レイヤの統合の確認 msg_confirm_merge_layer=本当にレイヤ %s をレイヤ %s に統合しますか? msg_merge_layer_failed=レイヤの統合に失敗しました #Tile Size select msg_invalid_tile_size=無効なタイルサイズです!
%d と %d の間の数値を入力してください #Tile Store Coverage msg_tile_store_failed_retrieve_coverage=タイルを既に取得したエリアのデータ収集に失敗しました。\n\ おそらく選択範囲とズームレベルが大きすぎます。 #Atlas download thread msg_out_of_memory_title=メモリ不足 msg_out_of_memory_head=Mobile Atlas Creator の実行に必要なメモリが不足しています。 msg_out_of_memory_detail=\nMOBAC に割り当てられたメモリの最大値は %d MB です msg_atlas_download_abort=地図(アトラス)のダウンロードを中断しました msg_too_many_tiles_title=ダウンロードの差し止め msg_too_many_tiles_msg=膨大な量のタイルがダウンロードされることを Mobile Atlas Creator が検知しました。\n\ 高いズームレベルでの選択エリアを削減してから再試行してください。\n\ 地図(アトラス)に許容されるタイル数の最大値は %d です。\n\ 現在の地図(アトラス)に含まれるタイル数 : %d msg_atlas_version_mismatch=読み込まれたアトラスは古いバージョンの Mobile Atlas Creator のものです。\n\ この古いバージョンでは現在のバージョンと互換性のないプロファイル形式が使用されています。\n\n\ 読み込んだアトラスを消去すると共に影響が及んだプロファイルを削除することをおすすめします。\n\ そうしないと、このアトラスで作業している間に様々な例外が発生します。 msg_atlas_data_check_failed=保存されたプロファイルの読み込み中に少なくとも一つの問題が検出されました。\n\ 通常これはプロファイルに互換性がないかファイル形式が変更されたことを示唆します。\n\n\ 読み込んだアトラスを消去すると共に影響が及んだプロファイルを削除することをおすすめします。\n\ そうしないと、このアトラスで作業している間に様々な例外が発生します。 #Settings msg_setting_file_is_changed_by_other_title=変更の上書き msg_setting_file_is_changed_by_other=settings.xml ファイルが他のアプリケーションから変更されました。\n\ これらの変更を上書きしますか?\n\ 他のアプリケーションによる変更点はすべて失われます! msg_settings_file_can_not_parse=settings.xml ファイルを読み込むことができません。プログラムを終了します。 #Others msg_atlas_is_empty=地図(アトラス)に選択範囲が追加されていません。 - 少なくとも一つの選択範囲を地図(アトラス)に追加してください msg_environment_not_support_title=サポート外の環境 msg_environment_not_support=この環境はサポートされていません。
デスクトップ : %s
オペレーティングシステム : %s msg_environment_failed_open_output_title=出力フォルダのオープンエラー msg_environment_failed_open_output=地図(アトラス)の出力フォルダのオープンに失敗しました。
msg_environment_use_commond=
使用コマンド : %s
msg_environment_commond_param=パラメーター : %d : %s msg_environment_lack_memory_title=警告 : メモリ不足 msg_environment_lack_memory=警告 : メモリの割り当てが非常に少ない状態で Mobile Atlas Creator が起動されました。
\ 現在 Mobile Atlas Creator が使用できるメモリの最大値は %s です。

\ 今後 Mobile Atlas Creator を起動する際は、\ Windows では Mobile Atlas Creator.exe から起動するか、
\ Linux/Unix/OSX では start.sh から起動するか、\ -Xmx 512M パラメーターをコマンドに追加してください。

\ 例 : java -Xmx512M -jar Mobile_Atlas_Creator.jar
\
Mobile Atlas Creator の起動を続行するには OK ボタンを押してください
msg_environment_error_create_dir=%s フォルダの作成エラーが発生しました。\nプログラムを終了します。 msg_environment_error_write_file=%s に書き込むことができません。\n %s \n フォルダ\n ファイルのパーミッションを修正してから MOBAC を再度起動してください。 msg_environment_error_create_setting=settings.xml ファイルを作成できませんでした。- プログラムを終了します。 msg_environment_error_init_mapsrc_dir=mapsources フォルダの初期化でエラーが発生しました :\n msg_environment_error_load_cloudmade=CloudMade のカスタムマップソースを読み込むことができません。openstreetmap のマップソースバンドルが利用可能であることを確認してください。 msg_environment_mapsrc_dir_not_exist=mapsources フォルダが存在しません。 - フォルダパス :\n %s \n\ MOBAC の zip ファイルがサブフォルダを含めて適切に展開されていることを確認してください! msg_environment_unable_to_start=Mobile Atlas Creator を起動できません : \n msg_environment_jre_bellow=使用中の Java Runtime Environment は最小限の要求を満たしていません。\n\ Mobile Atlas Creator は少なくとも Java 6 (1.6) またはそれ以上を必要とします。\n\ Mobile Atlas Creator を起動する前に Java Runtime を更新してください。\n\n\ 検出された Java Runtime のバージョン : %@ msg_environment_jre_bellow_title=Java Runtime バージョンの問題検出 msg_environment_invalid_source_folder=指定された mapsources フォルダが存在しません :\n地図の名称 : %s\ \nmapources フォルダ: %s msg_environment_invalid_source_folder_zoom=ズームフォルダが見つかりません :\n地図の名称 : %s\ \nmapsources フォルダ : %s msg_environment_invalid_source_folder_title=不正な mapsources フォルダ msg_tools_exec_command_ask=実行されるコマンド :
%s msg_tools_exec_command_ask_title=コマンドの実行 msg_custom_map_invalid_source_file_title=不正なソースファイル msg_custom_map_invalid_source_file=データベースファイルが指定されていません。\n地図の名称 : %s \nファイル名 : %s msg_custom_map_invalid_source_zip_title=不正なソース zip ファイル msg_custom_map_invalid_source_zip=指定されたソース zip ファイルが存在しません :\n地図の名称 : %s \nZip ファイル : %s msg_custom_map_failed_open_source_zip_title=zip ファイルの読み込みエラー msg_custom_map_failed_open_source_zip=指定されたソース zip ファイルを読み込むことができません :\n地図の名称 : %s \nZip ファイル : %s msg_custom_map_invalid_source_sqlitedb=指定されたソース sqlite データベースファイルが存在しません :\n地図の名称 : %s \nファイル名 : %s msg_custom_map_source_failed_load_sqlitedb_title=データベースの読み込みエラー msg_custom_map_source_failed_load_sqlitedb=指定されたソース sqlite データベースファイルを読み込むことができません :\n地図の名称 : %s\ \nファイル名 : %s \nエラー : %s msg_update_map_pack_error_title=更新された地図パックの読み込みエラー msg_update_map_pack_error=更新された地図パックのインストール中にエラーが発生しました。前のバージョンをリストアするには MOBAC を再起動してください。 msg_error_load_atlas_profile_title=アトラスの読み込みエラー - 読み込みを続行しますか? msg_error_load_atlas_profile=アトラスの読み込みエラー :
 %s 
\
ファイル : %s 行/カラム : %d / %d
\ 現在のアトラスの読み込みを続行しますか?
\ 読み込みを続行するとアトラスが不完全または機能不全になるかもしれません。
msg_environment_slqite_lib_missing_title="エラー - SQLite が使用できません" msg_environment_slqite_lib_missing=SQLite ライブラリが見つかりません。\ 現在選択されている地図(アトラス)形式に必要です。
\ README.HTM の "SQLite アトラス形式" の項目を参照してください。 msg_environment_image_format_not_available_title=画像形式が利用できません - ライブラリが見つかりません msg_environment_image_format_not_available=この画像形式には追加ライブラリがインストールされている必要があります :
\ Java Advanced Image library (jai_core.jar と jai_codec.jar)
\ 詳細は README.HTM ファイルの\ Requirements の項目を参照してください。 msg_tile_store_access_conflict_title=Mobile Atlas Creator の複数起動 msg_tile_store_access_conflict=複数の Mobile Atlas Creator が\ 同じタイル保管フォルダにアクセスしようとしています。\n\ タイル保管フォルダは一度に一つの Mobile Atlas Creator からのみ使用できます。\n\ 他の Mobile Atlas Creator を終了してから再試行してください。 mobile-atlas-creator-1.9.14+dfsg1/src/main/resources/mobac/resources/text/agpl.txt0000644000175000017500000010032712122526606030021 0ustar paulliupaulliuGNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU Affero General Public License is a free, copyleft license for software and other kinds of works, specifically designed to ensure cooperation with the community in the case of network server software. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, our General Public Licenses are intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. Developers that use our General Public Licenses protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License which gives you legal permission to copy, distribute and/or modify the software. A secondary benefit of defending all users' freedom is that improvements made in alternate versions of the program, if they receive widespread use, become available for other developers to incorporate. Many developers of free software are heartened and encouraged by the resulting cooperation. However, in the case of software used on network servers, this result may fail to come about. The GNU General Public License permits making a modified version and letting the public access it on a server without ever releasing its source code to the public. The GNU Affero General Public License is designed specifically to ensure that, in such cases, the modified source code becomes available to the community. It requires the operator of a network server to provide the source code of the modified version running there to the users of that server. Therefore, public use of a modified version, on a publicly accessible server, gives the public access to the source code of the modified version. An older license, called the Affero General Public License and published by Affero, was designed to accomplish similar goals. This is a different license, not a version of the Affero GPL, but Affero has released a new version of the Affero GPL which permits relicensing under this license. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU Affero General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Remote Network Interaction; Use with the GNU General Public License. Notwithstanding any other provision of this License, if you modify the Program, your modified version must prominently offer all users interacting with it remotely through a computer network (if your version supports such interaction) an opportunity to receive the Corresponding Source of your version by providing access to the Corresponding Source from a network server at no charge, through some standard or customary means of facilitating copying of software. This Corresponding Source shall include the Corresponding Source for any work covered by version 3 of the GNU General Public License that is incorporated pursuant to the following paragraph. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the work with which it is combined will remain governed by version 3 of the GNU General Public License. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU Affero General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU Affero General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU Affero General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU Affero General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONSmobile-atlas-creator-1.9.14+dfsg1/src/main/resources/mobac/resources/text/localize_fr_FR.properties0000644000175000017500000011260512167237332033341 0ustar paulliupaulliu#---------- Version ------------------------- mobac_version_subfix=International Edition mobac_version_subfix_dev= #---------- Basic ------------------------- OK=OK Cancel=Annuler Close=Fermer Error=Erreur Unnamed=Sans nom Warning=Attention minute=minute minutes=minutes second=seconde seconds=secondes Information=Information Continue=Continuer Abort=Interrompre Skip=Passer Retry=Réessayer Undefined=Indéfini Exit=Quitter Bytes=Octets KiByte=KiOctet MiByte=MiOctet GiByte=GiOctet #---------- On map controls ------------------------- map_ctrl_zoom_level_title= Zoom : map_ctrl_zoom_level_title_tips=Niveau de zoom actuel map_ctrl_zoom_grid_tips=Affiche une grille du niveau de zoom demandé sur la carte map_ctrl_zoom_grid_prefix_fmt=Niveau de zoom %d map_ctrl_zoom_grid_disable=Grille désactivée map_ctrl_wgs_grid_title=Grille WGS 84 map_ctrl_wgs_grid_tips=Affiche une grille WGS 84 sur l'aperçu de la carte (non incluse dans l'atlas) map_ctrl_wgs_grid_density_tips=Indique le pas de la grille WGS 84 map_ctrl_wgs_grid_density_prefix=Pas de map_ctrl_wgs_grid_density_degree=degré map_ctrl_wgs_grid_density_degrees=degrés map_ctrl_wgs_grid_density_minute=minute map_ctrl_wgs_grid_density_minutes=minutes map_ctrl_wgs_grid_density_seconds=secondes map_ctrl_wgs_grid_density_second=seconde map_loading_wait=Patientez SVP - chargement des cartes en cours #---------- Left Panel ------------------------- #coordinate lp_coords_title=Coordonnées de la sélection (min/max) lp_coords_select_btn_title=Valider les coordonnées lp_coords_label_N=N lp_coords_label_E=E lp_coords_label_W=O lp_coords_label_S=S lp_coords_fmt_list_title=Fmt lp_coords_fmt_degree_eng=Degrés (anglais) lp_coords_fmt_degree_local=Degrés (local) lp_coords_fmt_degree_min_eng=Deg Min (anglais) lp_coords_fmt_degree_min_local=Deg Min (local) lp_coords_fmt_degree_min_sec_eng=Deg Min Sec (anglais) lp_coords_fmt_degree_min_sec_local=Deg Min Sec (local) lp_coords_fmt_tile=Dalle (x ou y / zoom) lp_coords_invalid_text=Coordonnée invalide !
Tapez un nombre entre %s et %s #map source lp_map_source_title=Source de carte lp_map_source_combo_tips=Sélectionne une source de carte #zoom level lp_zoom_title=Niveaux de zoom lp_zoom_total_tile_count_tips=Nombre total de dalles à télécharger lp_zoom_number_tips=Sélectionne le niveau de zoom %d de l'atlas lp_zoom_total_tile_title=%s dalles lp_zoom_total_tile_hint_head=Nombre total de dalles à télécharger: lp_zoom_total_tile_hint_row=
Niveau %d : %d (%dx%d) #Tile parameters settings lp_tile_param_title=Paramètres de la couche : modification des dalles lp_tile_param_recreate_checkbox_title=Recréer/ajuster les dalles (calculs intensifs) lp_tile_param_recreate_checkbox_tips=Si cette option est inactive, chaque dalle (taille : 256x256) est utilisée exactement comme téléchargée (plus rapide).
\ Sinon chaque nouvelle dalle est recréée, ce qui permet d'utiliser une taille de dalle personnalisée (plus lent / calculs intensifs). lp_tile_param_width_title=Largeur : lp_tile_param_width_tips=Largeur des dalles lp_tile_param_height_title=Hauteur : lp_tile_param_height_tips=Hauteur des dalles lp_tile_param_image_fmt_title=Format des dalles : lp_tile_param_image_fmt_png=PNG lp_tile_param_image_fmt_png_8bit=PNG 256 couleurs (8 bits) lp_tile_param_image_fmt_png_4bit=PNG 16 couleurs (4 bits) lp_tile_param_image_fmt_jpg_q100=JPEG - qualité 100 lp_tile_param_image_fmt_jpg_q99=JPEG - qualité 99 lp_tile_param_image_fmt_jpg_q95=JPEG - qualité 95 lp_tile_param_image_fmt_jpg_q90=JPEG - qualité 90 lp_tile_param_image_fmt_jpg_q85=JPEG - qualité 85 lp_tile_param_image_fmt_jpg_q80=JPEG - qualité 80 lp_tile_param_image_fmt_jpg_q70=JPEG - qualité 70 lp_tile_param_image_fmt_jpg_q60=JPEG - qualité 60 lp_tile_param_image_fmt_jpg_q50=JPEG - qualité 50 lp_tile_param_msg_valid_height=La hauteur de la dalle doit être comprise entre %d et %d.\n lp_tile_param_msg_valid_width=La largeur de la dalle doit être comprise entre %d et %d.\n #atlas content lp_atlas_title=Contenu de l'atlas lp_atlas_new_btn_title=Nouveau lp_atlas_add_selection_btn_title=Ajouter la sélection lp_atlas_name_label_title=Nom : lp_atlas_name_field_tips=Tapez le nom de l'atlas ici # this one only support English #lp_atlas_element_default_name=Layer name #atlas content detail - Atlas lp_atlas_info_atlas_title=Atlas
lp_atlas_info_atlas_name=Nom : %s
lp_atlas_info_atlas_layer=Nombre de couches : %d
lp_atlas_info_atlas_format=Format de l'atlas : %s
lp_atlas_info_max_tile=Nombre maximal de dalles à télécharger : %d
lp_atlas_info_area_start=Début de la zone : %s %s
lp_atlas_info_area_end=Fin de la zone : %s %s
#atlas content detail - Layer lp_atlas_info_layer_title=Couche
lp_atlas_info_layer_map_count=Nombre de couches de cartes : %d
#atlas content detail - Map lp_atlas_info_map_title=Carte
lp_atlas_info_polygon_map_title=Sélection polygonale
lp_atlas_info_polygon_map_point=Points du polygone :
lp_atlas_info_map_source_short=Source de la carte : %s
lp_atlas_info_map_source=Source de la carte : %s (%s)
lp_atlas_info_map_zoom_lv=Niveau de zoom : %d
lp_atlas_info_map_area_start=Début de la zone : %s (%d / %d)
lp_atlas_info_map_area_end=Fin de la zone : %s (%d / %d)
lp_atlas_info_map_size=Taille de la carte : %d x %d pixels
lp_atlas_info_tile_size=Taille des dalles : %d x %d
lp_atlas_info_tile_format=Format des dalles : %s
lp_atlas_info_tile_format_origin=Format des dalles : 256x256 (pas de traitement)
#atlas content node pop menu lp_atlas_pop_menu_show_detail=Afficher les détails lp_atlas_pop_menu_display_select_area=Afficher les zones sélectionnées lp_atlas_pop_menu_select_map_box=Choisir l'étendue de la carte lp_atlas_pop_menu_zoom_to_map_box=Zoomer sur l'étendue de la carte lp_atlas_pop_menu_zoom_to=Zoomer sur lp_atlas_pop_menu_rename=Renommer lp_atlas_pop_menu_apply_tile_process=Valider les options de traitement des dalles lp_atlas_pop_menu_clear_atals=Effacer l'atlas lp_atlas_pop_menu_delete_node=Supprimer lp_atlas_default_tip=Utiliser le menu contextuel des options pour voir toutes les commandes disponibles. #Profile lp_atlas_profile_title=Profils sauvegardés lp_atlas_profile_combo_tips=Sélectionnez un profil de création de l'atlas\n ou tapez le nom du nouveau profil lp_atlas_profile_delete_btn_title=Supprimer lp_atlas_profile_delete_btn_tips=Supprime un profil d'atlas lp_atlas_profile_save_btn_title=Enregistrer lp_atlas_profile_save_btn_tips=Enregistre un profil d'atlas lp_atlas_profile_load_btn_title=Charger lp_atlas_profile_load_btn_tips=Charge le profil sélectionné lp_atlas_profile_refresh_btn_tips=Recharge la liste des profils lp_atlas_profile_msg_ask_name=Tapez le nom d'un profil lp_atlas_profile_msg_overwrite_confirm_title=Confirmez SVP lp_atlas_profile_msg_overwrite_confirm=Le profil %s existe déjà. Remplacer le profil existant ? #main button lp_mian_create_btn_title=Créer l'atlas lp_main_create_btn_tips=Crée l'atlas lp_main_setting_button_title=Configuration lp_main_setting_button_tips=Ouvre la boîte de dialogue des préférences #tile store coverage lp_tile_store_title=Zones disponibles hors connexion lp_tile_store_title_tips=Affiche les zones de la source de carte actuellement sélectionnée qui ont été
\ téléchargées et sont donc disponibles hors connexion dans le stock local de dalles (cache de dalles) lp_tile_store_show_coverage_btn_title=Afficher les zones disponibles lp_tile_store_show_coverage_btn_tips=Affiche les zones disponibles dans le stock local de dalles, pour la source de cartes en cours,
\ le niveau de zoom en cours et la zone de la carte visible actuellement dans l'aperçu.
\ Les zones en vert sont présentes dans le stock local, celles en gris ne le sont pas. lp_tile_store_hide_coverage_btn_title=Masquer les zones disponibles lp_tile_store_zoom_combo_tips=Sélectionne le niveau de zoom pour lequel vous voulez afficher les zones disponibles dans le stock local de dalles lp_tile_store_zoom_title=Niveau de zoom : lp_tile_store_layer_title=Couche : #---------- GPX Panel ------------------------- rp_gpx_new_gpx=Nouveau GPX rp_gpx_load_gpx=Charger GPX rp_gpx_save_gpx=Enregistrer GPX rp_gpx_clear_gpx=Effacer la liste rp_gpx_add_wpt=Ajouter un point de passage rp_gpx_default_node_name=fichiers GPX chargés... rp_gpx_pop_menu_delete_element=Supprimer un élément rp_gpx_pop_menu_rename_element=Renommer un élément rp_gpx_menu_rename=Renommer rp_gpx_menu_delete=Supprimer rp_gpx_msg_confim_delete_title=Supprimer un nœud rp_gpx_msg_confim_delete=Êtes-vous certain de vouloir supprimer ce nœud ? rp_gpx_rename_element_title=Tapez le nom : rp_gpx_msg_can_not_rename_track=Les segments de trace ne peuvent pas être nommés. rp_gpx_msg_ask_create_new=Aucun fichier GPX sélectionné. Voulez-vous créer un nouveau fichier GPX ? rp_gpx_msg_ask_create_new_title=Ajouter un point au nouveau fichier GPX ? rp_gpx_msg_add_point_failed=Les points de passage peuvent seulement être ajoutés au fichier GPX, aux itinéraires ou aux segments de trace. rp_gpx_root_default_name_nofile=sans_nom (nouveau GPX) rp_gpx_root_default_name_hasfile=sans_nom (fichier %s) rp_gpx_unname_route_name=itineraire_sans_nom rp_gpx_unname_track_name=trace_sans_nom rp_gpx_unname_wpt_name=point_de_passage_sans_nom rp_gpx_msg_confirm_reopen_file=Ce (ou ces) fichier(s) GPX est (sont) déjà ouvert(s).\nVoulez-vous ouvrir d'autres instances de ce(s) fichier(s) ? rp_gpx_msg_error_save_gpx_file=Erreur lors de l'enregistrement du fichier GPX rp_gpx_msg_no_select_file=Aucun fichier GPX sélectionné rp_gpx_node_seg_name=segment %s #---------- Main Menu ------------------------- #Atlas menu_atlas=Atlas menu_atlas_new=Nouvel atlas menu_atlas_convert_format=Changer le format de l'atlas menu_atlas_create=Créer un atlas #Maps menu_maps=Cartes menu_maps_selection=Mode de sélection menu_maps_selection_rect=Rectangulaire menu_maps_selection_polygon=Polygonal menu_maps_selection_circle=Circulaire menu_maps_selection_add=Ajouter la sélection menu_maps_selection_add_by_gpx=Sélectionner avec une trace GPX #Bookmark menu_bookmark=Favoris menu_bookmark_save=Enregistrer la vue actuelle menu_bookmark_manage=Gérer les favoris #Panels menu_panels=Panneaux menu_show_hide_left_panel=Afficher/Masquer le panneau gauche menu_show_hide_gpx_panel=Afficher/Masquer le panneau GPX #Debug menu_debug=Debug menu_debug_show_hide_tile_border=Afficher/Masquer les limites des dalles menu_debug_show_all_map_source=Afficher toutes les sources de cartes menu_debug_refresh_map_source=Mettre à jour les sources de cartes personnalisées menu_debug_show_log_file=Afficher le journal de bord menu_debug_log_level=Niveau d'enregistrement du journal de bord menu_debug_system_report=Créer un rapport système #help menu_help=Aide menu_help_readme=Afficher les notes menu_help_how_to_preview=Comment utiliser l'aperçu de la carte menu_help_licenses=Licences menu_help_about=À propos #tools menu_tool=Outils #---------- Dialog ------------------------- #About dlg_about_title=À propos dlg_about_version=Version : dlg_about_program_version=Révision du programme : dlg_about_download_mapplus=Télécharger Map Plus dlg_about_download_mapplus_url=http://itunes.apple.com/us/app/map-plus/id438868200?mt=8&ls=1 #Font choose dlg_font_choose_title=Choisir la police de caractères dlg_font_choose_preview=Aperçu dlg_font_choose_name=Nom dlg_font_choose_style=Style dlg_font_choose_size=Taille #Licenses dlg_license_title=Licences #Help dlg_help_title=Aide #Manager Bookmark dlg_mgn_bookmark_title=Gérer les favoris dlg_mgn_bookmark_delete=Supprimer le favori #Bookmark Add dlg_add_bookmark_msg=Tapez le nom du nouveau favori #New Atlas dlg_new_atlas_title=Paramètres du nouvel atlas dlg_new_atlas_name_title=Nom du nouvel atlas : dlg_new_atlas_default_atlas_name=Atlas_sans_nom dlg_new_atlas_select_format_title=Choisissez le format de l'atlas #Working Progress dlg_progress_title=Progression dlg_progress_about_btn=À propos dlg_progress_count=Nombre : 0 dlg_progress_count_i=Nombre : %d #Select GPX Track dlg_gpx_track_select_title=Distance autour de la trace dlg_gpx_track_select_distance=Distance autour de la trace : %d %s #Add GPS point dlg_gpx_inpu_point_name=Tapez le nom du nouveau point : #Show All Map Source dlg_show_source_title=Noms des sources de cartes dlg_show_source_column_name=Nom dlg_show_source_column_display_text=Afficher le texte dlg_show_source_column_rev=Révision dlg_show_source_column_type=Type #Select Dir dlg_select_dir_title=Choisissez le dossier dlg_select_dir_description=Dossiers #Atlas download progress dlg_download_title=Création de l'atlas en cours dlg_download_zoom_level_progress=Récupération des dalles pour le niveau de zoom dlg_download_map_progress=Traitement des cartes de l'atlas : dlg_download_atlas_progress=%d%% réalisés - traitement de l'atlas %s de type %s dlg_download_done_percent=%d%% réalisés dlg_download_done_tenthpercent=%.1f%% réalisés dlg_download_window_title=

CRÉATION DE L'ATLAS EN COURS...

dlg_download_map_info_label_default=Création de la carte ABCDEFGHIJKLMNOPQRSTUVWXYZ-nn de la couche ABCDEFGHIJKLMNOPQRSTUVWXYZ de la source de cartes ABCDEFGHIJKLMNOPQRSTUVWXYZ dlg_download_map_info_label=Création de la carte %s de la couche %s de la source de cartes %s dlg_download_map_done_count_default=000 sur 000 réalisés dlg_download_map_done_count=%d sur %d réalisés dlg_download_remain_time_default=Temps restant : 00000 minutes 00 secondes dlg_download_remain_time=Temps restant : %s dlg_download_tile_done_count_default=1000000 sur 1000000 dalles traitées dlg_download_tile_done_count=%d sur %d dalles traitées dlg_download_map_create_title=Création de la carte dlg_download_avg_speed=Vitesse moyenne de téléchargement dlg_download_avg_speed_value=: %s / seconde dlg_download_total_bytes=Téléchargé dlg_download_bytes_from_cache=Trouvé dans le stock local de dalles dlg_download_thread_count=Nombre de téléchargements simultanés dlg_download_retry_count=Erreurs de téléchargement temporaires dlg_download_retry_count_value=: carte actuelle : %d, total : %d dlg_download_failed_count=Erreurs de téléchargement permanentes dlg_download_failed_count_value=: carte actuelle : %d, total: %d dlg_download_error_tips=

Erreurs de téléchargement pour la carte actuelle et pour l'atlas complet (temporaires/permanentes)

\

Si un téléchargement de dalle échoue, Mobile Atlas Creator effectue deux nouvelles tentatives.
\ Si le téléchargement échoue la seconde fois, la dalle sera considérée comme
\ non disponible et aucune nouvelle tentative ne sera faite pendant la création de la carte.

dlg_download_total_time=Temps de création total dlg_download_checkbox_ignore_error=Ignorer les erreurs de téléchargement et continuer automatiquement dlg_download_status_title=État : dlg_download_status_running=EN COURS dlg_download_status_aborted=INTERROMPU dlg_download_status_finished=TERMINÉ dlg_download_status_paused=EN PAUSE dlg_download_btn_abort=Interrrompre la création dlg_download_btn_abort_tips=Interrompre le téléchargement en cours dlg_download_btn_close_win=Fermer la fenêtre dlg_download_btn_close_win_tips_disable=Création de l'atlas en cours... dlg_download_btn_close_win_tips_enable=Fermer la fenêtre de proression de la création de l'atlas dlg_download_btn_open_folder=Ouvrir le dossier des atlas dlg_download_btn_open_folder_tips_disabled=Création de l'atlas en cours... dlg_download_btn_open_folder_tips_enabled=Ouvre le dossier contenant l'atlas dlg_download_btn_pause_resume=Pause/Reprise dlg_download_time_unknown=inconnu dlg_download_abort_title=Création de l'atlas interrompue dlg_download_abort_window_title=

LA CRÉATION DE L'ATLAS A ÉTÉ INTERROMPUE PAR L'UTILISATEUR

dlg_download_succeed_title=L'atlas a été créé avec succès dlg_download_succeed_window_title=

L'ATLAS A ÉTÉ CRÉÉ AVCE SUCCÈS

dlg_download_errors_todo=Nombreuses erreurs de téléchargement - que faire ? dlg_download_errors_todo_msg=Plusieurs téléchargemenst de dalles ont échoué. \ Il y a peut-être un problème avec votre connexion Internet ou avec la zone sélectionnée. \
Voulez-vous :

\ Continuer la création de la carte en ignorant les erreurs ? (il y aura des dalles manquantes)
\ Réessayer de télécharger la carte, en recommençant du début ?
\ Passer la carte en cours et continuer avec les autres cartes de l'atlas ?
\ Interrompre la carte en cours et la création de l'atlas ?
dlg_download_errors_missing_tile=Erreur - des dalles sont manquantes - voulez-vous continuer tout de même ? dlg_download_errors_missing_tile_msg=Un problème est survenu pendant le chargement des dalles de l'atlas.\n\ Le nombre de dalles téléchargées est inférieur à celui qui a été calculé.\nPar conséquent, des dalles \ manqueront dans l'atlas.\n %d dalles manquent.\n\n\ Voulez-vous continuer et créer tout de même l'atlas ? dlg_download_show_error_report=Afficher le rapport d'erreur dlg_download_erro_head=Une erreur est survenue : #Splash Frame splash_title=Mobile Atlas Creator démarre... #---------- Setting ------------------------- set_title=Paramètres #Display set_display_title=Affichage set_display_unit_system_title=Système d'unités set_display_unit_system_metric=Métrique set_display_unit_system_imperial=Impérial set_display_unit_system_scale_bar=Système d'unités pour l'échelle : set_display_language=Langue set_display_language_choose=Choisissez la langue : set_display_language_choose_tips=Choisissez la langue et redémarrez MOBAC. set_display_language_restart_desc=Vous devez redémarrer MOBAC après le changement de langue. set_display_language_msg_title=Redémarrage indispensable. set_display_language_msg=Veuillez redémarrer MOBAC pour qu'il affiche la nouvelle langue. set_display_grid=Grille WGS 84 set_display_grid_compress=Étiquettes compactes set_display_grid_compress_tips=Si sélectionné, les étiquettes ne contiendront plus d'informations redondantes. set_display_grid_title=Choix de la couleur de la grille set_display_grid_width=Épaisseur : set_display_grid_width_tips=Épaisseur des lignes. set_display_grid_color=Couleur: set_display_grid_color_tips=Couleur des lignes et des coordonnées. set_display_grid_font=Police de caractères : set_display_grid_font_tips=Choix de la police de caractètres utilisée pour l'affichage des coordonnées. #Map sources config set_mapsrc_config_title=Configuration des sources de cartes set_mapsrc_config_online_update=Mise à jour des sources de cartes set_mapsrc_config_online_update_btn=Rechercher une mise à jour set_mapsrc_config_online_update_no_update=Aucune mise à jour disponible set_mapsrc_config_online_update_done=Les mises à jour ont été téléchargées set_mapsrc_config_online_update_failed=La mise à jour a échoué set_mapsrc_config_online_update_msg_outdate=Cette version de MOBAC n'est plus supportée pour les mises à jours en ligne.\ Veuillez installer la dernière version disponible. set_mapsrc_config_online_update_msg_noneed=La dernière version des sources de carte est déjà installée. set_mapsrc_config_online_update_msg_done=%d sources de cartes ont été mises à jour.\n\ Veuillez redémarrer MOBAC pour installer les mises à jour. set_mapsrc_config_osmhiking=Reit- und Wanderkarte ($Abo) set_mapsrc_config_osmhiking_purchased=Purchased ticket ID: set_mapsrc_config_osmhiking_howto=How to get a ticket (German) set_mapsrc_config_osmhiking_howto_url=http://www.wanderreitkarte.de/shop_abo_de.php #Map sources set_mapsrc_mgr_title=Sources de cartes set_mapsrc_mgr_title_enabled=Sources de cartes actives set_mapsrc_mgr_title_disabled=Sources de cartes inactives set_mapsrc_mgr_move_up_tips=Monter la carte active sélectionnée
d'une ligne set_mapsrc_mgr_move_down_tips=Descendre la carte active sélectionnée
d'une ligne set_mapsrc_mgr_move_left_tips=Activer la(les) carte(s) sélectionnée(s) set_mapsrc_mgr_move_right_tips=Désactiver la(les) carte(s) sélectionnée(s) #Tile Update set_tile_update_title=Mise à jour des dalles set_tile_update_desc=Les dalles sont mises à jour automatiquement selon les paramètres suivants. \ Chaque dalle possède
une date d'expiration qui est parfois fournie par \ le serveur. Si le serveur n'en fournit
pas une, la durée de validité par défaut est utilisée. set_tile_update_default_expiration=Durée de validité par défaut set_tile_update_default_expiration_desc=La durée de validité par défaut est utilisée pour les sources de cartes
\ qui ne fournissent pas une date d'expiration pour chaque dalle. set_tile_update_max_expiration=Durée de validité maximale set_tile_update_min_expiration=Durée de validité minimale #Tile Store set_tile_store_title=Stockage local des dalles set_tile_store_enable_checkbox=Activer le stockage local des dalles pour l'aperçu de la carte et le téléchargement de l'atlas set_tile_store_settings=Paramètre du stockage local de dalles set_tile_store_information=Information set_tile_store_info_mapsrc=Source de cartes set_tile_store_info_tiles=Dalles set_tile_store_info_size=Taille set_tile_store_info_disabled_subfix= (inutilisé) set_tile_store_info_delete_tips=Supprimer toutes les dalles %s. set_tile_store_info_deleteing_tips=Suppression en cours - patientez SVP set_tile_store_info_total=Total #Map Size set_map_size_title=Taille des cartes set_map_size_settings=Paramètres des tailles de cartes set_map_size_max_size_of_rect=Taille maximale (largeur et hauteur) des cartes rectangulaires : set_map_size_overlap_tiles=Nombre de dalles communes à deux zones voisines (recouvrement) : set_map_size_desc=Si la taille de la zone à télécharger est plus grande que la taille maximale de la carte,
la zone sera coupée en plusieurs morceaux lors de l'ajout de la zone sélectionnée.
\ Chaque morceau ne peut être plus grand que la taille maximale de carte spécifiée.
\ Remarque : les cartes polygonales ne sont pas concernées par ce paramètre !
\ Vous pouvez voir le nom de cartes et leurs zones dans l'arborescence de l'atlas.
\ La modification de la taille maximale n'a aucun effet sur les zones déjà ajoutées à l'atlas.

\ Remarque pour les utilisateurs de TrekBuddy :
Les versions de TrekBuddy versions antérieures à la version v0.9.88 \ ont une taille maximale de cartes de 32767 pixels.
\ Les nouvelles versions peuvent gérer des cartes jusqu'à une taille de 1048575 pixels. #Directory set_directory_title=Dossiers set_directory_output=Dossier de stockage des atlas set_directory_output_tips=Si laissé vide, le dossier par défaut est utilisé :
%s set_directory_output_select=Sélectionner set_directory_output_select_dlg_title=Sélectionnez un dossier #Network set_net_title=Réseau set_net_connection=Connexions réseau set_net_connection_desc=Nombre maximal de connexions simultanées pour le téléchargement des dalles set_net_bandwidth_desc=Limitation de débit pour le téléchargement des dalles set_net_bandwidth_unlimited=Non limité set_net_proxy=Mandataire HTTP set_net_proxy_settings=Paramètres du mandataire : set_net_proxy_settings_java=Utiliser les paramètres standards de Java set_net_proxy_settings_application=Utiliser les paramètres de l'application set_net_proxy_settings_custom=Utiliser des paramètres personnalisés (définis par l'utilisateur) set_net_proxy_settings_custom_auth=Utiliser des paramètres personnalisés avec authentification set_net_proxy_host=Nom de l'hôte : set_net_proxy_port=Port : set_net_proxy_username=Utilisateur : set_net_proxy_password=Mot de passe : set_net_default=Défaut set_net_default_ignore_error=Ignorer les erreurs de téléchargement et continuer automatiquement #Paper Atlas set_paper_title=Atlas papier #Paper Atlas - Size set_paper_size=Taille set_paper_size_default=Défaut set_paper_size_default_tips=Si coché, la taille du papier sera déterminée pat le format choisi. set_paper_size_default_combo_tips=Choisissez un format de page par défaut. set_paper_size_default_landscape=Paysage set_paper_size_default_landscape_tips=Si sélectionné, le papier sera positionné dans le sens paysage. set_paper_size_custom=Personnalisé set_paper_size_custom_tips=Si sélectionné, l'utilisateur peut choisir la taille du papier. set_paper_size_custom_width=Largeur : set_paper_size_custom_width_tips=Largeur de la page. set_paper_size_custom_height=Hauteur : set_paper_size_custom_height_tips=Hauteur de la page. set_paper_size_selection=Sélection set_paper_size_selection_tips=Si sélectionné, la taille du papier sera déterminée par la taille de la carte. #Paper Atlas - Additions set_paper_additions=Compléments set_paper_wgs_grid=Grille WGS 84 set_paper_wgs_grid_tips=Si sélectionné, une grille WGS 84 sera dessinée sur la carte. set_paper_wgs_grid_density_tips=Choisissez le pas de la grille WGS-84. set_paper_paper_nubmer=Numéros de page set_paper_paper_nubmer_tips=Si sélectionné, un numéro de page apparaîtra sur chaque page. set_paper_scale_bar=Échelle set_paper_scale_tips=Si sélectionné, l'échelle apparaîtra sur la carte. set_paper_compass=Rose des vents set_paper_compass_tips=Si sélectionné, une rose des vents apparaîtra sur la carte. #Paper Atlas - Margins set_paper_margins=Marges set_paper_margins_tips=Taille des marges. set_paper_margins_top=Haut : set_paper_margins_left=Gauche : set_paper_margins_bottom=Bas : set_paper_margins_right=Droite : #Paper Atlas - Advanced set_paper_advanced=Paramètres avancés set_paper_advanced_compression=Compression: set_paper_advanced_compression_tips=Indique le niveau de compression utilisé dans le fichier PDF.
\ 0 correspond à aucune compression et 9 à la compression maximale.
\ La valeur par défaut est 6. set_paper_advanced_dpi=Résolution set_paper_advanced_dpi_tips=Indique la résolution (DPI) à utiliser pour les images.
\ En général, plus la valeur sera grande et meilleure sera la qualité,
mais les surimpressions seront plus petites
\ (par exemple l'échelle, la grille WGS-84, la rose des vents et les numéros de page).
\ La valeur par défaut et 96, une meilleure qualité peut être obtenue avec la valeur 120.
\ Avertissement : Assurez vous que votre visualisateur PDF est capable d'afficher la page
\ avec la résolution choisie. set_paper_advanced_overlap=Recouvrement: set_paper_advanced_overlap_tips=Indique la taille du recouvrement entre deux pages voisines. set_paper_advanced_crop=Découpage : set_paper_advanced_crop_tips=Indique le pourcentage de couverture minimal d'une page.
\ Si une page du bord est remplie moins que ce pourcentage,
\ elle sera supprimée. #Paper Atlas - Actions set_paper_actions=Actions set_paper_actions_import_xml=Importer XML set_paper_actions_import_xml_tip=Importe tous les paramètres de l'atlas papier à partir d'un fichier XML. set_paper_actions_export_xml=Exporter XML set_paper_actions_export_xml_tip=Exporte tous les paramètres de l'atlas papier vers un fichier XML. set_paper_actions_restore_default=Réinitialiser tous les paramètres à la valeur par défaut. set_paper_actions_restore_default_tips=Remet tous les paramètres à la valeur par défaut.
\ Toutes les modifications effectuées seront perdues. set_paper_actions_error_import=Impossible d'importer les paramètres de l'atlas papier à partir du fichier : set_paper_actions_error_export=Impossible d'exporter les paramètres de l'atlas papier vers le fichier : set_paper_actions_error_reason=Raison : set_paper_actions_error_title=Une erreur est survenue ! set_paper_actions_xml_filter=Fichiers XML (*.xml) #Error set_error_saving_title=Erreur lors de l'enregistrement des paramètres set_error_saving_msg=Erreur lors de l'enregistrement des paramètres dans le fichier :\n ( %s ) #---------- Message ------------------------- #common msg_no_zoom_level_selected=Auncun niveau de zoon sélectionné msg_no_select_area=Veuillez sélectionner une zone #Add GPX Track Polygon msg_add_gpx_polygon_too_many_track=Le fichier GPX sélectionné contient plus d'un trace.\nVeuillez sélectionner une trace ou un segment de trace. msg_add_gpx_polygon_too_many_segment=La trace sélectionnée contient plus d'un segment de trace.\nVeuillez sélectionner un segment de trace. msg_add_gpx_polygon_no_select=Aucun segment de trace n'a été sélectionné. x=Maximum map size violated msg_add_gpx_polygon_maxsize=Au moins une carte dépasse la taille maximale autorisée.\n\ Le découpage automatique d'une carte polygonale en morceaux plus petits n'est pas encore implémenté.\n\nVoulez-vous continuer tout de même ? #Convert Atlas msg_convert_atlas_format=Changer le format de l'atlas msg_convert_incompatible_format=Carte incompatible avec le format de l'atlas #Log file msg_no_log_file_config=Aucin fichier journal configuré msg_no_log_file=Le fichier journal n'existe pas :

%s #Setting msg_settings_write_error=Erreur lors de l'écriture des paramètres du programme dans "settings.xml" #Refresh msg_refresh_all_map_source_done=%d sources de cartes personnalisées ont été mises à jour #Help msg_no_found_readme_file=Fichier README.HTM introuvable #Merge Layer msg_confirm_merge_layer_title=Confirmer la fusion des couches msg_confirm_merge_layer=Êtes-vous certain de vouloir superposer la couche\n %s à la couche %s? msg_merge_layer_failed=La fusion des couches a échoué #Tile Size select msg_invalid_tile_size=Taille de dalle incorrecte !
Tapez un nombre entre %d et %d #Tile Store Coverage msg_tile_store_failed_retrieve_coverage=Impossible de trouver les informations sur l'étendue du stock de dalles.\n\ Il est possible que la zone sélectionnée ou le zoom soient trop grands. #Atlas download thread msg_out_of_memory_title=Mémoire insuffisante. msg_out_of_memory_head=Mobile Atlas Creator n'a pas assez de mémoire disponible. msg_out_of_memory_detail=\nLa taille de la mémoire allouée à MOBAC est actuellement de %d Mo msg_atlas_download_abort=Téléchargement de l'atlas interrompu msg_too_many_tiles_title=Téléchargement de l'atlas interdit msg_too_many_tiles_msg=Mobile Atlas Creator a détecté que vous essayez\n\ de télécharger un atlas énorme avec un très grand nombre de dalles.\n\ Veuillez réduire les zones sélectionnées avec des niveaux de zoom élevés et recommencez.\n\ Le nombre maximal de dalles autorisé par atlas est : %d\n\ Le nombre maximal de dalles dans l'atlas en cours est : %d msg_atlas_version_mismatch=Cet atlas a été créé avec une ancienne version de MOBAC. Cette vieille version\n\ utilisait un format de profil d'atlas légèrement différent et incompatible avec la version actuelle de MOBAC.\n\n\ Vous devriez effacer cet atlas et supprimer le profil correspondant.\n\ Sinon, des erreurs pourront survenir pendant l'utilisation de l'atlas. msg_atlas_data_check_failed=Un problème a été détecté pendant le chargement du profil de l'atlas.\n\ En général, cela signifie que le fichier de profil est incorrect ou que le format du fichier a changé.\n\n\ Vous devriez effacer cet atlas et supprimer le profil correspondant.\n\ Sinon, des erreurs pourront survenir pendant l'utilisation de l'atlas. #Settings msg_setting_file_is_changed_by_other_title=Enregistrer les modifications ? msg_setting_file_is_changed_by_other=Le fichier settings.xml a été modifié par une autre application.\n\ Voulez-vous sauvegarder vos modifications ?\n\ Toutes les modifications faites par l'autre application seront perdues ! msg_settings_file_can_not_parse=Impossible de lire le fichier settings.xml - Le programme va s'arrêter. #Others msg_atlas_is_empty=L'atlas est vide - ajoutez au moins une zone à l'atlas. msg_environment_not_support_title=Environnement non supporté msg_environment_not_support=Votre environnement n'est pas supporté.
Bureau : %s
Système : %s msg_environment_failed_open_output_title=Impossible d'ouvrir le dossier des atlas msg_environment_failed_open_output=Impossible d'ouvrir le dossier des atlas.
msg_environment_use_commond=
Commande utilisée : %s
msg_environment_commond_param=Paramètre : %d : %s msg_environment_lack_memory_title=Attention : mémoire disponible très faible msg_environment_lack_memory=ATTENTION : Mobile Atlas Creator a été lancé \ avec une quantité très faible de mémoire allouée.
\ La quantité maximale de mémoire utilisable actuellement par MOBAC est %s.

\ La prochaine fois, assurez-vous de démarrer Mobile Atlas Creator\ en utilisant les scripts fournis Mobile Atlas Creator.exe
\ pour Windows or start.sh pour Linux/Unix/OSX, ou ajoutez \ le paramètre -Xmx 512M à votre commande de lancement.

\ Exemple : java -Xmx512M -jar Mobile_Atlas_Creator.jar
\
Cliquez sur OK pour continuer et dèmarrer Mobile Atlas Creator
msg_environment_error_create_dir=Erreur lors de la création du dossier %s %s\n Le programme va s'arrêter. msg_environment_error_write_file=Impossible d'écrire dans le dossier %s \n %s \n Corrigez les droits d'accès aux fichiers et redémarrez MOBAC. msg_environment_error_create_setting=Impossible de créer le fichier settings.xml - le programme va s'arrêter. msg_environment_error_init_mapsrc_dir=Erreur lors de l'initialisation du dossier de sources de cartes :\n msg_environment_error_load_cloudmade=Impossible de charger la source de carte personnalisée CloudMade. Vérifiez que le lot de sources de cartes OpenStreetMap est disponible. msg_environment_mapsrc_dir_not_exist=Le dossier des sources de dalles n'existe pas - chemin :\n %s \n\ Vérifiez que vous avez bien décompacté l'archive ZIP\n\ de MOBAC, y compris tous les sous-dossiers ! msg_environment_unable_to_start=Impossible de lancer Mobile Atlas Creator : \n msg_environment_jre_bellow=L'environnement d'exécution Java ne possède pas les caractéristiques minimales requises.\n\ Mobile Atlas Creator nécessite Java 6 (1.6) ou plus récent.\n\ Veuillez mettre à jour votre environnement d'exécution Java avant de lancer Mobile Atlas Creator.\n\n\ Version de l'environnement Java : %@ msg_environment_jre_bellow_title=Problème de version de l'environnement Java msg_environment_invalid_source_folder=Le dossier demandé n'existe pas :\nMap name: %s\ \nDossier source : %s msg_environment_invalid_source_folder_zoom=Aucun dossier de niveau de zoom n'a été trouvé :\nNom de la carte : %s\ \nDossier source : %s msg_environment_invalid_source_folder_title=Dossier source invalide msg_tools_exec_command_ask=Commande à exécuter :
%s msg_tools_exec_command_ask_title=Voulez-vous exécuter cette commande ? msg_custom_map_invalid_source_file_title=Fichier source invalide msg_custom_map_invalid_source_file=Aucun fichier de base de données n'a été fourni.\nNom de la carte : %s \nNom du fichier : %s msg_custom_map_invalid_source_zip_title=Fichier ZIP source invalide msg_custom_map_invalid_source_zip=Le fichier ZIP source indiqué n'existe pas :\nNom de la carte: %s \nFichier ZIP : %s msg_custom_map_failed_open_source_zip_title=Erreur lors de la lecture du fichier ZIP msg_custom_map_failed_open_source_zip=Le fichier ZIP source indiqué n'a pas pu être lu :\nNom de la carte : %s \nFichier ZIP : %s msg_custom_map_invalid_source_sqlitedb=La base de données SQLite indiquée n'existe pas :\nNom de la carte : %s \nNom du fichier : %s msg_custom_map_source_failed_load_sqlitedb_title=Erreur lors du chargement de la base de données msg_custom_map_source_failed_load_sqlitedb=Cette base de données source SQLite n'a pas pu être chargéee :\nNom de la carte : %s\ \nNom du fichier: %s \nErreur: %s msg_update_map_pack_error_title=Erreur lors du chargement de la mise à jour des sources de cartes msg_update_map_pack_error=Une erreur est survenue lors de l'installation de la mise à jour des sources de cartes. Veuillez redémarrer MOBAC pour recharger la version précédente. msg_error_load_atlas_profile_title=Erreur pendant le téléchargement de l'atlas - continuer ? msg_error_load_atlas_profile=Erreur pendant le téléchargement de l'atlas :
 %s 
\
fichier : %s ligne/colonne : %d / %d
\ Voulez-vous continuer le téléchargement de l'atlas ?
\ La poursuite du téléchargement pourrait produire un atlas incomplet ou inutilisable.
msg_environment_slqite_lib_missing_title="Erreur - SQLite non disponible" msg_environment_slqite_lib_missing=Impossible de trouver les bibliothèques SQLite. \ Elles sont indispensables pour le format d'atlas sélectionné.
Veuillez lire la page README.HTM \ paragraphe "SQLite atlas formats". " msg_environment_image_format_not_available_title=Format d'image non disponible - bibliothèques manquantes msg_environment_image_format_not_available=Ce format d'image nécessite l'installation de biliothèques supplémentaires :
\ Java Advanced Image library (jai_core.jar et jai_codec.jar)
\ Pour plus de détails, lisez la page README.HTM \ paragraphe Requirements. msg_tile_store_access_conflict_title=Plusieurs instances de Mobile Atlas Creator sont en cours d'exécution msg_tile_store_access_conflict=Plusieurs instances de Mobile Atlas Creator essaient \ d'accéder au même stock local de dalles.\n\ Le stock local de dalles ne peut être utilisé que par une seule instance de MOBAC à la fois.\n\ Veuillez fermer l'autre instance et recommencer. mobile-atlas-creator-1.9.14+dfsg1/src/main/resources/mobac/resources/text/localize_zh_CN.properties0000644000175000017500000010001112150552674033331 0ustar paulliupaulliu#---------- Version ------------------------- mobac_version_subfix=多语言版 mobac_version_subfix_dev= #---------- Basic ------------------------- OK=确定 Cancel=取消 Close=关闭 Error=出错 Unnamed=未命名 Warning=警告 minute=分 minutes=分 second=秒 seconds=秒 Information=消息 Continue=继续 Abort=终止 Skip=跳过 Retry=重试 Undefined=未定义 Exit=退出 Bytes=字节 KiByte=KB MiByte=MB GiByte=GB #---------- On map controls ------------------------- map_ctrl_zoom_level_title=缩放等级 map_ctrl_zoom_level_title_tips=当前缩放等级 map_ctrl_zoom_grid_tips=在地图上显示指定缩放等级的图片块网格 map_ctrl_zoom_grid_prefix_fmt=%d 级网格 map_ctrl_zoom_grid_disable=不显示网格 map_ctrl_wgs_grid_title=显示经纬度网格 map_ctrl_wgs_grid_tips=在地图上显示经纬度网格线(不会保存到地图册) map_ctrl_wgs_grid_density_tips=设置经纬度网格的显示密度 map_ctrl_wgs_grid_density_prefix=每 map_ctrl_wgs_grid_density_degree=度 map_ctrl_wgs_grid_density_degrees=度 map_ctrl_wgs_grid_density_minute=分 map_ctrl_wgs_grid_density_minutes=分 map_ctrl_wgs_grid_density_seconds=秒 map_ctrl_wgs_grid_density_second=秒 map_loading_wait=正在载入地图数据,请稍等... #---------- Left Panel ------------------------- #coordinate lp_coords_title=坐标信息 lp_coords_select_btn_title=选择该区域 lp_coords_label_N=北 lp_coords_label_E=东 lp_coords_label_W=西 lp_coords_label_S=南 lp_coords_fmt_list_title=单位 lp_coords_fmt_degree_eng=度(英语) lp_coords_fmt_degree_local=度(本地) lp_coords_fmt_degree_min_eng=度 分(英文) lp_coords_fmt_degree_min_local=度 分 (本地) lp_coords_fmt_degree_min_sec_eng=度 分 秒 (英语) lp_coords_fmt_degree_min_sec_local=度 分 秒 (本地) lp_coords_fmt_tile=地图块 (x/z 或 y/z) lp_coords_invalid_text=无效坐标!
请输入 %s 到 %s 之间的数字 #map source lp_map_source_title=地图源 lp_map_source_combo_tips=选择地图源 #zoom level lp_zoom_title=缩放比例 lp_zoom_total_tile_count_tips=图片块总数 lp_zoom_number_tips=选取级别 %d 的地图 lp_zoom_total_tile_title=约 %s 个图片块 lp_zoom_total_tile_hint_head=全部图片块: lp_zoom_total_tile_hint_row=
等级 %d: %d (%dx%d) #Tile parameters settings lp_tile_param_title=图片转换 lp_tile_param_recreate_checkbox_title=图片保存前转换 (需要CPU额外计算) lp_tile_param_recreate_checkbox_tips=如果关闭这个选项,服务器下载的图片将直接保存(速度快) .
\ 否则,图片会在保存前转换为指定的大小和格式(速度很慢,依赖CPU). lp_tile_param_width_title=宽度: lp_tile_param_width_tips=图块宽度 lp_tile_param_height_title=高度: lp_tile_param_height_tips=图块高度 lp_tile_param_image_fmt_title=图块格式: lp_tile_param_image_fmt_png=PNG lp_tile_param_image_fmt_png_8bit=PNG 256 色 (8 位) lp_tile_param_image_fmt_png_4bit=PNG 16 色 (4 位) lp_tile_param_image_fmt_jpg_q100=JPEG - 品质系数 100 lp_tile_param_image_fmt_jpg_q99=JPEG - 品质系数 99 lp_tile_param_image_fmt_jpg_q95=JPEG - 品质系数 95 lp_tile_param_image_fmt_jpg_q90=JPEG - 品质系数 90 lp_tile_param_image_fmt_jpg_q85=JPEG - 品质系数 85 lp_tile_param_image_fmt_jpg_q80=JPEG - 品质系数 80 lp_tile_param_image_fmt_jpg_q70=JPEG - 品质系数 70 lp_tile_param_image_fmt_jpg_q60=JPEG - 品质系数 60 lp_tile_param_image_fmt_jpg_q50=JPEG - 品质系数 50 lp_tile_param_msg_valid_height=图片块高度只能在 %d 到 %d 之间.\n lp_tile_param_msg_valid_width=图片块宽度只能在 %d 到 %d 之间.\n #atlas content lp_atlas_title=当前地图册 lp_atlas_new_btn_title=新建地图册 lp_atlas_add_selection_btn_title=添加选择的区域 lp_atlas_name_label_title=新建地图名字: lp_atlas_name_field_tips=输入一个地图名字 # this one only support English #lp_atlas_element_default_name=Layer #atlas content detail - Atlas lp_atlas_info_atlas_title=地图册
lp_atlas_info_atlas_name=名字: %s
lp_atlas_info_atlas_layer=地图层个数: %d
lp_atlas_info_atlas_format=地图册格式: %s
lp_atlas_info_max_tile=最大图片块个数: %d
lp_atlas_info_area_start=区域开始: %s %s
lp_atlas_info_area_end=区域结束: %s %s
#atlas content detail - Layer lp_atlas_info_layer_title=地图层
lp_atlas_info_layer_map_count=地图个数: %d
#atlas content detail - Map lp_atlas_info_map_title=地图
lp_atlas_info_polygon_map_title=多边形地图
lp_atlas_info_polygon_map_point=多边形点数:
lp_atlas_info_map_source_short=地图源: %s
lp_atlas_info_map_source=地图源: %s (%s)
lp_atlas_info_map_zoom_lv=缩放级别: %d
lp_atlas_info_map_area_start=区域开始: %s (%d / %d)
lp_atlas_info_map_area_end=区域结束: %s (%d / %d)
lp_atlas_info_map_size=地图大小: %d x %d 像素
lp_atlas_info_tile_size=图片块大小: %d x %d
lp_atlas_info_tile_format=图片块格式: %s
lp_atlas_info_tile_format_origin=图片块格式: 256x256 (无处理)
#atlas content node pop menu lp_atlas_pop_menu_show_detail=显示详细信息 lp_atlas_pop_menu_display_select_area=显示下载区域 lp_atlas_pop_menu_select_map_box=选择该地图所在区域 lp_atlas_pop_menu_zoom_to_map_box=缩放到边界 lp_atlas_pop_menu_zoom_to=缩放到自身 lp_atlas_pop_menu_renmae=重命名 lp_atlas_pop_menu_apply_tile_process=应用图片转换 lp_atlas_pop_menu_clear_atals=清除整个地图册 lp_atlas_pop_menu_delete_node=删除 lp_atlas_default_tip=使用右键菜单来查看所有的节点命令. #Profile lp_atlas_profile_title=地图册配置 lp_atlas_profile_combo_tips=选择一个地图册配置\n 或者输入新的名字来保存地图册配置 lp_atlas_profile_delete_btn_title=删除配置 lp_atlas_profile_delete_btn_tips=从配置列表中删除地图册 lp_atlas_profile_save_btn_title=保存当前配置 lp_atlas_profile_save_btn_tips=保存当前地图册的配置 lp_atlas_profile_load_btn_title=载入配置 lp_atlas_profile_load_btn_tips=载入选择的地图册配置 lp_atlas_profile_refresh_btn_tips=刷新地图册配置列表 lp_atlas_profile_msg_ask_name=请输入一个配置名称 lp_atlas_profile_msg_overwrite_confirm_title=覆盖确认 lp_atlas_profile_msg_overwrite_confirm=同名地图册配置 %s 已经存在,要覆盖它吗? #main button lp_mian_create_btn_title=开始下载地图册 lp_main_create_btn_tips=开始下载地图册 lp_main_setting_button_title=设置 lp_main_setting_button_tips=打开偏好设置对话框 #tile store coverage lp_tile_store_title=本地缓存 lp_tile_store_title_tips=显示当前地图源的已下载(缓存)区域
\ 已下载缓存可以离线查看或者作为地图源制作新地图 lp_tile_store_show_coverage_btn_title=显示已缓存区域 lp_tile_store_show_coverage_btn_tips=显示当前地图源在指定级别下
\ 已经下载到本地的地图数据范围,
\ 绿色:表示已经下载到本地缓存的区域,
\ 灰色:表示没有下载的区域. lp_tile_store_hide_coverage_btn_title=取消显示 lp_tile_store_zoom_combo_tips=选择缓存区域的缩放级别 lp_tile_store_zoom_title=缩放级别: lp_tile_store_layer_title=地图源图层: #---------- GPX Panel ------------------------- rp_gpx_new_gpx=新建GPX rp_gpx_load_gpx=载入GPX rp_gpx_save_gpx=保存GPX rp_gpx_clear_gpx=清除列表 rp_gpx_add_wpt=添加路点 rp_gpx_default_node_name=已载入GPX文件... rp_gpx_pop_menu_delete_element=删除节点 rp_gpx_pop_menu_rename_element=重命名节点 rp_gpx_menu_rename=重命名 rp_gpx_menu_delete=删除 rp_gpx_msg_confim_delete_title=删除节点 rp_gpx_msg_confim_delete=您确认要删除这个节点吗? rp_gpx_rename_element_title=请输入名称: rp_gpx_msg_can_not_rename_track=Track段的名称不支持修改。 rp_gpx_msg_ask_create_new=尚未选择GPX任何文件,希望新建一个GPX文件吗? rp_gpx_msg_ask_create_new_title=添加路点到GPX文件? rp_gpx_msg_add_point_failed=路点只能加入到GPX文件根节点、route段以及Track段下。 rp_gpx_root_default_name_nofile=未命名 (新建GPX) rp_gpx_root_default_name_hasfile=未命名 (文件 %s) rp_gpx_unname_route_name=未命名 route rp_gpx_unname_track_name=未命名 track rp_gpx_unname_wpt_name=未命名 waypoint rp_gpx_msg_confirm_reopen_file=GPX文件已经被打开,您希望再次打开这些文件吗? rp_gpx_msg_error_save_gpx_file=保存GPX文件出错 rp_gpx_msg_no_select_file=很抱歉,您尚未选择GPX文件 rp_gpx_node_seg_name=线路段 %s #---------- Main Menu ------------------------- #Atlas menu_atlas=地图册 menu_atlas_new=新建地图册 menu_atlas_convert_format=转换地图册类型 menu_atlas_create=开始下载地图册 #Maps menu_maps=地图 menu_maps_selection=选择区域按 menu_maps_selection_rect=矩形 menu_maps_selection_polygon=多边形 menu_maps_selection_circle=圆 menu_maps_selection_add=添加选择的区域 menu_maps_selection_add_by_gpx=添加GPX沿线区域 #Bookmark menu_bookmark=书签 menu_bookmark_save=保存当前显示区域 menu_bookmark_manage=管理书签 #Panels menu_panels=面板 menu_show_hide_left_panel=显示/隐藏 左侧面板 menu_show_hide_gpx_panel=显示/隐藏 GPX面板 #Debug menu_debug=高级 menu_debug_show_hide_tile_border=显示/隐藏 图片边框 menu_debug_show_all_map_source=显示所有地图源 menu_debug_refresh_map_source=刷新自定义地图源 menu_debug_show_log_file=查看日志文件 menu_debug_log_level=日志级别 menu_debug_system_report=查看系统信息 #help menu_help=帮助 menu_help_readme=帮助文档 menu_help_how_to_preview=如何查看地图 menu_help_licenses=版权声明与许可证 menu_help_about=关于 #tools menu_tool=工具 #---------- Dialog ------------------------- #About dlg_about_title=关于 dlg_about_version=版本: dlg_about_program_version=开发版本: dlg_about_download_mapplus=下载地图加加 dlg_about_download_mapplus_url=https://itunes.apple.com/cn/app/id438868200?mt=8 #Font choose dlg_font_choose_title=选择字体 dlg_font_choose_preview=预览 dlg_font_choose_name=名称 dlg_font_choose_style=风格 dlg_font_choose_size=大小 #Licenses dlg_license_title=版权声明与许可证 #Help dlg_help_title=帮助 #Manager Bookmark dlg_mgn_bookmark_title=管理书签 dlg_mgn_bookmark_delete=删除书签 #Bookmark Add dlg_add_bookmark_msg=请为新建书签设置一个名字 #New Atlas dlg_new_atlas_title=新建地图册 dlg_new_atlas_name_title=新建地图册名字: dlg_new_atlas_default_atlas_name=我的地图册 dlg_new_atlas_select_format_title=请选择地图册类型 #Working Progress dlg_progress_title=完成 dlg_progress_about_btn=关于 dlg_progress_count=已完成: 0 dlg_progress_count_i=已完成: %d #Select GPX Track dlg_gpx_track_select_title=设置区域宽度 dlg_gpx_track_select_distance=设置边沿到线路中心线的距离: %d %s #Add GPS point dlg_gpx_inpu_point_name=请为该点输入一个名字: #Show All Map Source dlg_show_source_title=全部地图源 dlg_show_source_column_name=名称 dlg_show_source_column_display_text=全称 dlg_show_source_column_rev=内部版本号 dlg_show_source_column_type=类型 #Select Dir dlg_select_dir_title=选择目录 dlg_select_dir_description=目录 #Atlas download progress dlg_download_title=正在创建地图册 dlg_download_zoom_level_progress=正在下载缩放等级: dlg_download_map_progress=正在下载地图: dlg_download_atlas_progress=%d%% 已完成 - 当前地图册: %s, 类型: %s dlg_download_done_percent=%d%% 已完成 dlg_download_done_tenthpercent=%.1f%% 已完成 dlg_download_window_title=

正在创建地图册...

dlg_download_map_info_label_default=正在下载地图 ABCDEFGHIJKLMNOPQRSTUVWXYZ-nn, 图层 ABCDEFGHIJKLMNOPQRSTUVWXYZ, 地图源 ABCDEFGHIJKLMNOPQRSTUVWXYZ dlg_download_map_info_label=正在下载地图 %s 的图层 %s , 从地图源: %s dlg_download_map_done_count_default=已完成000, 共 000 dlg_download_map_done_count=已完成%d, 共 %d dlg_download_remain_time_default=剩余时间: 00000 分 00 秒 dlg_download_remain_time=剩余时间: %s dlg_download_tile_done_count_default=已下载图片 1000000, 共 1000000 块 dlg_download_tile_done_count=已下载图片 %d 块,共 %d 块 dlg_download_map_create_title=创建地图文件 dlg_download_avg_speed=平均下载速度 dlg_download_avg_speed_value=: %s / 秒 dlg_download_total_bytes=从地图源下载 dlg_download_bytes_from_cache=从本地缓存读取 dlg_download_thread_count=当前使用线程数 dlg_download_retry_count=临时出错图片 dlg_download_retry_count_value=: 当前地图: %d 次, 总共: %d 次 dlg_download_failed_count=无法下载图片 dlg_download_failed_count_value=: 当前地图: %d 次, 总共: %d 次 dlg_download_error_tips=

地图下载的出错次数(临时出错/无法下载)。

\

下载某个图片失败时,系统会重试2次,如果第二次重试时
\ 仍然无法下载. 则会标记为出错块, 并且在本次地图
\ 下载过程中不会对其进行再次下载

dlg_download_total_time=下载时间 dlg_download_checkbox_ignore_error=忽略下载错误并自动继续 dlg_download_status_title=状态: dlg_download_status_running=运行中 dlg_download_status_aborted=被终止 dlg_download_status_finished=成功完成 dlg_download_status_paused=暂停 dlg_download_btn_abort=终止下载 dlg_download_btn_abort_tips=终止地图册的下载 dlg_download_btn_close_win=关闭窗口 dlg_download_btn_close_win_tips_disable=地图册正在下载中... dlg_download_btn_close_win_tips_enable=关闭地图册下载窗口 dlg_download_btn_open_folder=打开下载文件夹 dlg_download_btn_open_folder_tips_disabled=地图册正在下载中... dlg_download_btn_open_folder_tips_enabled=打开地图册下载保存的文件夹 dlg_download_btn_pause_resume=暂停/恢复 dlg_download_time_unknown=未知 dlg_download_abort_title=地图册下载已终止 dlg_download_abort_window_title=

地图册已经被用户终止下载

dlg_download_succeed_title=地图册下载已成功 dlg_download_succeed_window_title=

地图册以成功完成

dlg_download_errors_todo=下载地图图片出错多个错误 - 您希望如何处理? dlg_download_errors_todo_msg=多个地图图片下载失败. \ 您当前连接的地图服务器或者选择的下载区域可能存在问题. \
您希望:

\ 继续 下载,并忽略遇到的图片错误? (将导致部分图块空白/丢失)
\ 重试 从头开始重新下载一遍该本地图?
\ 跳过 当前地图所有图片,进行下一个地图的下载?
\ 终止 当前地图和整个地图册的所有下载?
dlg_download_errors_missing_tile=错误:部分地图图片在下载过程丢失,仍然继续吗? dlg_download_errors_missing_tile_msg=下载地图册存在问题.\n\ 成功下载的地图图片数量少于期望下载的图片数量.\n\ 即地图册下载过程中存在图片的丢失.\n共有 %d 张图片未成功下载.\n\n\ 你仍然希望继续整个地图册的创建吗? dlg_download_show_error_report=查看错误报告 dlg_download_erro_head=运行出错: #Splash Frame splash_title=正在启动 Mobile Atlas Creator 中文版... #---------- Setting ------------------------- set_title=设置 #Display set_display_title=显示 set_display_unit_system_title=单位 set_display_unit_system_metric=公制单位 set_display_unit_system_imperial=英制单位 set_display_unit_system_scale_bar=比例尺单位: set_display_language=界面语言 set_display_language_choose=选择界面语言(需重启): set_display_language_choose_tips=选择一种语言,需要重启MOBAC才能生效 set_display_language_restart_desc=您需要重新启动MOBAC才能使得新语言生效. set_display_language_msg_title=需要重启 set_display_language_msg=语言修改需要重新启动MOBAC才能生效,现在就退出MOBAC吗? set_display_grid=经纬度网格线 set_display_grid_compress=简化坐标 set_display_grid_compress_tips=选中后,坐标文本将使用简写. set_display_grid_title=选择颜色 set_display_grid_width=线宽: set_display_grid_width_tips=设置绘制宽度 set_display_grid_color=颜色: set_display_grid_color_tips=设置网格线和文本的颜色 set_display_grid_font=字体: set_display_grid_font_tips=设置文本坐标的字体 #Map sources config set_mapsrc_config_title=地图源设置 set_mapsrc_config_online_update=在线更新地图源 set_mapsrc_config_online_update_btn=开始在线更新 set_mapsrc_config_online_update_no_update=无可用更新 set_mapsrc_config_online_update_done=更新成功 set_mapsrc_config_online_update_failed=更新失败 set_mapsrc_config_online_update_msg_outdate=当前版本的 MOBAC 不支持在线更新,\ 请升级到最新版本后再试。 set_mapsrc_config_online_update_msg_noneed=您已经拥有最新版本的地图包,无需更新。 set_mapsrc_config_online_update_msg_done=%d 个地图源被更新.\n\ 请重新启动 MOBAC 来安装这些更新。 set_mapsrc_config_osmhiking=Reit-und Wanderkarte ($Abo) 地图设置 set_mapsrc_config_osmhiking_purchased=已支付的 ticket ID: set_mapsrc_config_osmhiking_howto=如果获取一个 ticket (德语) set_mapsrc_config_osmhiking_howto_url=http://www.wanderreitkarte.de/shop_abo_de.php #Map sources set_mapsrc_mgr_title=管理地图源 set_mapsrc_mgr_title_enabled=启用的地图源 set_mapsrc_mgr_title_disabled=禁用的地图源 set_mapsrc_mgr_move_up_tips=上移选中的地图源 set_mapsrc_mgr_move_down_tips=下移选中的地图源 set_mapsrc_mgr_move_left_tips=启用选中的地图源 set_mapsrc_mgr_move_right_tips=禁用选中的地图源 #Tile Update set_tile_update_title=图片块更新 set_tile_update_desc=\ 本地缓存的图片块会按此规则在必要时重新下载(更新)
\ 每个图片块会首先按地图服务器预设的有效时间控制更新,
\ 当地图源服务器没有提供相关设置,则按照下面设置更新 set_tile_update_default_expiration=默认有效时间 set_tile_update_default_expiration_desc=只有当地图源未提供有效时间时,
\ 才会使用默认有效时间进行管理. set_tile_update_max_expiration=最大有效时间 set_tile_update_min_expiration=最小有效时间 #Tile Store set_tile_store_title=本地缓存库 set_tile_store_enable_checkbox=允许使用本地缓存来预览和下载地图 set_tile_store_settings=本地缓存设置 set_tile_store_information=信息 set_tile_store_info_mapsrc=地图源 set_tile_store_info_tiles=已缓存图片 set_tile_store_info_size=已缓存大小 set_tile_store_info_disabled_subfix= (禁用) set_tile_store_info_delete_tips=删除所有 %s 的本地缓存图片. set_tile_store_info_deleteing_tips=正在删除 - 请稍等... set_tile_store_info_total=缓存大小合计 #Map Size set_map_size_title=地图大小 set_map_size_settings=地图大小设置 set_map_size_max_size_of_rect=矩形选区对应的地图最大宽度或高度: set_map_size_overlap_tiles=地图区域的图片块叠加个数: set_map_size_desc=\ 如果矩形选区的长或者宽超出设置的最大大小,
\ MOBAC会在您添加区域到地图册的时候,
\ 自动拆分区域为多个子地图,以保证每个子地图的大小
\ 都会小于设置的最大地图大小.
\ 注意:该设置对多边形选区无效,对于已经添加的选区也无效
\ 您可以在地图册的树型结构中查看当前地图的大小.
\
\ 使用TrekBuddy用户请注意:
\ TrekBuddy 在 v0.9.88 版本之前不支持地图大于 32767.
\ 之后版本可以支持大小在 1048575 以内的地图. #Directory set_directory_title=目录 set_directory_output=地图册导出目录 set_directory_output_tips=如果设置为空,则使用默认目录:
%s set_directory_output_select=重新选择 set_directory_output_select_dlg_title=选择目录 #Network set_net_title=网络 set_net_connection=网络连接 set_net_connection_desc=同时运行的下载连接数 set_net_bandwidth_desc=下载带宽限速 set_net_bandwidth_unlimited=无限制 set_net_proxy=HTTP 代理 set_net_proxy_settings=代理设置: set_net_proxy_settings_java=使用Java代理设置 set_net_proxy_settings_application=使用应用的代理设置 set_net_proxy_settings_custom=用户自定义 set_net_proxy_settings_custom_auth=用户自定义(带认证) set_net_proxy_host=代理服务器: set_net_proxy_port=端口: set_net_proxy_username=用户名: set_net_proxy_password=密码: set_net_default=默认 set_net_default_ignore_error=下载时忽略错误并继续下载 #Paper Atlas set_paper_title=页面设置 #Paper Atlas - Size set_paper_size=大小 set_paper_size_default=默认 set_paper_size_default_tips=选择该选项, 则页面大小由指定的格式决定. set_paper_size_default_combo_tips=选择一个默认的页面格式 set_paper_size_default_landscape=横向排版 set_paper_size_default_landscape_tips=选择该选项,页面方向为横向。 set_paper_size_custom=自定义 set_paper_size_custom_tips=选择该选项,用户可以手工指定页面大小 set_paper_size_custom_width=宽度: set_paper_size_custom_width_tips=指定页面宽度. set_paper_size_custom_height=高度: set_paper_size_custom_height_tips=指定页面高度 set_paper_size_selection=选择区域 set_paper_size_selection_tips=选择该选项,页面按地图的大小区域决定 #Paper Atlas - Additions set_paper_additions=附加 set_paper_wgs_grid=经纬度网格线 set_paper_wgs_grid_tips=如果选择,将会打印经纬度格线(WGS-64) set_paper_wgs_grid_density_tips=选择经纬度网格线密度 set_paper_paper_nubmer=页面编号 set_paper_paper_nubmer_tips=选择该选项,页码编号将会打印在每一页 set_paper_scale_bar=比例尺 set_paper_scale_tips=选择该选项,比例尺将会打印在地图上 set_paper_compass=指南针 set_paper_compass_tips=选择该选项,指南针将会打印在地图上 #Paper Atlas - Margins set_paper_margins=缩进 set_paper_margins_tips=指定缩进的尺寸 set_paper_margins_top=上: set_paper_margins_left=左: set_paper_margins_bottom=下: set_paper_margins_right=右: #Paper Atlas - Advanced set_paper_advanced=高级 set_paper_advanced_compression=压缩: set_paper_advanced_compression_tips=指定PDF文档的压缩级别.
\ 0 表示不压缩, 9 表示最大压缩.
\ 数字越大,压缩比例越高,默认为6. set_paper_advanced_dpi=分辨率 set_paper_advanced_dpi_tips=指定图片的分辨率 (DPI) .
\ 一般地,更高的值意味着更好的视觉效果.
\ 默认值为 96, 可以提升到120以获得更好的效果,
\ 但请注意:您的PDF阅读器也须以相当的分辨率来显示
\ 才能获得最佳效果 set_paper_advanced_overlap=重叠: set_paper_advanced_overlap_tips=指定相邻两个页面的重叠区大小. set_paper_advanced_crop=裁剪: set_paper_advanced_crop_tips=指定裁剪的百分比.
\ 超过这个比例位置的页面边界将会被裁剪掉 #Paper Atlas - Actions set_paper_actions=操作 set_paper_actions_import_xml=从XML导入 set_paper_actions_import_xml_tip=从XML导入所有页面设置 set_paper_actions_export_xml=导出到XML set_paper_actions_export_xml_tip=导出所有页面设置到XML文件 set_paper_actions_restore_default=恢复到默认值 set_paper_actions_restore_default_tips=重置全部页面设置为默认值
\ 所有当前的设置的参数将会被覆盖. set_paper_actions_error_import=无法导入页面设置文件: set_paper_actions_error_export=无法导出到页面设置文件: set_paper_actions_error_reason=原因: set_paper_actions_error_title=发生错误! set_paper_actions_xml_filter=XML 文件 (*.xml) #Error set_error_saving_title=保存设置出错 set_error_saving_msg=无法保存设置到文件:\n ( %s ) #---------- Message ------------------------- #common msg_no_zoom_level_selected=请至少选择一个缩放级别 msg_no_select_area=请选择一个区域 #Add GPX Track Polygon msg_add_gpx_polygon_too_many_track=当前选择文件包含不止一条线路\n请选择其中一条线路(track)或线路段(segment)。 msg_add_gpx_polygon_too_many_segment=当前选择的线路包含不止一条线路段(segment)\n请选择其中一条线路段(segment)。 msg_add_gpx_polygon_no_select=没有选择GPX线路(track)或线路段(segment) msg_add_gpx_polygon_maxsize_title=超出最大地图尺寸 msg_add_gpx_polygon_maxsize=至少一个地图超出了最大尺寸,\n\ 但本程序暂不支持多边形区域的自动拆分,\n您仍然希望继续吗? #Convert Atlas msg_convert_atlas_format=转换地图册格式 msg_convert_incompatible_format=地图和地图册的格式不兼容 #Log file msg_no_log_file_config=没有配置的日志文件 msg_no_log_file=日志文件不存在:

%s #Setting msg_settings_write_error=写入设置信息到"settings.xml"时出错 #Refresh msg_refresh_all_map_source_done=%d 个自定义地图源被成功刷新 #Help msg_no_found_readme_file=不能找到文件:README.HTM #Merge Layer msg_confirm_merge_layer_title=确认合并地图层 msg_confirm_merge_layer=您确定要将地图层 %s 合并到 %s 吗? msg_merge_layer_failed=图层合并失败 #Tile Size select msg_invalid_tile_size=无效的图片块大小!
请输入 %d 到 %d 之间的数 #Tile Store Coverage msg_tile_store_failed_retrieve_coverage=无法显示本地缓存的覆盖范围.\n\ 可能是因为选择的区域过大或者缩放级别过大. #Atlas download thread msg_out_of_memory_title=内存不足. msg_out_of_memory_head=Mobile Atlas Creator没有足够内存继续运行. msg_out_of_memory_detail=\n当前分配给MOBAC的最大内存数为 %d MB msg_atlas_download_abort=地图册下载已经被终止 msg_too_many_tiles_title=无法进行地图册下载 msg_too_many_tiles_msg=Mobile Atlas Creator 检测到您即将\n\ 下载的地图册拥有远远超出常规数目的图片块数量,\n\ 请减少在高缩放级别时选择的地图区域大小,并重新下载.\n\ 最大允许的地图图片块数为: %d\n\ 当前地图册中的图片块数为:%d msg_atlas_version_mismatch=当前打开/加载的地图册是MOBAC早期版本创建的,\n\ 该版本与当前版本的存储格式无法兼容。\n\n\ 建议您清除掉整个地图册,并删除受影响的地图册保存文件,\n\ 否则在使用相关地图册时,可能出现更多异常情况.\n msg_atlas_data_check_failed=载入保存的地图册时出现错误。\n\ 这可能是因为文件被修改或者格式不兼容造成的,\n\n\ 建议您清除掉整个地图册,并删除受影响的地图册保存文件,\n\ 否则在使用相关地图册时,可能出现更多异常情况.\n #Settings msg_setting_file_is_changed_by_other_title=覆盖已修改内容? msg_setting_file_is_changed_by_other=参数文件 settings.xml 已经被其它程序修改.\n\ 您希望覆盖其它程序的修改吗?\n\ 当覆盖后,其它程序所作的所有修改都会被清除! msg_settings_file_can_not_parse=无法读取或解析设置文件,程序将会退出。 #Others msg_atlas_is_empty=地图册为空,请首先为地图册添加一个区域 msg_environment_not_support_title=不支持平台 msg_environment_not_support=不支持您的运行环境.
桌面平台: %s
操作系统: %s msg_environment_failed_open_output_title=打开地图册文件夹失败 msg_environment_failed_open_output=打开地图册输出文件夹失败.
msg_environment_use_commond=
使用命令: %s
msg_environment_commond_param=参数: %d : %s msg_environment_lack_memory_title=警告: 内存设置过小 msg_environment_lack_memory=\ 警告: Mobile Atlas Creator 在运行时允许使用的内存过小.
\ 当前Mobile Atlas Creator 最大可用内存仅为: %s.

\ 请确认您使用了正确启动程序或脚本来运行MOBAC:
\ 对于Window系统,请使用Mobile Atlas Creator.exe
\ 对于Linux/Unix/OSX系统,请使用 start.sh 脚本,
\ 脚本参数:-Xmx 512M 可指定512M最大可用内存.

\ 例如: java -Xmx512M -jar Mobile_Atlas_Creator.jar
\
Mobile Atlas Creator将在您确定后继续运行
msg_environment_error_create_dir=创建文件夹 %s 出错,文件夹路径 %s\n 程序将退出. msg_environment_error_write_file=无法写入到文件:\n %s \n路径:%s \n 请修改文件权限并重启MOBAC. msg_environment_error_create_setting=无法写入到设置文件settings.xml, 程序将退出. msg_environment_error_init_mapsrc_dir=无法初始化地图源文件夹:\n msg_environment_error_load_cloudmade=无法载入自定义的CloudMade 地图源. 请确保openstreetmap地图源包完好可用. msg_environment_mapsrc_dir_not_exist=地图源文件夹不存在 - 位置:\n %s \n\ 请确保您在解压缩MOBAC的zip包时,\n\ 包含了所有的子文件夹. msg_environment_unable_to_start=无法启动Mobile Atlas Creator: \n msg_environment_jre_bellow=您电脑上安装的Java环境(Java Runtime Environment)版本过低.\n\ Mobile Atlas Creator 需要至少Java 6 (1.6) 或更高版本.\n\ 请升级您的Java运行时环境,再重启Mobile Atlas Creator.\n\n\ 当前检测到的 Java 版本为: %@ msg_environment_jre_bellow_title=Java运行环境不兼容 msg_environment_invalid_source_folder=指定的地图源文件夹不存在:\n地图名: %s\ \n地图源目录: %s msg_environment_invalid_source_folder_zoom=无法找到指定缩放等级的目录:\n地图名: %s\ \n地图源目录: %s msg_environment_invalid_source_folder_title=无效地图源目录 msg_tools_exec_command_ask=要执行的命令行:
%s msg_tools_exec_command_ask_title=您希望执行该命令吗? msg_custom_map_invalid_source_file_title=无效地图源文件 msg_custom_map_invalid_source_file=指定数据库文件不存在.\n地图名: %s \n文件名: %s msg_custom_map_invalid_source_zip_title=无效的zip源 msg_custom_map_invalid_source_zip=指定的zip地图源文件不存在:\n地图名: %s \nZip 文件: %s msg_custom_map_failed_open_source_zip_title=读取zip文件失败 msg_custom_map_failed_open_source_zip=无法读取指定的地图源zip文件:\n地图名: %s \nZip 文件: %s msg_custom_map_invalid_source_sqlitedb=指定的 SQLite 数据库文件不存在:\n地图名: %s \n文件名: %s msg_custom_map_source_failed_load_sqlitedb_title=加载数据库文件出错 msg_custom_map_source_failed_load_sqlitedb=指定的数据库文件无法被加载:\n地图名: %s\ \n文件名: %s \n错误信息:%s msg_update_map_pack_error_title=加载地图包出错 msg_update_map_pack_error=在加载升级的地图包时出现错误,请重新启动 MOBAC 来恢复到之前的版本。 msg_error_load_atlas_profile_title=加载地图册出错 - 继续吗? msg_error_load_atlas_profile=加载地图册出错:
 %s 
\
文件: %s 行/列: %d / %d
\ 您希望继续加载该地图册吗?
\ 这可能导致地图册不完整或者无法正常工作.
msg_environment_slqite_lib_missing_title="出错 - SQLite 库不可用" msg_environment_slqite_lib_missing=无法找到SQLite库文件. \ 您当前的地图册格式必须Sqlite库才能运行.
请查阅帮助文件 README.HTM \ 的"SQLite atlas formats"章节获得更多帮助. " msg_environment_image_format_not_available_title=图片格式不支持 - 缺少图片库 msg_environment_image_format_not_available=该文件格式需要安装额外的Java图片处理库:
\ Java Advanced Image library (jai_core.jar & jai_codec.jar)
\ 更多信息请查看帮助文件 README.HTM \ 中的 Requirements章节. msg_tile_store_access_conflict_title=运行冲突 msg_tile_store_access_conflict=\ 多个 Mobile Atlas Creator 正在试图同时访问\n\ 相同的本地地图缓存,本地地图缓存只能同时有一个MOBAC\n\ 实例访问.请关闭其它MOBAC程序实例后再试.\nmobile-atlas-creator-1.9.14+dfsg1/src/main/resources/mobac/resources/text/license-dbd-je.txt0000644000175000017500000001007612122526606031644 0ustar paulliupaulliu/*- * $Id: LICENSE,v 1.12.2.2 2010/01/04 15:30:18 cwl Exp $ */ The following is the license that applies to this copy of the Berkeley DB Java Edition software. For a license to use the Berkeley DB Java Edition software under conditions other than those described here, or to purchase support for this software, please contact Oracle at berkeleydb-info_us@oracle.com. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= /* * Copyright (c) 2002,2010 Oracle. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Redistributions in any form must be accompanied by information on * how to obtain complete source code for the DB software and any * accompanying software that uses the DB software. The source code * must either be included in the distribution or be available for no * more than the cost of distribution plus a nominal fee, and must be * freely redistributable under reasonable conditions. For an * executable file, complete source code means the source code for all * modules it contains. It does not include source code for modules or * files that typically accompany the major components of the operating * system on which the executable file runs. * * THIS SOFTWARE IS PROVIDED BY ORACLE ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR * NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL ORACLE BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= /*** * ASM: a very small and fast Java bytecode manipulation framework * Copyright (c) 2000-2005 INRIA, France Telecom * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ mobile-atlas-creator-1.9.14+dfsg1/src/main/resources/mobac/resources/text/localize_zh_TW.properties0000644000175000017500000010006112150552674033370 0ustar paulliupaulliu#---------- Version ------------------------- mobac_version_subfix=多語言版 mobac_version_subfix_dev= #---------- Basic ------------------------- OK=確定 Cancel=取消 Close=關閉 Error=出錯 Unnamed=未命名 Warning=警告 minute=分 minutes=分 second=秒 seconds=秒 Information=消息 Continue=繼續 Abort=終止 Skip=跳過 Retry=重試 Undefined=未定義 Exit=退出 Bytes=Bytes KiByte=KB MiByte=MB GiByte=GB #---------- On map controls ------------------------- map_ctrl_zoom_level_title=縮放等級 map_ctrl_zoom_level_title_tips=當前縮放等級 map_ctrl_zoom_grid_tips=在地圖上顯示指定縮放等級的圖片塊網格 map_ctrl_zoom_grid_prefix_fmt=%d 級網格 map_ctrl_zoom_grid_disable=不顯示網格 map_ctrl_wgs_grid_title=顯示經緯度網格 map_ctrl_wgs_grid_tips=在地圖上顯示經緯度網格線(不會保存到地圖冊) map_ctrl_wgs_grid_density_tips=設置經緯度網格的顯示密度 map_ctrl_wgs_grid_density_prefix=每 map_ctrl_wgs_grid_density_degree=度 map_ctrl_wgs_grid_density_degrees=度 map_ctrl_wgs_grid_density_minute=分 map_ctrl_wgs_grid_density_minutes=分 map_ctrl_wgs_grid_density_seconds=秒 map_ctrl_wgs_grid_density_second=秒 map_loading_wait=正在載入地圖數據,請稍等... #---------- Left Panel ------------------------- #coordinate lp_coords_title=坐標信息 lp_coords_select_btn_title=選擇該區域 lp_coords_label_N=北 lp_coords_label_E=東 lp_coords_label_W=西 lp_coords_label_S=南 lp_coords_fmt_list_title=單位 lp_coords_fmt_degree_eng=度(英語) lp_coords_fmt_degree_local=度(本地) lp_coords_fmt_degree_min_eng=度 分(英文) lp_coords_fmt_degree_min_local=度 分 (本地) lp_coords_fmt_degree_min_sec_eng=度 分 秒 (英語) lp_coords_fmt_degree_min_sec_local=度 分 秒 (本地) lp_coords_fmt_tile=地圖塊 (x/z 或 y/z) lp_coords_invalid_text=無效坐標!
請輸入 %s 到 %s 之間的數字 #map source lp_map_source_title=地圖源 lp_map_source_combo_tips=選擇地圖源 #zoom level lp_zoom_title=縮放比例 lp_zoom_total_tile_count_tips=圖片塊總數 lp_zoom_number_tips=選取級別 %d 的地圖 lp_zoom_total_tile_title=約 %s 個圖片塊 lp_zoom_total_tile_hint_head=全部圖片塊: lp_zoom_total_tile_hint_row=
等級 %d: %d (%dx%d) #Tile parameters settings lp_tile_param_title=圖片轉換 lp_tile_param_recreate_checkbox_title=圖片保存前轉換 (需要CPU額外計算) lp_tile_param_recreate_checkbox_tips=如果關閉這個選項,服務器下載的圖片將直接保存(速度快) .
\ 否則,圖片會在保存前轉換為指定的大小和格式(速度很慢,依賴CPU). lp_tile_param_width_title=寬度: lp_tile_param_width_tips=圖塊寬度 lp_tile_param_height_title=高度: lp_tile_param_height_tips=圖塊高度 lp_tile_param_image_fmt_title=圖塊格式: lp_tile_param_image_fmt_png=PNG lp_tile_param_image_fmt_png_8bit=PNG 256 色 (8 位) lp_tile_param_image_fmt_png_4bit=PNG 16 色 (4 位) lp_tile_param_image_fmt_jpg_q100=JPEG - 品質系數 100 lp_tile_param_image_fmt_jpg_q99=JPEG - 品質系數 99 lp_tile_param_image_fmt_jpg_q95=JPEG - 品質系數 95 lp_tile_param_image_fmt_jpg_q90=JPEG - 品質系數 90 lp_tile_param_image_fmt_jpg_q85=JPEG - 品質系數 85 lp_tile_param_image_fmt_jpg_q80=JPEG - 品質系數 80 lp_tile_param_image_fmt_jpg_q70=JPEG - 品質系數 70 lp_tile_param_image_fmt_jpg_q60=JPEG - 品質系數 60 lp_tile_param_image_fmt_jpg_q50=JPEG - 品質系數 50 lp_tile_param_msg_valid_height=圖片塊高度只能在 %d 到 %d 之間.\n lp_tile_param_msg_valid_width=圖片塊寬度只能在 %d 到 %d 之間.\n #atlas content lp_atlas_title=當前地圖冊 lp_atlas_new_btn_title=新建地圖冊 lp_atlas_add_selection_btn_title=添加選擇的區域 lp_atlas_name_label_title=新建地圖名字: lp_atlas_name_field_tips=輸入一個地圖名字 # this one only support English #lp_atlas_element_default_name=Layer #atlas content detail - Atlas lp_atlas_info_atlas_title=地圖冊
lp_atlas_info_atlas_name=名字: %s
lp_atlas_info_atlas_layer=地圖層個數: %d
lp_atlas_info_atlas_format=地圖冊格式: %s
lp_atlas_info_max_tile=最大圖片塊個數: %d
lp_atlas_info_area_start=區域開始: %s %s
lp_atlas_info_area_end=區域結束: %s %s
#atlas content detail - Layer lp_atlas_info_layer_title=地圖層
lp_atlas_info_layer_map_count=地圖個數: %d
#atlas content detail - Map lp_atlas_info_map_title=地圖
lp_atlas_info_polygon_map_title=多邊形地圖
lp_atlas_info_polygon_map_point=多邊形點數:
lp_atlas_info_map_source_short=地圖源: %s
lp_atlas_info_map_source=地圖源: %s (%s)
lp_atlas_info_map_zoom_lv=縮放級別: %d
lp_atlas_info_map_area_start=區域開始: %s (%d / %d)
lp_atlas_info_map_area_end=區域結束: %s (%d / %d)
lp_atlas_info_map_size=地圖大小: %d x %d 像素
lp_atlas_info_tile_size=圖片塊大小: %d x %d
lp_atlas_info_tile_format=圖片塊格式: %s
lp_atlas_info_tile_format_origin=圖片塊格式: 256x256 (無處理)
#atlas content node pop menu lp_atlas_pop_menu_show_detail=顯示詳細信息 lp_atlas_pop_menu_display_select_area=顯示下載區域 lp_atlas_pop_menu_select_map_box=選擇該地圖所在區域 lp_atlas_pop_menu_zoom_to_map_box=縮放到邊界 lp_atlas_pop_menu_zoom_to=縮放到自身 lp_atlas_pop_menu_renmae=重命名 lp_atlas_pop_menu_apply_tile_process=應用圖片轉換 lp_atlas_pop_menu_clear_atals=清除整個地圖冊 lp_atlas_pop_menu_delete_node=刪除 lp_atlas_default_tip=使用右鍵菜單來查看所有的節點命令. #Profile lp_atlas_profile_title=地圖冊配置 lp_atlas_profile_combo_tips=選擇一個地圖冊配置\n 或者輸入新的名字來保存地圖冊配置 lp_atlas_profile_delete_btn_title=刪除配置 lp_atlas_profile_delete_btn_tips=從配置列表中刪除地圖冊 lp_atlas_profile_save_btn_title=保存當前配置 lp_atlas_profile_save_btn_tips=保存當前地圖冊的配置 lp_atlas_profile_load_btn_title=載入配置 lp_atlas_profile_load_btn_tips=載入選擇的地圖冊配置 lp_atlas_profile_refresh_btn_tips=刷新地圖冊配置列表 lp_atlas_profile_msg_ask_name=請輸入一個配置名稱 lp_atlas_profile_msg_overwrite_confirm_title=覆蓋確認 lp_atlas_profile_msg_overwrite_confirm=同名地圖冊配置 %s 已經存在,要覆蓋它嗎? #main button lp_mian_create_btn_title=開始下載地圖冊 lp_main_create_btn_tips=開始下載地圖冊 lp_main_setting_button_title=設置 lp_main_setting_button_tips=打開偏好設置對話框 #tile store coverage lp_tile_store_title=本地緩存 lp_tile_store_title_tips=顯示當前地圖源的已下載(緩存)區域
\ 已下載緩存可以離線查看或者作為地圖源制作新地圖 lp_tile_store_show_coverage_btn_title=顯示已緩存區域 lp_tile_store_show_coverage_btn_tips=顯示當前地圖源在指定級別下
\ 已經下載到本地的地圖數據範圍,
\ 綠色:表示已經下載到本地緩存的區域,
\ 灰色:表示沒有下載的區域. lp_tile_store_hide_coverage_btn_title=取消顯示 lp_tile_store_zoom_combo_tips=選擇緩存區域的縮放級別 lp_tile_store_zoom_title=縮放級別: lp_tile_store_layer_title=地圖源圖層: #---------- GPX Panel ------------------------- rp_gpx_new_gpx=新建GPX rp_gpx_load_gpx=載入GPX rp_gpx_save_gpx=保存GPX rp_gpx_clear_gpx=清除列表 rp_gpx_add_wpt=添加路點 rp_gpx_default_node_name=已載入GPX檔案... rp_gpx_pop_menu_delete_element=刪除節點 rp_gpx_pop_menu_rename_element=重命名節點 rp_gpx_menu_rename=重命名 rp_gpx_menu_delete=刪除 rp_gpx_msg_confim_delete_title=刪除節點 rp_gpx_msg_confim_delete=您確認要刪除這個節點嗎? rp_gpx_rename_element_title=請輸入名稱: rp_gpx_msg_can_not_rename_track=Track段的名稱不支持修改。 rp_gpx_msg_ask_create_new=尚未選擇GPX任何檔案,希望新建一個GPX檔案嗎? rp_gpx_msg_ask_create_new_title=添加路點到GPX檔案? rp_gpx_msg_add_point_failed=路點只能加入到GPX檔案根節點、route段以及Track段下。 rp_gpx_root_default_name_nofile=未命名 (新建GPX) rp_gpx_root_default_name_hasfile=未命名 (檔案 %s) rp_gpx_unname_route_name=未命名 route rp_gpx_unname_track_name=未命名 track rp_gpx_unname_wpt_name=未命名 waypoint rp_gpx_msg_confirm_reopen_file=GPX檔案已經被打開,您希望再次打開這些檔案嗎? rp_gpx_msg_error_save_gpx_file=保存GPX檔案出錯 rp_gpx_msg_no_select_file=很抱歉,您尚未選擇GPX檔案 rp_gpx_node_seg_name=線路段 %s #---------- Main Menu ------------------------- #Atlas menu_atlas=地圖冊 menu_atlas_new=新建地圖冊 menu_atlas_convert_format=轉換地圖冊類型 menu_atlas_create=開始下載地圖冊 #Maps menu_maps=地圖 menu_maps_selection=選擇區域按 menu_maps_selection_rect=矩形 menu_maps_selection_polygon=多邊形 menu_maps_selection_circle=圓 menu_maps_selection_add=添加選擇的區域 menu_maps_selection_add_by_gpx=添加GPX沿線區域 #Bookmark menu_bookmark=書簽 menu_bookmark_save=保存當前顯示區域 menu_bookmark_manage=管理書簽 #Panels menu_panels=面板 menu_show_hide_left_panel=顯示/隱藏 左側面板 menu_show_hide_gpx_panel=顯示/隱藏 GPX面板 #Debug menu_debug=高級 menu_debug_show_hide_tile_border=顯示/隱藏 圖片邊框 menu_debug_show_all_map_source=顯示所有地圖源 menu_debug_refresh_map_source=刷新自定義地圖源 menu_debug_show_log_file=查看日誌檔案 menu_debug_log_level=日誌級別 menu_debug_system_report=查看系統信息 #help menu_help=幫助 menu_help_readme=幫助文檔 menu_help_how_to_preview=如何查看地圖 menu_help_licenses=版權聲明與許可證 menu_help_about=關於 #tools menu_tool=工具 #---------- Dialog ------------------------- #About dlg_about_title=關於 dlg_about_version=版本: dlg_about_program_version=開發版本: dlg_about_download_mapplus=下載地圖加加 dlg_about_download_mapplus_url=https://itunes.apple.com/cn/app/id438868200?mt=8 #Font choose dlg_font_choose_title=選擇字體 dlg_font_choose_preview=預覽 dlg_font_choose_name=名稱 dlg_font_choose_style=風格 dlg_font_choose_size=大小 #Licenses dlg_license_title=版權聲明與許可證 #Help dlg_help_title=幫助 #Manager Bookmark dlg_mgn_bookmark_title=管理書簽 dlg_mgn_bookmark_delete=刪除書簽 #Bookmark Add dlg_add_bookmark_msg=請為新建書簽設置一個名字 #New Atlas dlg_new_atlas_title=新建地圖冊 dlg_new_atlas_name_title=新建地圖冊名字: dlg_new_atlas_default_atlas_name=我的地圖冊 dlg_new_atlas_select_format_title=請選擇地圖冊類型 #Working Progress dlg_progress_title=完成 dlg_progress_about_btn=關於 dlg_progress_count=已完成: 0 dlg_progress_count_i=已完成: %d #Select GPX Track dlg_gpx_track_select_title=設置區域寬度 dlg_gpx_track_select_distance=設置邊沿到線路中心線的距離: %d %s #Add GPS point dlg_gpx_inpu_point_name=請為該點輸入一個名字: #Show All Map Source dlg_show_source_title=全部地圖源 dlg_show_source_column_name=名稱 dlg_show_source_column_display_text=全稱 dlg_show_source_column_rev=內部版本號 dlg_show_source_column_type=類型 #Select Dir dlg_select_dir_title=選擇檔案夾 dlg_select_dir_description=檔案夾 #Atlas download progress dlg_download_title=正在創建地圖冊 dlg_download_zoom_level_progress=正在下載縮放等級: dlg_download_map_progress=正在下載地圖: dlg_download_atlas_progress=%d%% 已完成 - 當前地圖冊: %s, 類型: %s dlg_download_done_percent=%d%% 已完成 dlg_download_done_tenthpercent=%.1f%% 已完成 dlg_download_window_title=

正在創建地圖冊...

dlg_download_map_info_label_default=正在下載地圖 ABCDEFGHIJKLMNOPQRSTUVWXYZ-nn, 圖層 ABCDEFGHIJKLMNOPQRSTUVWXYZ, 地圖源 ABCDEFGHIJKLMNOPQRSTUVWXYZ dlg_download_map_info_label=正在下載地圖 %s 的圖層 %s , 從地圖源: %s dlg_download_map_done_count_default=已完成000, 共 000 dlg_download_map_done_count=已完成%d, 共 %d dlg_download_remain_time_default=剩余時間: 00000 分 00 秒 dlg_download_remain_time=剩余時間: %s dlg_download_tile_done_count_default=已下載圖片 1000000, 共 1000000 塊 dlg_download_tile_done_count=已下載圖片 %d 塊,共 %d 塊 dlg_download_map_create_title=創建地圖檔案 dlg_download_avg_speed=平均下載速度 dlg_download_avg_speed_value=: %s / 秒 dlg_download_total_bytes=從地圖源下載 dlg_download_bytes_from_cache=從本地緩存讀取 dlg_download_thread_count=當前使用線程數 dlg_download_retry_count=臨時出錯圖片 dlg_download_retry_count_value=: 當前地圖: %d 次, 總共: %d 次 dlg_download_failed_count=無法下載圖片 dlg_download_failed_count_value=: 當前地圖: %d 次, 總共: %d 次 dlg_download_error_tips=

地圖下載的出錯次數(臨時出錯/無法下載)。

\

下載某個圖片失敗時,系統會重試2次,如果第二次重試時
\ 仍然無法下載. 則會標記為出錯塊, 並且在本次地圖
\ 下載過程中不會對其進行再次下載

dlg_download_total_time=下載時間 dlg_download_checkbox_ignore_error=忽略下載錯誤並自動繼續 dlg_download_status_title=狀態: dlg_download_status_running=運行中 dlg_download_status_aborted=終止 dlg_download_status_finished=完成 dlg_download_status_paused=暫停 dlg_download_btn_abort=終止下載 dlg_download_btn_abort_tips=終止地圖冊的下載 dlg_download_btn_close_win=關閉窗口 dlg_download_btn_close_win_tips_disable=地圖冊正在下載中... dlg_download_btn_close_win_tips_enable=關閉地圖冊下載窗口 dlg_download_btn_open_folder=打開下載檔案夾 dlg_download_btn_open_folder_tips_disabled=地圖冊正在下載中... dlg_download_btn_open_folder_tips_enabled=打開地圖冊下載保存的檔案夾 dlg_download_btn_pause_resume=暫停/恢復 dlg_download_time_unknown=未知 dlg_download_abort_title=地圖冊下載已終止 dlg_download_abort_window_title=

地圖冊已經被用戶終止下載

dlg_download_succeed_title=地圖冊下載已成功 dlg_download_succeed_window_title=

地圖冊以成功完成

dlg_download_errors_todo=下載地圖圖片出錯多個錯誤 - 您希望如何處理? dlg_download_errors_todo_msg=多個地圖圖片下載失敗. \ 您當前連接的地圖服務器或者選擇的下載區域可能存在問題. \
您希望:

\ 繼續 下載,並忽略遇到的圖片錯誤? (將導致部分圖塊空白/丟失)
\ 重試 從頭開始重新下載一遍該本地圖?
\ 跳過 當前地圖所有圖片,進行下一個地圖的下載?
\ 終止 當前地圖和整個地圖冊的所有下載?
dlg_download_errors_missing_tile=錯誤:部分地圖圖片在下載過程丟失,仍然繼續嗎? dlg_download_errors_missing_tile_msg=下載地圖冊存在問題.\n\ 成功下載的地圖圖片數量少於期望下載的圖片數量.\n\ 即地圖冊下載過程中存在圖片的丟失.\n共有 %d 張圖片未成功下載.\n\n\ 你仍然希望繼續整個地圖冊的創建嗎? dlg_download_show_error_report=查看錯誤報告 dlg_download_erro_head=運行出錯: #Splash Frame splash_title=正在啟動 Mobile Atlas Creator 中文版... #---------- Setting ------------------------- set_title=設置 #Display set_display_title=顯示 set_display_unit_system_title=單位 set_display_unit_system_metric=公制單位 set_display_unit_system_imperial=英制單位 set_display_unit_system_scale_bar=比例尺單位: set_display_language=界面語言 set_display_language_choose=選擇界面語言(需重啟): set_display_language_choose_tips=選擇一種語言,需要重啟MOBAC才能生效 set_display_language_restart_desc=您需要重新啟動MOBAC才能使得新語言生效. set_display_language_msg_title=需要重啟 set_display_language_msg=語言修改需要重新啟動MOBAC才能生效,現在就退出MOBAC嗎? set_display_grid=經緯度網格線 set_display_grid_compress=簡化坐標 set_display_grid_compress_tips=選中後,坐標文本將使用簡寫. set_display_grid_title=選擇顏色 set_display_grid_width=線寬: set_display_grid_width_tips=設置繪制寬度 set_display_grid_color=顏色: set_display_grid_color_tips=設置網格線和文本的顏色 set_display_grid_font=字體: set_display_grid_font_tips=設置文本坐標的字體 #Map sources config set_mapsrc_config_title=地圖源設置 set_mapsrc_config_online_update=在線更新地圖源 set_mapsrc_config_online_update_btn=開始在線更新 set_mapsrc_config_online_update_no_update=無可用更新 set_mapsrc_config_online_update_done=更新成功 set_mapsrc_config_online_update_failed=更新失敗 set_mapsrc_config_online_update_msg_outdate=當前版本的 MOBAC 不支持在線更新,\ 請升級到最新版本後再試。 set_mapsrc_config_online_update_msg_noneed=您已經擁有最新版本的地圖包,無需更新。 set_mapsrc_config_online_update_msg_done=%d 個地圖源被更新.\n\ 請重新啟動 MOBAC 來安裝這些更新。 set_mapsrc_config_osmhiking=Reit-und Wanderkarte ($Abo) 地圖設置 set_mapsrc_config_osmhiking_purchased=已支付的 ticket ID: set_mapsrc_config_osmhiking_howto=如果獲取一個 ticket (德語) set_mapsrc_config_osmhiking_howto_url=http://www.wanderreitkarte.de/shop_abo_de.php #Map sources set_mapsrc_mgr_title=管理地圖源 set_mapsrc_mgr_title_enabled=啟用的地圖源 set_mapsrc_mgr_title_disabled=禁用的地圖源 set_mapsrc_mgr_move_up_tips=上移選中的地圖源 set_mapsrc_mgr_move_down_tips=下移選中的地圖源 set_mapsrc_mgr_move_left_tips=啟用選中的地圖源 set_mapsrc_mgr_move_right_tips=禁用選中的地圖源 #Tile Update set_tile_update_title=圖片塊更新 set_tile_update_desc=\ 本地緩存的圖片塊會按此規則在必要時重新下載(更新)
\ 每個圖片塊會首先按地圖服務器預設的有效時間控制更新,
\ 當地圖源服務器沒有提供相關設置,則按照下面設置更新 set_tile_update_default_expiration=默認有效時間 set_tile_update_default_expiration_desc=只有當地圖源未提供有效時間時,
\ 才會使用默認有效時間進行管理. set_tile_update_max_expiration=最大有效時間 set_tile_update_min_expiration=最小有效時間 #Tile Store set_tile_store_title=本地緩存庫 set_tile_store_enable_checkbox=允許使用本地緩存來預覽和下載地圖 set_tile_store_settings=本地緩存設置 set_tile_store_information=信息 set_tile_store_info_mapsrc=地圖源 set_tile_store_info_tiles=已緩存圖片 set_tile_store_info_size=已緩存大小 set_tile_store_info_disabled_subfix= (禁用) set_tile_store_info_delete_tips=刪除所有 %s 的本地緩存圖片. set_tile_store_info_deleteing_tips=正在刪除 - 請稍等... set_tile_store_info_total=緩存大小合計 #Map Size set_map_size_title=地圖大小 set_map_size_settings=地圖大小設置 set_map_size_max_size_of_rect=矩形選區對應的地圖最大寬度或高度: set_map_size_overlap_tiles=地圖區域的圖片塊疊加個數: set_map_size_desc=\ 如果矩形選區的長或者寬超出設置的最大大小,
\ MOBAC會在您添加區域到地圖冊的時候,
\ 自動拆分區域為多個子地圖,以保證每個子地圖的大小
\ 都會小於設置的最大地圖大小.
\ 註意:該設置對多邊形選區無效,對於已經添加的選區也無效
\ 您可以在地圖冊的樹型結構中查看當前地圖的大小.
\
\ 使用TrekBuddy用戶請註意:
\ TrekBuddy 在 v0.9.88 版本之前不支持地圖大於 32767.
\ 之後版本可以支持大小在 1048575 以內的地圖. #Directory set_directory_title=檔案夾 set_directory_output=地圖冊導出檔案夾 set_directory_output_tips=如果設置為空,則使用默認檔案夾:
%s set_directory_output_select=重新選擇 set_directory_output_select_dlg_title=選擇檔案夾 #Network set_net_title=網絡 set_net_connection=網絡連接 set_net_connection_desc=同時運行的下載連接數 set_net_bandwidth_desc=下載帶寬限速 set_net_bandwidth_unlimited=無限制 set_net_proxy=HTTP 代理 set_net_proxy_settings=代理設置: set_net_proxy_settings_java=使用Java代理設置 set_net_proxy_settings_application=使用應用的代理設置 set_net_proxy_settings_custom=用戶自定義 set_net_proxy_settings_custom_auth=用戶自定義(帶認證) set_net_proxy_host=代理服務器: set_net_proxy_port=端口: set_net_proxy_username=用戶名: set_net_proxy_password=密碼: set_net_default=默認 set_net_default_ignore_error=下載時忽略錯誤並繼續下載 #Paper Atlas set_paper_title=頁面設置 #Paper Atlas - Size set_paper_size=大小 set_paper_size_default=默認 set_paper_size_default_tips=選擇該選項, 則頁面大小由指定的格式決定. set_paper_size_default_combo_tips=選擇一個默認的頁面格式 set_paper_size_default_landscape=橫向排版 set_paper_size_default_landscape_tips=選擇該選項,頁面方向為橫向。 set_paper_size_custom=自定義 set_paper_size_custom_tips=選擇該選項,用戶可以手工指定頁面大小 set_paper_size_custom_width=寬度: set_paper_size_custom_width_tips=指定頁面寬度. set_paper_size_custom_height=高度: set_paper_size_custom_height_tips=指定頁面高度 set_paper_size_selection=選擇區域 set_paper_size_selection_tips=選擇該選項,頁面按地圖的大小區域決定 #Paper Atlas - Additions set_paper_additions=附加 set_paper_wgs_grid=經緯度網格線 set_paper_wgs_grid_tips=如果選擇,將會打印經緯度格線(WGS-64) set_paper_wgs_grid_density_tips=選擇經緯度網格線密度 set_paper_paper_nubmer=頁面編號 set_paper_paper_nubmer_tips=選擇該選項,頁碼編號將會打印在每一頁 set_paper_scale_bar=比例尺 set_paper_scale_tips=選擇該選項,比例尺將會打印在地圖上 set_paper_compass=指南針 set_paper_compass_tips=選擇該選項,指南針將會打印在地圖上 #Paper Atlas - Margins set_paper_margins=縮進 set_paper_margins_tips=指定縮進的尺寸 set_paper_margins_top=上: set_paper_margins_left=左: set_paper_margins_bottom=下: set_paper_margins_right=右: #Paper Atlas - Advanced set_paper_advanced=高級 set_paper_advanced_compression=壓縮: set_paper_advanced_compression_tips=指定PDF文檔的壓縮級別.
\ 0 表示不壓縮, 9 表示最大壓縮.
\ 數字越大,壓縮比例越高,默認為6. set_paper_advanced_dpi=分辨率 set_paper_advanced_dpi_tips=指定圖片的分辨率 (DPI) .
\ 一般地,更高的值意味著更好的視覺效果.
\ 默認值為 96, 可以提升到120以獲得更好的效果,
\ 但請註意:您的PDF閱讀器也須以相當的分辨率來顯示
\ 才能獲得最佳效果 set_paper_advanced_overlap=重疊: set_paper_advanced_overlap_tips=指定相鄰兩個頁面的重疊區大小. set_paper_advanced_crop=裁剪: set_paper_advanced_crop_tips=指定裁剪的百分比.
\ 超過這個比例位置的頁面邊界將會被裁剪掉 #Paper Atlas - Actions set_paper_actions=操作 set_paper_actions_import_xml=從XML導入 set_paper_actions_import_xml_tip=從XML導入所有頁面設置 set_paper_actions_export_xml=導出到XML set_paper_actions_export_xml_tip=導出所有頁面設置到XML檔案 set_paper_actions_restore_default=恢復到默認值 set_paper_actions_restore_default_tips=重置全部頁面設置為默認值
\ 所有當前的設置的參數將會被覆蓋. set_paper_actions_error_import=無法導入頁面設置檔案: set_paper_actions_error_export=無法導出到頁面設置檔案: set_paper_actions_error_reason=原因: set_paper_actions_error_title=發生錯誤! set_paper_actions_xml_filter=XML 檔案 (*.xml) #Error set_error_saving_title=保存設置出錯 set_error_saving_msg=無法保存設置到檔案:\n ( %s ) #---------- Message ------------------------- #common msg_no_zoom_level_selected=請至少選擇一個縮放級別 msg_no_select_area=請選擇一個區域 #Add GPX Track Polygon msg_add_gpx_polygon_too_many_track=當前選擇檔案包含不止一條線路\n請選擇其中一條線路(track)或線路段(segment)。 msg_add_gpx_polygon_too_many_segment=當前選擇的線路包含不止一條線路段(segment)\n請選擇其中一條線路段(segment)。 msg_add_gpx_polygon_no_select=沒有選擇GPX線路(track)或線路段(segment) msg_add_gpx_polygon_maxsize_title=超出最大地圖尺寸 msg_add_gpx_polygon_maxsize=至少一個地圖超出了最大尺寸,\n\ 但本程序暫不支持多邊形區域的自動拆分,\n您仍然希望繼續嗎? #Convert Atlas msg_convert_atlas_format=轉換地圖冊格式 msg_convert_incompatible_format=地圖和地圖冊的格式不兼容 #Log file msg_no_log_file_config=沒有配置的日誌檔案 msg_no_log_file=日誌檔案不存在:

%s #Setting msg_settings_write_error=寫入設置信息到"settings.xml"時出錯 #Refresh msg_refresh_all_map_source_done=%d 個自定義地圖源被成功刷新 #Help msg_no_found_readme_file=不能找到檔案:README.HTM #Merge Layer msg_confirm_merge_layer_title=確認合並地圖層 msg_confirm_merge_layer=您確定要將地圖層 %s 合並到 %s 嗎? msg_merge_layer_failed=圖層合並失敗 #Tile Size select msg_invalid_tile_size=無效的圖片塊大小!
請輸入 %d 到 %d 之間的數 #Tile Store Coverage msg_tile_store_failed_retrieve_coverage=無法顯示本地緩存的覆蓋範圍.\n\ 可能是因為選擇的區域過大或者縮放級別過大. #Atlas download thread msg_out_of_memory_title=存儲體不足. msg_out_of_memory_head=Mobile Atlas Creator沒有足夠存儲體繼續運行. msg_out_of_memory_detail=\n當前分配給MOBAC的最大存儲體數為 %d MB msg_atlas_download_abort=地圖冊下載已經被終止 msg_too_many_tiles_title=無法進行地圖冊下載 msg_too_many_tiles_msg=Mobile Atlas Creator 檢測到您即將\n\ 下載的地圖冊擁有遠遠超出常規數目的圖片塊數量,\n\ 請減少在高縮放級別時選擇的地圖區域大小,並重新下載.\n\ 最大允許的地圖圖片塊數為: %d\n\ 當前地圖冊中的圖片塊數為:%d msg_atlas_version_mismatch=當前打開/加載的地圖冊是MOBAC早期版本創建的,\n\ 該版本與當前版本的存儲格式無法兼容。\n\n\ 建議您清除掉整個地圖冊,並刪除受影響的地圖冊保存檔案,\n\ 否則在使用相關地圖冊時,可能出現更多異常情況.\n msg_atlas_data_check_failed=載入保存的地圖冊時出現錯誤。\n\ 這可能是因為檔案被修改或者格式不兼容造成的,\n\n\ 建議您清除掉整個地圖冊,並刪除受影響的地圖冊保存檔案,\n\ 否則在使用相關地圖冊時,可能出現更多異常情況.\n #Settings msg_setting_file_is_changed_by_other_title=覆蓋已修改內容? msg_setting_file_is_changed_by_other=參數檔案 settings.xml 已經被其它程序修改.\n\ 您希望覆蓋其它程序的修改嗎?\n\ 當覆蓋後,其它程序所作的所有修改都會被清除! msg_settings_file_can_not_parse=無法讀取或解析設置檔案,程序將會退出。 #Others msg_atlas_is_empty=地圖冊為空,請首先為地圖冊添加一個區域 msg_environment_not_support_title=不支持平臺 msg_environment_not_support=不支持您的運行環境.
桌面平臺: %s
操作系統: %s msg_environment_failed_open_output_title=打開地圖冊檔案夾失敗 msg_environment_failed_open_output=打開地圖冊輸出檔案夾失敗.
msg_environment_use_commond=
使用命令: %s
msg_environment_commond_param=參數: %d : %s msg_environment_lack_memory_title=警告: 存儲體設置過小 msg_environment_lack_memory=\ 警告: Mobile Atlas Creator 在運行時允許使用的存儲體過小.
\ 當前Mobile Atlas Creator 最大可用存儲體僅為: %s.

\ 請確認您使用了正確啟動程序或腳本來運行MOBAC:
\ 對於Window系統,請使用Mobile Atlas Creator.exe
\ 對於Linux/Unix/OSX系統,請使用 start.sh 腳本,
\ 腳本參數:-Xmx 512M 可指定512M最大可用存儲體.

\ 例如: java -Xmx512M -jar Mobile_Atlas_Creator.jar
\
Mobile Atlas Creator將在您確定後繼續運行
msg_environment_error_create_dir=創建檔案夾 %s 出錯,檔案夾路徑 %s\n 程序將退出. msg_environment_error_write_file=無法寫入到檔案:\n %s \n路徑:%s \n 請修改檔案權限並重啟MOBAC. msg_environment_error_create_setting=無法寫入到設置檔案settings.xml, 程序將退出. msg_environment_error_init_mapsrc_dir=無法初始化地圖源檔案夾:\n msg_environment_error_load_cloudmade=無法載入自定義的CloudMade 地圖源. 請確保openstreetmap地圖源包完好可用. msg_environment_mapsrc_dir_not_exist=地圖源檔案夾不存在 - 位置:\n %s \n\ 請確保您在解壓縮MOBAC的zip包時,\n\ 包含了所有的子檔案夾. msg_environment_unable_to_start=無法啟動Mobile Atlas Creator: \n msg_environment_jre_bellow=您電腦上安裝的Java環境(Java Runtime Environment)版本過低.\n\ Mobile Atlas Creator 需要至少Java 6 (1.6) 或更高版本.\n\ 請升級您的Java運行時環境,再重啟Mobile Atlas Creator.\n\n\ 當前檢測到的 Java 版本為: %@ msg_environment_jre_bellow_title=Java運行環境不兼容 msg_environment_invalid_source_folder=指定的地圖源檔案夾不存在:\n地圖名: %s\ \n地圖源檔案夾: %s msg_environment_invalid_source_folder_zoom=無法找到指定縮放等級的檔案夾:\n地圖名: %s\ \n地圖源檔案夾: %s msg_environment_invalid_source_folder_title=無效地圖源檔案夾 msg_tools_exec_command_ask=要執行的命令行:
%s msg_tools_exec_command_ask_title=您希望執行該命令嗎? msg_custom_map_invalid_source_file_title=無效地圖源檔案 msg_custom_map_invalid_source_file=指定數據庫檔案不存在.\n地圖名: %s \n檔案名: %s msg_custom_map_invalid_source_zip_title=無效的zip源 msg_custom_map_invalid_source_zip=指定的zip地圖源檔案不存在:\n地圖名: %s \nZip 檔案: %s msg_custom_map_failed_open_source_zip_title=讀取zip檔案失敗 msg_custom_map_failed_open_source_zip=無法讀取指定的地圖源zip檔案:\n地圖名: %s \nZip 檔案: %s msg_custom_map_invalid_source_sqlitedb=指定的 SQLite 數據庫檔案不存在:\n地圖名: %s \n檔案名: %s msg_custom_map_source_failed_load_sqlitedb_title=加載數據庫檔案出錯 msg_custom_map_source_failed_load_sqlitedb=指定的數據庫檔案無法被加載:\n地圖名: %s\ \n檔案名: %s \n錯誤信息:%s msg_update_map_pack_error_title=加載地圖包出錯 msg_update_map_pack_error=在加載升級的地圖包時出現錯誤,請重新啟動 MOBAC 來恢復到之前的版本。 msg_error_load_atlas_profile_title=加載地圖冊出錯 - 繼續嗎? msg_error_load_atlas_profile=加載地圖冊出錯:
 %s 
\
檔案: %s 行/列: %d / %d
\ 您希望繼續加載該地圖冊嗎?
\ 這可能導致地圖冊不完整或者無法正常工作.
msg_environment_slqite_lib_missing_title="出錯 - SQLite 庫不可用" msg_environment_slqite_lib_missing=無法找到SQLite庫檔案. \ 您當前的地圖冊格式必須Sqlite庫才能運行.
請查閱幫助檔案 README.HTM \ 的"SQLite atlas formats"章節獲得更多幫助. " msg_environment_image_format_not_available_title=圖片格式不支持 - 缺少圖片庫 msg_environment_image_format_not_available=該檔案格式需要安裝額外的Java圖片處理庫:
\ Java Advanced Image library (jai_core.jar & jai_codec.jar)
\ 更多信息請查看幫助檔案 README.HTM \ 中的 Requirements章節. msg_tile_store_access_conflict_title=運行沖突 msg_tile_store_access_conflict=\ 多個 Mobile Atlas Creator 正在試圖同時訪問\n\ 相同的本地地圖緩存,本地地圖緩存只能同時有一個MOBAC\n\ 實例訪問.請關閉其它MOBAC程序實例後再試.\nmobile-atlas-creator-1.9.14+dfsg1/src/main/resources/mobac/resources/text/help_dialog_zh.html0000644000175000017500000000212012127544350032164 0ustar paulliupaulliu

快捷键 & 鼠标操作

F5 刷新地图显示 (重新载入缺失的地图块)
<光标箭头(上下左右)> 移动地图
[拖动鼠标右键] 移动地图
<ctrl> + <鼠标左键> 移动地图 (仅限OSX系统)
<ctrl> + <光标上箭头> 放大
[双击鼠标左键] 放大
[鼠标滚轮 上] 放大
<ctrl> + <光标下箭头> 缩小
[鼠标滚轮 下] 缩小
<ctrl> + <光标左箭头> 上一个地图源
<ctrl> + <光标右箭头> 下一个地图源
[拖动鼠标左键] 选择下载区域
mobile-atlas-creator-1.9.14+dfsg1/src/main/resources/mobac/resources/cert/0000755000175000017500000000000012122526606026303 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/resources/mobac/resources/cert/MapPack.cer0000644000175000017500000000067112122526606030316 0ustar paulliupaulliu00L 0  *H 010UMOBAC MapPack Signer0 101206105922Z 151205105922Z010UMOBAC MapPack Signer00  *H 0$kNvT>NQ^+0_,BkaS".hEj>Wg0 0FwfZZ5pwQ"/8PtXeY39]2gQ0  *H .}m%ktĺviDӏӟ>R[Jh7=GɱvQ L=CY ǻgFȼ.̓'0uDϨgƯ2T~wW6aD!cɥmobile-atlas-creator-1.9.14+dfsg1/src/main/resources/mobac/resources/images/0000755000175000017500000000000012122526606026613 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/main/resources/mobac/resources/images/refresh.png0000644000175000017500000000251512122526606030762 0ustar paulliupaulliuPNG  IHDR(-SsRGBgAMA a cHRMz&u0`:pQ<PLTE+h(k/r6u7w7x9u%o#t#y$}%~6@@A쉫ٕ؋ btRNSS%tEXtSoftwarePaint.NET v3.36%IDAT(S= PA*VdQ_RV39db 3ơ3c˟y y H>Pw+;4ÈTKMEI4uR' dص4j ©7M8V#\ʺAxoŌIENDB`mobile-atlas-creator-1.9.14+dfsg1/src/main/resources/mobac/resources/images/error.png0000644000175000017500000001304412122526606030454 0ustar paulliupaulliuPNG  IHDR\rfsRGBgAMA a cHRMz&u0`:pQ< pHYsPPs[tEXtSoftwarePaint.NET v3.22}iIDATx^ Uu Z TEѴ28!8"!8OrXFE<&b>JLH!eezHقq>@U=|i>5]D>z4wiqxUgp=?8J;|V 8Y$=j qrǟ 88|UcH{8.~;p> qw@pq܁'H{8.>g?!@pqq>p\,w| Y5gOp\|>~Ϫ1$=?8B;|V 8Y$=j qrǟ 88|UcH{8.~;p> qw@pq܁'H{8.>g?!@pqq>p\,w| Y5gOp\|>~Ϫ1$=?8B;|V 8Y$=j qrǟ 88|UcH{8.~;p> qw@pq܁'H{8.>g?!@pqq>p\,w| Y5gOp\|>~Ϫ1$=?8B\Z575Znl.6p/][wmklWۢf7c*z*|ͅ6'*zr\]m@@*u# *귖w˪]d~B&:~R\C]dY`}A _BI @kM_1m%g{!붔+0ГUS/u{yya.}eBZX\`ר_*~uTs^~[!dž*)$-}K_.W>B^#33k6Y a+:@@P޲粹 埳f[{.?WSkzlM\VE'4B̆Pv(į?}/u5{c%f,))5u*LQG'{k Ӏ@>/ty1K_,9S~tysg k ruS!9Mu_EpzHY5YڿQ $ד*1)knP,{_3ӧ_?_6HRiu]SmrE `+ЃdC˒~ rB@/״T_ͭ:loL_8Mrsϕׇ*O))No+9gWn*Skdo+u'+ug>;S[gO(Ouz׊ē؋<%8~*9:V}v_&#~uiP˹$`kuC.V}6O~s䭳Β?y:tH!pB@z0< 9&9@%&qlGrB`BV}6_3ʙ3&&MWv/KJ_ݵ7L29vzI_W#*l_o}_R\=lڟ?y9yvŐ~ҪE6/|/M7׊|_/M" Xlo+=[=UMmW|_&o&,u{71߻W-@ʟmo+=[=UMm)SO7&$?A|_ ?/o?OġG,d|%tL!`>38YswL_I}T^Cc_2@@*/W\xR!`> zq qGsCvzl {  +bW@':سUMm_yU˱c|~ooW'Sz -a` WI=}[٪ϦoZ_Tə?('D R)}o [ٴ?=W3_-\/ "]c [ٴ~!uszՈ ?9$_V/ҝUM6W#zA~ƚbYGtg>oMg8OP Oq'.R؎V}iY2`4U?!DTR觸 9 wtg_>SҪ``@~ %M:~E}?!?Н]gI=/1l @dpןOo?{*}foyd^rB`B`B4 D@OGR<ߞxrB@Smu2a[@ID~k{H?G_S+E;m+m#hJ]G_/n!?Q[5`MrB`| b_*|sC;ZCdUvzT'@p30Lv뽶UMm% % (]nh=zT8POU1U/l{ۙOw?non=lg~̿ſcu~rd~]ߦJߦ*W B_OWnߎtg>_ݣ|uuUrB8@ TtR>v$}U!`>>;w |rM}dl$J `߰Lgn[u6?ϯ _'jlo"~A}eBUrB( PIT-ey^1]ҳmlo3n`.MrW߭JӍ$PIup~*{g|[MW1V}6_wml;l)sGw#U%@P%C^ӕ=tgtW̿ůd@ܯOWDS^X_3M˗5l-/9s_U!ktoiq~OT w:LX-:#U+@6Zr]KGh M}oU rkSW @o { T`Q`۷y "/YzHY_Yįc mo>m⟣>=:gW,NW P!&y~koΈ#^lgt_.~{GRR@`EOq/S D޲jrԁ!ˊ'E󗻜Hlg{~[ٴ~8 R VDW٫ȗoT/]*~{GN`+=[]UMӁ_1? Wm~ A_wKR؞V}6X1N_ѕM!pCWaB?z63_Ul_z k=_#f0GaqǴ?~_¿Zײ9{y7.vAA>|pqq|\4 qٹ| $=ECp\k'@pqq|\4 qٹ| $=ECp\k'@pqq|\4 qٹ| $=ECp\k'@pqq|\4 qٹ| $=ECp\k'@pqq|\4 qٹ| $=ECp\k'@pqq|\4 qٹ| $=ECp\k'@pqq|\4 qٹ| $=ECp\k'@pqq|\4 qٹ| $=ECp\k'@pqq|\4 qٹ| $=ECp\k'@pqq|\4 qٹ| $=ECp\k'@pqq|\4 qٹ| $=ECp\k'@pqq|\4 qٹ| $=ECp\k'@pqq|\4 qգG?>z4la>{=zqIENDB`mobile-atlas-creator-1.9.14+dfsg1/src/main/resources/mobac/resources/images/hourglass.png0000644000175000017500000002161012122526606031330 0ustar paulliupaulliuPNG  IHDR>gAMA a pHYs;;,q˵tEXtSoftwarePaint.NET v3.317w#IDATx^ XUSAP0]-/x xAxA%EQD$"&2&cE~SGjLe}rACšp{wk}-G$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$@$Py T[~[s('cUrWW2׈5׎0TN$ `$T5T5M_rrsm[Fy$pÈ`d0*U];l?2׀uj9 ."6P7?gLj`P0{T;>iߗG\ wzBF A1Fø`TQ=cjB6j?ҟjϚσq~\êD_ !SB@! 1B}xkUXſm.ujPjA5U&׬ uE}-QjTT'Mw|Ǜt%1h]OjUc\]:"4/D4OPv>r{nw5C&OowYUkҌӆ+PQASG  7@%`GASҢI,F;D +'{qѢICZȯQZHF>VV!G $0M?@%`7~^}A=_CJ6AUɫ;wVFx7ZeG'U;!@?B$6i獃@iƏܪWV뚺Iukl6Mejoj&PMNuн{uo}FMShֶVi;nxψK^lyЅ|n♳6ke'UhROUGTc8g8k-{ ` zn{Rz^^V-hz#݂zvtt g=(9ji]+~_'Sg_4]t:R-[UQj*Z5_5[5U5Q5V9U?Uw~>$p Ə0=U?o Uj*X`ǽ-V?=Qj0τ5pC??20 4Oz8 o;Ic~$HRN>sZlwJ6杔ukm Y(,V(QG%ZuwD?G_' a| *>0ԇ?Gբc>sg1}h94Ca\02a;!6vicJG VSVW,F}=-Q2:T^*x~?x9:tG_ݧ)8O[ba+=F]"FqNyz/FG.?2!=|I:ػ7|'xȼ,,a#z=O}G!Vp&` ߤ@$g}~ ;PV^6(CH1 v&r0Əh:8g'}j !yyCamz iV1(Ҍ9T3V?oPq:֏ ?*;K0a?Kx%-$P[kPSё/#/Ac[U~ZoMI{Uz ܃I=Ha!Pq>gL3xSxUv{~3# ٹ_Zˏ~t0rG}?f%,4cj5= v`b1}(AY2jL5OD@%`MaX00Z;o7􅅹ؖsP(?~\RTVֿ?G.L'kuzQM:;E ?[Pz:Ju8Wy[yUZ=m8`v/ړ/rq)d:/uЫ:7%_$%1l{&0!?M>O㯀~os7߽G]F})ŭὙRx$O VvOɆ:23̫~.i~INN:{(V6!s3oyRTXzƩ0g>,mWw^~fO1:؎x7C׌Yvk$L9fݵV2$'#Aw$I֎ܾY236IfzںZRb$9 BFȬũXRSroQ7AD0}}c/Eb嫀!Hrp}x\,"׺qH9z)}gem$w+I(;ed&EKH2zZL^-ҿ cߠZLJU!ɇ; RʼW:>1sMk/QJζU%DrFKh%ё2rR͊˭{~-=Cr/F5KP~>BᾇʾD x@>`_4Gǻo{rNj-ڞl5HDD j/% w7+ OSVc"}`%LHaj&@#XA|VfS"Ƥg'[^?+%Z"#_12rn Mr/UBU U|]U/'Ck! G?k`Od䃪l⬴:J!}C4u&e3g, :Q lHfOQ"qwxgUTo]ίKW)9YŞ!ƚUX<31zÐ^iϾ T@i 4`Hx}_\{t֣2iV<\qѵFQ-R}|~{Άo/Iï" Ga@$O`o;."p vf8 L |<% F>9f?CzTw;r3;?c8_|_;߽w -Ua, Y.X Kq۷6<|6I P&RյWQً/&qqe2|~hS@9 )Gl)FGmx I33dgJnϿ@Ű_?F?2%t_#]J{4 8C gR1yJ MUkׄm8/,] ߜ iV$@BAݍwJ,(35힭1ޏ"~*$T,2MVyo;ߥ]n9k}?>Ie+K{K(`Iz,~\Bow6]ό#^10+pn>$p6o zyݮ}5߿㼵>)H2GHX"D H5 (}σ$p 8{}kaXdܔclnu 5PnS3גӒ<׷@JAة x/&`nw> ^PW#=Cώ^o_3GfKZblUp?׍A_J9vQk Tqn>$p Ǧt qa_Nf5PѿnQj|ߜI:u=zܴ~<4 ؇lպaا/|x├9lّ-iɫ%#=? $q$Y/,qdebܐ%+%.9WRtB+}jv]=}n*=7~Ws Ҋ.SJwӟ=JyaLJIj IZ6E~$DNd 9BO*!eƘB? W^YeCAþQ'FP$`7~TSרoϰĒ?5e%_|ۍfM8[N;o)ӇIC$| 5~/} 2bL‚!HHڷ|>$Pgbߗ0Ĥd߹FN|xTlR0tc^1x7@#!<@+#zЁҲ{-J6={!*TuTaPs_6?Bvt67WmΓ;Kގu$O\K̇SժMs3>b1+I.RBTIoW1R՟(a/\&g}O ]=+zK.aw&Q[WhzuUBϏWTkU-w̲cEi}z t |e a9B#cxK.ҳt =$4(A Cz~M;Ǩ7~Wۦ3*3;7<9]3͟ E7b $bHn2>wOsNЯ+MN̕]d [ EjnzX|U "[/v2ޟO|0񛛀vG=Yg{`OtKQqi6~Գû#s$jXG$}JG)\uzSR<bO, Pak0cSD'h`!WaF7˻ 7aT TfO>ڽ~נ]3 .DLA~V[za z߷۷+ :͐{;N:'{ߴTi;8nuN ~lMA`%rQOxPћc"i¸9Ȃ{aۨa﭂ mg〙i'_2-\{j$c?bg5Rݤsw?i5Pv ώѷ+>b{B&O =U/Yυ߬} U~X "#T7{ÇᠢTalXV ɶ*( qy]F-=7=b ^ħtOv'/ilRߡwx̗.K3bwtub\{Ǩf^`MAD+fD1l*!nY}xJ7*֪X׽:Ns^%^QŨVּjbMinիfV}ӭ~u >ol.>7S}=#H:ҟU^j{Qz䌛ܪWDzB{z}\9SϕZ^Z׳@6jko4R`D-*= x|(S@V}Clv>>Eq|HgJQ+]YTgg*Ԣ8紑@DD+hI@2V_ŏA[Y}=j'^:l/^zT$ ܅J7ǷȻ rp6~s :!Nq[JFzlB>1$Pi ؍߬W~^;rH37R׼`&5/h'}?84JAT7$޸nU jWOWu*CCzM]u U*n-UTr@uH{a{#N7~];ֱ]R^wב鸮4W* 8?J 1$Y3U+y寯B]8cgI*TMW0F̽Ram -Q-u~zu#1fr69^Tax{ƪFWa{}PT1WG `7~dCb c* !t!al,3 6 TTh0x0V8L՟ah$ɎAgahdpL ΅} S1GC~(PB~ HpC1x @?Q@&Ԡ1 Sl@`*4(EcCh& a,1ql9qnz8uV!чp ه>PB?҆`(04*CsmUO "P o  nP ` q!pn;{QߏF eXp1a>7@&\<c3@CBD a0A֟sܸ磁!6Mu}x}VG7_M}iD7e`P wUiχkћ=c~>>lYrt0"Q(M0ׂ:qn#Ne$`ovd3I?0*5pqV9 *`4iLc_ZZ3l4NLT㒴U4-4\@ )r[J| . \TTHPBB  {s|||m?9qJ.}p\i#VD{"=ezp8ܨ߇g8)jG>œI6$Q=ՈlŴ'"&2cs3#* sU] ='fPY׎ǝ,#yGyuD3{c&67Xnı x;6Im#И ?[,vH`&BY a&d(f@Ten~yDZq8z?.ŅJXރI8E0 Qct#n5iN;f[l9v~?{ 1Y0<@pȊr)eFSh4Һ1p0CdG#ٰJ,̥ BDL0QiVYn\6&aU(×$TAr']F-x_JE&,Hf Z٘N8.M(zÕ\$Q=qd#JpQYh5c\0f0!s%%p/H6Kb/ 82*Ec.OW{:9 Bx||槲wQdϮ,=SKTYBYU,m}T{ʕoz`ae_!}u7uZM痯|}EVIENDB`mobile-atlas-creator-1.9.14+dfsg1/src/main/resources/mobac/resources/images/plus.png0000644000175000017500000000034112122526606030302 0ustar paulliupaulliuPNG  IHDR Vu\gAMA a pHYs::6)QtEXtSoftwarePaint.NET v3.317w_IDAT(Sc`@@ 34H '`Ps`4,Z_ 99Rg`%G@]3΁l`F¬@>$ l45(q2tFupypss aƚ7/NRL,:D1" 35Y% &YY+s]޽ž}토`CBC$69ΜqBS׻ ǎ(/aرys#8x!UUz+jjIa&q͓t" rsPTԋ[obz!"))]po4+ŏI#G(,GkƱmaC~Tjj.kk$ ;čI\t3~Ğ=äǖ-}HO^hh{t:7Oi {{X +ˊ|t!5#h4&_YN=FɓBǁ ᥫgԩS]`ӦM` z ̻q9*G atv *jhtoFQL9qKeQDVi9zGY@4E8V!ĥz{{c̴y?G F>q,5r$yU!B#szȌ2J5Otga ^9Lv 2(/0DCjjsqGIgCv[GqJ2@P[Oj0T Ih1|{ä _ @bڎ?m@́8~YY VoOOx#b,) ɔf1RrFHNj_ r(Q6+-ĨLjR_Jm ̙>n+Vl&W19tr:ˌ^aHH˦n] A/j|C&7<?6nܘER7ۺ_6]FBp*Cƕ<)JƥbE,"D]>_ӊV Kcʸj+ÈEW::Σ=t8 MȥeݏP(`? {," ĂQWS@b2ɨ܉Y1r wߔg,QW8؂ߋ}'Z>ݶnw&J8J/l6FwynK-Q:+ %Y9lj2\?M(B$BۍǛL/ʟG}?J׮]^GJX,*DFl12Nq U|pc fbLtuuTE^oeWx" KboU4p 88ո %:%EJazIJE7NX4ְ$bOQ!e[GX___~0gAvSKS}oC1· b%Fٓ-'^UWH\eIMݭ@`v d2r=z:hҭEٓjfVZș::IENDB`mobile-atlas-creator-1.9.14+dfsg1/src/main/resources/mobac/resources/images/ajax-loader.gif0000644000175000017500000002510312122526606031472 0ustar paulliupaulliuGIF89a䰰ª! NETSCAPE2.0!Created with ajaxload.info! , dihlp,tmx|pHrl:ШtJZجv:(zݸHxhh|{~zxkwuyst`f^+]d dpn p½õǾźʱӰ,  ׏ ;x/!A{ОÂNF}\H\:YEr0V8wС<:ϥG*T͠U>źӪѨZrjW+XA-ZpSYK‚vpgɭ;n^św/_ E\8`q&Y]ʴӅYb̀-EB-,,Jk;u]Ǿ,ݻe |7y\䰏Ås_Wݛt Ө-mא`͟~~z݋/v_]xxpƊf1 voNZbHI!YX?8Yh Ao5USta)cs;h\8xTB*GciձƣLʋ& P ^ԗaW&~`JIbnզXo^Wh `4 F}>'Ngjg h+.٠H:أ*M*ꨤj*]ꪬ꫰*무j'! , dihlp,tmx|pHrl:ШtJZجv:( 6ap݃z݆|Jy㙗w=}Ko\?g<,! |_v0XV X[d]b^'ͅjZɵA!v !lsb+ZW/ 6Z^7\"rx v`X$5$#ʸ#*v!{.*a(8ar GfdNa}%B"&hܛ|b]p_m-tݢ2vz)y()fr G+)bBfvvP*{9Zxvu,Q!z^"+kik9gJ`k.Da>#|H卦99>2I8gH@ `.YLf4|҈Fs ,O% l' map2@,Y(fIi+*{r c2httM?4Ԁn7zEF1I،4g/ `,Gpjh-{5TbӭxyZۋHl砇.SEꬷ.~B! , dihlp,tmx|pHrl:ШtJZجv:ix6hpA!M_ x<@lx}ipo}{jon|nwli{km`^+]k  gt Аg hhet}ڈiV4 7P8(``A A.(p@ɓ| )AI `T$P@M2c\fN<\d1քpΞE=)է֠d ThX!A0+䄻wxfz 2ΛC7Fvy%868rLǔV3eH5m軪'oԬYxӮ!gw< 0OAss,HOu K>aA]k0|Λξ{зWw}<]uwY|] 2ũp\P`l]gAymLxȄ5l2 N@c'RL4g`"8/ʸc=V,B5NV$,fN7b)h8&X{)htezʼ' ȷfY烲!z墆ieIgR-_yv*hpy $Ph@ ݂݊;F1Y t2 d<#Zuׄvkoia&1?b+n&BChkna-[E{Er *+Y@$n).2 )&ty$x-yL2^Rd K%4Va_3VI8Fo5nL(7{0mX2l05$h`[y->sЧ} XKG9'*y[3P_ZXYʩ&-LQKvGhOX*wɫnfx2-E7K1 yxޥIo7ݎ8V8|/o<]7G/Wo'! , dihlp,tmx|pHrl:ШtJZجv:g0tqpچ1O yy}u~m{|~jxqov}jwn~poxzzpeg,]wo  h ih~ؒ juuNХG\A?T@0S0$yA L e'QBX`M2g>в2i\ %\,З&ss$Ԙ(d3̣<.Aȕ1hEH0n , `]x%o߿uƣY38V,ٚ*+1g~C fӊUho!]A !ூ $XFxǑU| 'P'jt{~SaL2#^r VWT̊^@>cCx׉Hbw<"w)VK!wvc is)ʓfyщ̜l0|2 ܉Y pb(gz'ꢡ%t)] 4i$ TO,hmg_' 0]lפ77ÜKXYCeq%(6maPD" kagw]Y }ܮ劽v-k%$o{?/q [;?o^ӻ-T=rtB $Pi &z-&_H=l@]gV|ebfe֘ovih3D8tp x኏xMy#:g"vmAbnuPf=f ^0 ~ Ȣ[xXNhԉt#Q%i22֗43&@]&֠eZt(%ߊȚQV7h1 &ommۗXג)(ڱb `v}A!^sܧSZ*Uu~ͅyyIz'AYٙio6'l^N) Տz4f [AuF6Z]8ڋ}뛆2[z oGȚ@lІG05&H, ɯ&g1P`pŌL|-KV؀Mis=h9s Y&\:ۇhrJ-jW]sud3l^HAʉv&ph-/&ܼ8K8\*,yx-<CXn=*|7 6[TtQo'7П! , dihlp,tmx|pHrl:ШtJZجv:);Oano#~x< 7 yye||g~vx o{fzhwy qrwpnGea^+yɂ  ѵۀlvɊmnA$߷ps` X0eB 0$Ǝ$ir#J `\˘%c:g#M-} JRP/ UN<dP ʧ7 Й,bXʝpNP[qu k  Ob72$38[rFYh3GN|z&sB fWAbtZ0܂v^q;[9l .tv<7V^^!j nYuvYd@ Te]Afuq=[f&Z&R&"{n.quAb̂ HY8̊!8׆!1ɣ`P` ^0Ф\ahYRh؍ȧ%`]F @'\rk2@'3>&z9܌o䵝fxʼn͡Ee'LVݕ@sJ&7N0~'ZN\ـ'c^#lڪ"쉭+z|ĩj]Ǟg' v]c/ڐ^&fE!H^ ݆6k9ʫ0Jp &c*kp@x[辙1]Eez&Zsv%~gRۀ\'8k@|z+i[W6^0cvcs3Is}zb3GUp/GW_\?Kp|wu~Wv'p*tzr_= 1cbD.n;]/o'! , dihlp,tmx|pHrl:ШtJZجv:ph4i7f9=x$ِ6=vx|jwzciu p~xfc~y{~yv{o ea^+ `Ô ºy”mٕm“nгCLۛz 0a@Qƒ2j\@/\ԸAE %H'+l1%Ŕ3IL gN |<3ˡ!BSҠ|Zfŕ-K@ 1EچҪpǚj`Ѯjε sӂT@Ykk \ u%e` WÁ&P0as뎶a1굪1T vI~kmC  $(.wʙWH+!za޲oWλq/x`엝b 'ͻ9rl)m* B)ßeA˜Fle}r e!ah!gtۃɇH3*px8`բXcjI` S%kY@o j j][ed%Y0fl)bg g'E&ϭYfqfpxB  G9|g,u\٘l-yU] Qzn)Z-* 暤[*쫦'†JZuW5͹(\}W'4)!ofnj#zغY5cKVl[,YNpYek\ 0]K"ž H ,UZWia:ہͥɌfJ䍎N2jL,'JlB]eZShj^YArcdrWffC+RʲP킧]دR dP̘Ʊs)'pjp lpo#yˍH`;⒫exٕf=7ޞ;]!o'7'! , dihlp,tmx|pHrl:ШtJZجv:P h)l#1O;~x{}~cvw ~|zx| gkk|kyqzd^+ oypo zB90a GE @qA\@#Ǎ rCɓ?-^=Hl/SE'7G/WB! , dihlp,tmx|pHrl:ШtJZجv:(8!6̮{~6x y}~ul lcp tkizzoye^+ {`фzͿ ьyq[ =k$0  (p@ŋ4\̶#ǏDxAI @b%ʕ f,i2ȟ [s$͡' ZNJFw3FScδ8hhh(@`@@Aʝ R5ΝA$jZl6̭`{뮭p_ niH yH +,ʋ1EzeEw{Y,0ٻ ,{8Z 7 '>aAlktqǵ޶q7UY:k=6m* @c%s}eV3GۂX!3!_ b kZff%B`{}^2&[bȕ|}HXF` "h1qS֠Vf{ӥiYMz7AYc&$tԵpnةxxꉀ2v)Emx.e5)W< i T@$|05"HΑZjt~ިx kE+t}'k[[IJV(+!+Apbی'&XmVq2'>;m"^8kay6tIb2&|- 0r$'d"E]\_Λr Xe-Y G]BޟHh.iYIGF4L\%6dɅVo `c +m;\ Hjt#wYH~0q*vk| .ANdBP\+!/`#ꬷNEEn/ !;mobile-atlas-creator-1.9.14+dfsg1/src/main/resources/mobac/resources/images/arrow_blue_left.png0000644000175000017500000000324612122526606032501 0ustar paulliupaulliuPNG  IHDRvsBIT|d pHYs U UtEXtSoftwarewww.inkscape.org<tEXtTitleArrow Blue Left`6 tEXtAuthorJean-Victor BalinJL'tEXtDescriptionjean.victor.balin@gmail.comQtEXtCreation Time2005-10-318ϡItEXtCopyrightPublic Domain http://creativecommons.org/licenses/publicdomain/Y2IDATHo\?~ۓĎ).1-iP@mDHFU+h E]tQ]ET5; !uV i Hqb;{qxfH6 ]7{Ϲ85'b~'b/}=2L=EL?h$٩i۩/>W%.I Ġ+~H!)q<hNK*G^iط$>3tSOe%Svw D "a'#kO=9xSjL5ibxh$fjh$41% R^)+%/{m]}oD!ji{N㹣ܿ"r!fSJ+'Pw :7s1W 꾫SaS- A:sEj41X+ A)\WUA)@^2Ԋ}]=]VpAdhԻsKVR > pY)ymTk+lwd6(UPno Od{zg/荢yYE `U=k;ݣ(D}P@ʇw,d}OeACs~sqMЧBGot(ׁ}7ld'C$7ZP׊oi'NsxZaeE{6&-ijn:.|MQxؐƆ8GR +رNS\`Oo۝O8%b޶' ca>% E?n&$6$!suWF#aQ|߻wGW_j fͤts86R.}õ$; 9|_lL>VXKT1ucpen`՗S$} ['\x^?\~Wͷi~Tş>u\VPt+_zRџj2 GқIENDB`mobile-atlas-creator-1.9.14+dfsg1/src/main/resources/mobac/resources/images/trash.png0000644000175000017500000000155012122526606030443 0ustar paulliupaulliuPNG  IHDR&N:sBIT|d pHYs91tEXtSoftwarewww.inkscape.org<IDAT(]ou8BjJJH2@2T, ԅ1E![b*VhԤQ#q.~`1 ߟ}0ǁryC1(p3ytr P\C[%%Jku38Kܺyں^h>ŏׯS*P*.B1ax(ploo 1z3>>""8G^X 3P"[z,{C1clԼv>FwUhbӰ " ϴO|e=k+)!Bm8}Pq?$8p὆>RoRؾ Fqbץh̜rNQӏ]|ĮGʬP?\.Еq2Wq:`T[jrW$dž{{z3PXt-  5t"2Mz'l6}yޤneYadlR(J}@)9s0kF#yބ뺟{^}/IENDB`mobile-atlas-creator-1.9.14+dfsg1/src/main/resources/mobac/resources/images/compass.png0000644000175000017500000004075312122526606030777 0ustar paulliupaulliuPNG  IHDRXXfbKGD IDATxkl\zg8ϾH[Y3Uکx)p 7umFڢp4M[p\4-I_$HmIqݦ9u|#P]7mm]8k_!fך~!ֳ/g%?2][ux}E8ߔs|끤FGYU@Stp!Ia8  _yE@;,~vXE"`2]Dw^ `)x_Hee*O `C|,0o~$y_qhz˵[XhEo=k"_tZ ,~uGiZ ,~Kʷy$}r- }!kK` y%]uDee_B<>kۼ.pc~jHRZo٣8~Q}0}IK~Ґ.X!5]FЏ 6~$E\æ 63cGc8F I .N)!`)@  %Z?k& $)TK>oG X$ ՛_5X H"`%$ҥK%5/I,~$̄fKKH~IRI,fI ~I$R' L"`yI#_,R6hDo W<I"d0Ϧzbj}K;BT,մ-^#`E"B-,~} eX,~bx>Uﰋ/\.UKCCCtR^40><řX "`KJ0g]@G/ZV`ll캋XȒ;ERV!cX躤a/NOO+~ W \GGs^FzwJ.T Net(59')tԛF$%{_ojsRTٳ$` $ V2T `#XfVF4X\.7rm,~sCQozw$x \SSSE,~1VfggCb'!X䪤|oa= r_2(O:7[JR=[?Tpo|;"+ F'yxxX~a^tX~ LJj2 ~Ϗ3X"!rIU,~=hxJ$$@,~ iJ$f ),~p+Wep+XI?855U; Nᅅ.p $$Nṹآ@G,~`MDBHdz#?HI=-RXz#?S|_]pAJ%.iܹp,~pCCCKX.(dff& xݤi8gN_,ISIJ[X AA,KZi\Au%O{W*;/i%@g,^7AѨy睒N:!`IL&kb'!x;BNlaaaDRҩaX)n|P* ={z,9eYSx٬S,K\&w=Ge% 9uw}W@ ] xٴ*7xUX.BGͅDc,^5-)AFczz24L*1@OxUJ lI$*JW>.GU7ԃ3_|Yb񜤨J裏X3,^qL&%v!/ ֫Ϗd $oJH*׮] NLL,I^K,%Ij5z8KK uW*;/iحs ,^2"Ο?_ >0XX',&F5p WKu 1II x%I]:{,; 8+,I!OjY (se)˹xuICn I}n+Mʕ+EX "S' DW%M|~~~4:@#`-KXld  $%:eY*JWM@!`N~e sj_XɓA]p!/;/hd2)?XL(faF5p i IeE\v-811qt i yH${$S&Mpd2Y;  ei𤅅X HT4]aRThbbNKRt,K@`tO ˲f'MXL+ $gD`Uʕ+E -*Eenn.$NmW%MqX,amaYb؂: ے–d2R4mDIų{XX`P}Q^XMC..[TJIo!`pIUEtk~~~txxQ M"uڵ u7%䣦D"z c#`pӢ|7} w F&_ HhBOLp\SSSQk,n&4??;]#`pKB>AsssEu$[dY:  [f$Lq\DBB:  [nȇ9.\PZI0] ݗmdAܓ1aX8| %LqRH$2cA"Nʲ@<nA|%HVq@Xp]Rt'5==l6^28 |ݿu+k,nd2Y; tU|,,,@t_z<ϒT4]i]v-411Mtגq{eY %^4jӲ,KldAk}qYwQ(ӵ>^j\r(v @/E%3]SC{#^7]SFcج:x @/Y peY鋞2EKI˲T.MXz醤"299bxF҈Zx @/խe.\W,2$"J$v8 @\T1],> Xd2011qtW˲T XzeA}rE=f @,.˒>6] "`OL+ٔz"`qGd@[,`n|ld||:x @/$G9(H( ͙w¬"z%HX,m#`E˅ TF$M7 ~dA dX6,}ELP$p}"h^[\\D"M,NKH.P<gTXR lI$j\" ӮK .צfߓso `pڌ%]1] !`pڤbYV]j },..@tg`"ВJB$'%5 -e) D!`pҜQE%L*N8itn:wB$}t-IӦ pTI$p SΚ.maٽg S%MX,@LL&5222PgFhaeY*{3ܐ4].]b8!it-)) u…p%8aHEJ$v؇ %ULaB|xx5'$5+J3X=ht Yz~t 5==l6Nė'̛.x<^4 `pe6==]; 4ք"L[XX݋,fI*.´:x i%49Ȳ,E4’&% }7 Κyæ ge_ Ľ^/ӅBJu]Iw$K%)-)#遤/F-IoZ:sl.h4BW\)FP2ԕ+Wh4455U{PU__ԘK*ʾDҦ!;xe$ݬ@o3*;DYéF#ٳgKW^-..Fgff"DBdRdvvv͐U W|~萷D߻$dhJz!{kIҊЕeO S,} {.t<_D" ryX,_x1?33MRD"D"X,:ɉ@.U'+]-盏Ŭ$ݗuSҖuG|GX$MI@̙3%rKp1==]͍$I% ]tI@`B-d2\%7gYǿ*{+ D\ˍ%=AMYRH$566v\.'^!JG-NRJ$:{$Y䠄NevmY&;x$ݕ*VP4 `tIvJ9sL<|\p~~~Բ!˲455P(4vq]!`dHR|5Mòj<}UmkN"`QkF*~411Q-,,Dggg#J&M^ӯ!ˣ(/7wdxjoՋ&{X@/<#b\R,\x1wڵh2 Xi܋-d4\urXԛM=k]WFv]dNHI@ `9s憤k\n2 5KsssX*&''{dE0\S}^{MOer-`/,"НjD"Ʈe+ϟd8L&ɤ,2dE~Y: &?&=_weZ֛. C$}/|>I^LNNޚd^5dv>&_қ^KI4٣0FdfFf&&&l$HȲ,}ᇒ̽o!p嘃M4?')+{Ed[I_Y,jFfTP8RT`aaIdE~ Y+W$dzɾ!{~ך쁪[W&{x ~_é@ h6rKPHW^-χgffbdE^Y+O8&etݒd-bvX3jD"3ccc&w}b*Ǯ],KeܹsMՐEM5ho}Z@UdH&/BIVNNNfggCdRSSS4B5/6ӲӲWE=F #ڛdhXO2XD">H4GW}S}\L [WdMٗ!c#`7'/b̅ rTjhaa!~ڵ,ˢ|YԛM6죲o%@v}rcZg X._uq%ٗ$;]㿒ˇ%.gd,՜d~]l.8 MMMóK.) dL,q>|GdhoWk*Md )Kobk]!i>=p0벎ɞrLd~R$r{ϟ/RB,Jɤy&stE td_dDF $:m>=uKo:猤:Y|Zvb8+ Wj˅h",KW^q+dvMכ $ېDzWnIE XˢsT3~=?#{Y;83";DYfy2^/]z$s^,\m>ZZMlVe7e|edU Gu6d?w1nV>S^fb\*g/\OR &qV`\B renչa4{\.$C^X8Q!eAXòk(gΜYd~&# t"\GFj>7ٷ&o^J񽐽Y8v:x1 ?Tuԏr]2ikQIv  5pj5fi2Gr*d':5dµ*>#;=MYWr܀uݟSnZ?tCop899(nC>pxd>B9iC  ÛIo6d){k88쭧VDbAaڭnA/x3XG]["j$󉉉z=f/^ZEi2NW[MWvM;o8;-O8,ǒ~׿VXA?=]jǯ ʾnb###7bx>]vmM9! h!pttXMdxDt9;8r~gnv^_>Z_﹠j2dnIΝ;wCL. Blh~~~Բ,YI&'m"\rZq++]ꕑʵJ=Sg{;@kciכ){҄8jj5'b,LZM·puڣG Y+g6_h>Eo_n>OOe!Od=q?7ݮs֊WnKzfhty IDAT吤W&BIZMNNfggd2H$pY8۷$}oo6 pW&bj>\{7fd>*jT>? 'c>2/Iwio7oI~_<|!?=C$cu(R*,҅ )JEkf J-I|ލ$`7C^%͟Sknks/JK7w9߿$ u_tIuj#6?}c١,R#7bpm,x?޺t:]m^ <}tdddi8r ºKz[ Õ{iV=Ѻxv8ms,;oy#5o,;D.c/Sdz놶 2\~;! xS^Ç__[]]-vvv"bqhtt/^ܬީT*eåI]oN>?a:4Geiٗ7P4 W?F dFpvTZi6gdF}^*1) jלn{PCcUN쏛}e̴d.n&awC} YẈccc@˗?VjNMhyU:襤#uS^?:;/7&%^J4o59vp0,URݻw&juŋ˲[S2.H+LI:ӬxIZ+tx=,酺kJ0R.,{Hkk㧲GL\h/t\{]o[د6:::DȂxBLFtZՕF믿&grRPX}IoKf+tIxtO.;z}Zq*KuX~n[Iv%{kQvIcN=<JLj4z VXYY) B ?ŋ&4.۽St~(ZMׁڛdߚ镔}_V1z^^+ d2 U_ZZmnnM8ЍJ{issSL_YY޻w/h4*X^V[mN2o |aid7wL.7Η j?ZoI4٣ӄc4C;$I/_|=`ss |W####ϚM'gdH٫-5uXanvA{U4Ӯ\2`Ij2V:~=B˗/Ҝd%!4XX1١L/K4`0X?wK"dB֊T}ii)QAkrIO >r,):^})i1'•Г?_uk666KKKL&o#ccc_Rɼ5^Z4/~T}dnE{УGL&Jqgg'傣$mެVz+Jp逯w=l>~cCWBoN_>dg7!T*ikk"$p8FwJR<|<*٬8K no TmMW.]"3 >}zg:.ߺudϞ=σ`fwwf\ސM@zW{}^UIdʕ%ժݻt:L&Zugg'Rkϗ7&s .#doM}zY0_.|ƆX4}Dn|>*{%*-bxsp ?%IAkoB샒b:A֊ŝP6@˗\V[ۮT*]~%B4ൿ;kI pe~o].,J'ommoݺܬ߿?s&% |h~#`dX$@OeJUЙF;wʕd׳Oat t:=' >9w>}-˦0%/it x<ۦ0"v؇`pkwH98"d2 uRtRi}ii)gC.8%V3]! -,Nٺ" (  `pʋ`0X|:V;@0$v81ryekktn KzhBW^-L'ꦋ-,N,//LM'CpQ]ME'=zU(͚-Y 'GGGoooM,o!`pT01I&tQ/_9(^Jʛ.8Z ktí\dDǏj5uZ^Ҋ"x hLkIxX龟^4pw 0$ E&~_pt6WVVʦ .^DLCqgWJE~:z Ax'A}0*nhby* "`z^ZZQ \ @lmmmwLC-E~ w>}-nVNҺ"x @TۦpZM\"p LȈ,=foe2:VtgJRtkGK"bGK[1]JMXzpǦpJA Fwh'aHҦ"x @OU*> XLXzիWKkkk%u8䉤"x @e pt׶vvvBp@]@XzWlt+XDkxX +ʊ_w>0]!`pKzuub0]!`pKΝ;QE@EOL_XUR?{tǕ; k}6BDzNn1(*"  k^|Fk,yu 鴟wn.oF:nCj<r{{tݪKNU`0Q #|S, `pU6U7]G^.T*h']'mLѥ'mݿt](IZ2]"`p۫GLqAX\722r/|v Iݍx Ox ^zukuuh#A`\\^_YY1#,^V3\ê#,^yAKbDxP({葩ĐQ"`h4z71qBb!xBTZ68!$顩?,Z4tDzo `ʊi WwvvB[;8+}ެX0hdž&N xF 40!&'X<˗7766ܾe كF1,QV7WVVr.v,^N ?/ɓXZu|yIkn `b4޽{n,vOD"]Id [.a5$} Okn$tZ$B5[εy ىpGXi^?})<Mb!!`zBt'0X<677=>W\`xQzyys| "`L:uIzx|={,R,{uXǿ}v_; '$=Xzvwwommm{t=:6xS\^_ZZM3"`zVVzt\D]-<1z ?vE@xV4ۃ!Ii xVTZQzA`?]Z[[szcI7v~,^Y^^v:`m:|<x  m<^MMmx٣l6;+ \@ixQ&T#` w$m;u08  ب9t@OxZZM8ugVcmSN:!`۟yZ89IkG"`R4}v޽"p  E"$Jrtr-꒾v8  $D- ?HUNyuG*.NHZr8  |Sk_} X|att)n;)vH`9 /<fRҩG@XbkyypryXbkkk+x%r脀/={,Z,3E-}ωK\F`0s>$Np,{skk~̏$E=p(ǽIfmm+X=: `ÇcFM@'p8ѣn_;@+h1vBJTZd^ Iz B+Kkkkޓ𱤮),~YZZ*uލV `̝;w]&fvXQ. zup [X|'?r'!;A;Fc1I.o!`ݛ#A:ߩVoJ1 mGsB?m]o^ڔTW!_0P//ߒ}fDEu^{JN+Yc.{𪰤S|~k/Nq\8 WHZ$1?;$:I yY/-KJ I:7|Ϫ1 wMKy/$X]I$e#$d~&/Y*+XN=~Ϳ/EZ4_<.WAJUI/$Dz>+hrIJSo|E9IJz.}E%z^E]*x IENDB`mobile-atlas-creator-1.9.14+dfsg1/src/main/resources/mobac/resources/images/map.png0000644000175000017500000000227212122526606030101 0ustar paulliupaulliuPNG  IHDRDbsRGBgAMA a cHRMz&u0`:pQ<tEXtSoftwarePaint.NET v3.36%IDAT8O-TOe`:cq.(r)w0eQ1`6.:ƀ1BKW(.3hb_t61=Ky9yg {īzFc׋#H'rt9<֟'o*k^ ?{A$I^ۥp&`As<u& 51sUQ0W,5j:-j0Vh\)5ܽS6'bzƯުDؚJ;kIX~'-Tp~\*Uu\M t0ڒ՗4 Eўt8^,)Xʨ9ИF.Db+5v2Cxh-h?1pFR}/g$,[x+0VҔd" <7\T,Rm"ipw蟙",Ϭco ;dbmcIxE4<$= =eaf:6J`u=TɕK+l=EYpr,&j-RC o?>ψK' :`bɒOMq49ݡ{Wu>+rr LHYN|:|N~\*VhH)T* kXGZ&[>yBX1FhW̘\u77 * wY$!:7mc$zw*, cV K<|J""3 P4&, dn' 5Ju\l(W~fEI3F(1N``Paint.NET v3.5.8C      C  ," }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?((((((r \.M/srhO>im&5}:7o@:}y_?߳'- _Ng>%v+xaO&e,E(RK握h?ྟ%х3uO[kg]j?>ۆG+GĥwN_s"8 M}NOw7m_$שj_ )PN0LdAwEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPE^@οe:[B 'c<X2HS^ Keԁ+ddG z_h}$BzgX5ݵiXRH,H$5]oo6jV~Ӡwb&"3ۆa'uO͐@~5!+$|e=N %+E40lbKM,Jǐ#CBFucj/j?nΙ+Ŭ4mX ~:-+u?PWM>!|>,̏^[x{ö:m,H;n[]=q#6YtM2Ğ6/<[}JGH z`8-UˮS_ c]IsR=#=q<)ػ;I>-fOZ"?u Fm?N҄oem,&d|_xJ,.ouNd G;QhJסL]V*֨DVC`czٳ_/U?!x|-FJl#+:K PB ]-xgah#+FL/<ƍc2д OHKv9?sUɰk)Eڞc[ '>Vݏ'7Os+jҹN^)Pw`wMŰ"_eߴ!SZ֗-=šwd?2 8W<Wu+{O0k kqKTܪ3JcOR?S $ _6~a@jA'9nP:3UsW˹Oī_D32׌tt.UY0?2x"ck_ О<9az_D]եjn$;IFp?8xSÿ mRیKTG9qXu(V>H^Y #q-j U R^dr0FA`VeEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEJo8<p yǿoAm>f#=nx $NvmlpWY3'LU}t-FMc$Ƒ ,{lu㏎lY k֑[|Gkij \,XB4~"~ǿ >j%4EܚsxNVX]%I'E՝u-']?&7wLB"JM-~:Oj,$j:nm4~Qi&Ki?ï'/g`oGXK%V8'H,de`kkտx]{Vf.e2w^+rJᆋmmwgfV*VI-5OMcP%Y..Iy&N,N9'EIH'ųCxŢ=C_ZýVA JH`60D%/KoxZu F__cZvfb K ]_*c2QM8=n:c-G{i d50bOGQҼW<); lj=rM.9Q3Tr2DWBCS2ݟ ~~#Z:K5x60R[xYIV!~`A"?%Q;Fn`4 ܛ=~(펳k*C$\+,h+ʤx8392 Fwmi^K24 '6/TSsMinH"X)bXf'j33Ny=8;" 9=U!E,L`rNW$ٯ+91u#hG[%Y2jrm[|6I,G#]7|a`+%x/ӑHa%b8ʩĂvxPr?a-֍k ~ѳ Kg$k)mcGۺÖ/ua/ţ\mofTTXꐤMEi[|pN/ U˕+g\3Ǻu1x~ ƶJdOkX/];gd#e>KeZC ZiP\7X!u )^W% `nr]K;EuxH$ii}VY&ky!2xX`3 L$M~1VչzvW?MaWC.o4#,LA#pmt*Jqk|f=?ZHJC.y@'l` (j8Aϵrzh8>}q5 ӊZ_.<7~t~[w< ryd-<#oG2ʡV#րEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP857^C<%yGۮcK*eU~lkjcӧW񖾏 $0. ρ9_ɿ#㏏~x;3ľ,IΰܵFIv| 25gVy}5@dسĜܜ}ko*oof]IqY_L;xvѪ\e2ȩ_ |I⟃wz%a|OivEŔ׸/1pdVN Dd3O6ZUfR$Ԯ~yI_h`(P1pOۥyzɍGh_O<u=+VYWEk7;c@o(;|E~1_^FFjiאkh:ò4fy@ubPX@ {Fs|?௿?i_{vKׇ[1"[GgPRynKŞF=XRǹ97S~:"k%ŗtȧ!4wLN6V8g i Yg^=|n#NGU\ʫ<~d X)x([zqk!*0mFrVO2 xR?*_?a _h:fsu吓L҄n`7*\\?O,'Vȿ9~?Qo,":8t FaDdZ[sl]<[֭uyyr帑,}Ϡ01zL:psHXpyv[_XU%{?$qbu7-NyqiUA_ֿAf!_?#{ %cs3&2p*>yYCgli3ΑZO2;ŁUr73#<'1 kwͧTgeIOKdZ%JcĞмMH/l-j~gp;W<:qՕ*ACELpLS!8\5JtaNrri$۵[m.>{BuH.T.4ޠ p{Yo>>!ICHֻ̒y R\`FiFɲ$ Pm$`P3߿/t/:|y[(bwz**O^3fUheB +OxzXX'I^ީ$|-`o}uŻ kqw++/ +nU>Dd)T2R3_Ƽ|{| msXI']Қ)h WۺvT#xD _߳VU_ű|0ɼn7ӠɷfV H .k*̢T,N't%u?Q̸#4c r4{_iO|ShfJo&yumN{kF.2MHˍN D98 c + ZwPŔwvz n%dRI&,n b2h /k%B){w>Iյ֡`]4|]5Y 5uo e@A#1Z >+qFl2sSmbz'#?sZecGq#T:g>OQ >4⼍F ,Xu.؄Fߙ@lڪ#/*GրEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP\/WڿunnT;D @gv*22̣nߊ~'i7 ˈ T 4bck=K_ծҴkw:9qR0[摂$cc߲O>7izֵ?6^ .d2ߤKlZD#qmw#ڭ}nj{jL:.YCАq4~+־&xStĺGKDfX"3FQTf8J$Mm}yuܓ =:Gm&;Z`I7,szJA a]"YS8>-h>|U𶁫pѰ]#Cc8[*XevYyy6w J3ݟ?mb/~(:sj/ W71[C%gK[Y 1P6>Ba˕Udb䓢ғJڶױeYWN_kJ/Z> m'#Q/qpYq1}I,gǗொFORmž"[ >i/4k-fe*,WRy"dOw`=gImQ-` !P*RUYv>ᾉvtMF.m-dPvv ::WԸzܾ+4*R߫.c*P~Zt_4RI4&lZ[v"|?jtpKzu?9˓g)r<VM$`+jqskj?c_^ccCK2U2GKS#(MFN@ }"Z {n>~^i6W3C6L/p Vfp2A&I,^]&}?E&dK@Q@ywP/O;6z8bJ9o$Y&#Y$ "߃Qq-'a_~->[it/6̓L%."YP:BVN#>.ZjS$-wohn hwSڏmb\J@ycڀ>F<=x~$ԴcVMCI)eݶYb@6N|:y񿋴!tK~HPXgv5@ow[>5վFQA-\A?~d+7 lM#ژQxkPWAz `X%4ο;A&3kFkiQ Z2FhH`$ R1]M_㟉$伎ݜF/. g0}_/>|Q@W1욆ܣ5iI6QF#3# 鯋}E|u=)_\_;_V-&U>C|珀wltZ *\k/9})h@,:V/6cR-tO\ޯk/&R"A6f9' a /5K߇u4E,s`-cљ>gvCPO ,N*GRXAA s5wrX?C|gg5 3|QιڌڅDŽ,Ib򦞲,sY#䉣GQ@׮BWW6j772XF46ѧ=HKo~_x>[HXt+(-LQCnf+ds%/<k767K.>_68arv#9 _mַ^#OeKS׺{0;DJ"85|}ӥ~Ο(x~1E=i$Vfg2J X[@ ?)<{?~<4rt„ۍE(N䝮Ƈ'RpjQWM/f?F{TV(CDIzWogԿ׿՟/سV/V1G>\( @,2+TFUSjJ1NRi7mzSy],v2J<Ќݒ_W^?gx,m~!xvٛP{uEˏy>|OOxº֝ SO2a,2 R Erf5j20򦥳i_k^F_`qͬ%Xͭzݢ+=0(((sEK\i2:F&b"Xg0!KU[QNKi˼Y8ZnI&=Oo%ڂYLm#Cep/Y^3 ;ᧂmӏu~WHhs$ӨlU#b@RBoFU^#*jwGLu(JJn=;xOMXF}YWUf"$ 0,Z|e7h(I>OZ {%E|MV0Vm͖>aI~^'~14]Ж-,-e'eJIڋ}ٙY<  p =8άSωd7hǎ>hg]/ wzN-]+k`񆻯xW3 JQx9D$UXZ`с{{B?l-${H(R1q^e)Jiϥj*8ͨյW??wht%VQI[٤1]I%0OxWSkf$-[V6y 'c 7U 1_7^!_D3Uk0RDr#FN)`C_ ^]ykڟuUbU+VpKqI'ڑ^܎SL$W z.kaYi.LycT&Bd@[y$. &XZ2UE_& c ׄ~koX_C{^&|==w afCW8*{>8j`G~;pQafv>ijOQGQkZ~arn;E+T0??࡚ =._ֹ{$3ZQK-EQY%Pb5g,3 ~ҿw<%KK\muc Ä\3*1;G@%U,GO i}\xmsǺ^|?ь\~q_E"k u ê ;3K()ru~\s sK ,"&]_3ܿc//*ca$]:oF}iv֒tV,6 h]}K wg=c]t} VuG#Q8 f<¦ULo|:|FNzg1jjY.#BC ! кN pFs¾=YeJ6=}Q`] Q']<ߙy_Ж xF jLmv $2K 7* 1Il1'slMO{JxyK']䳔d@H# $$JfuQRJ[yUPbe։Kk0x鳸7[B;8ch)Nc$Mͼ %1G>UfS\PXkc(5zAQEQq+/'Ok@C OJ=li[5%GB7?i߈ .eqk- -bYAsc.Ҫ;3EtB3V'A$߷$DX|H_,m>N,li&wOB }hӾ4_78R׺=;}F2629@8ZM 2y&~m^ %IB65՟|R:EO IyO;z 5!%v˨ %[[ Ph]χwVp"׼UX`(u%|kx:M~X#mKK,l-++U-m{^iww/h2T3qM+P+ _4Vf +(F$-a= m2X ાGݥI,0 YUer}Df&'Ө]2_ 6y5d ;# E௟ cUDt˧}7}uOW_੺l>rOH4cؖS_xW?^ ?sƫjj6a{=ЖTCCu%ۜo>(RЭ,:]NvS"2l$g h߱/NC[¿3֓7jQXЬbIf 1 ^3P~<֗}=MM6CJOnʍP.-P'M@cO(^Ͳ=cWpw(UA;~0طs2_Hq\~xC1ɺ{F`+7q$aiaI `l~pR<¿%3 Kһ*:FV5mηb]W0}gBw,?{nHz_\?Z IqO3uff?+t  /RxWHF I7?(1qcO_D7wXlLP A8W?O>"O Ggjmgno,W>q78z^ %>ISJ| n\WNWagjy%{s?u%}_~_@~:y^񶉧Iya~e2LY1Ѫ$ ?ڧR}R^.;9-m]Xux̢D [\W.\߲7?l7x> !+&~15\dܯK*nԪUͣZg4y,:J\N-뢷Kmъ(ׂ((( 'R__O>)m4 Oy-p;CO{vgfQ/-,n"џ6lmY\&<6;O 8/WZBPjײ6m!S+$!-xBI ,g5WR//궲Ohڟ -%0%,er|OEm^|F6wW/A,J*pAV+ݏ6r+6-EB\a'#!zkZKIt $g8#5ysS1+C_NK3~5i)` t+i2H'+ƴ>_xmrЮ9͑qޖŗuscYs1X+gT؁p2Nȯ1:],8ni{aA %1 ]/}b;?1^oz/B?hY#BkKe! 'jYHHjֱc AZv0i2NYT9?ҲذS[62Ю0rL|bL1JMO*i%\.1_m|!/x¯xǞz_5/_4c)hDߺ\BɀCD省U|?[|Bx-nP k4w]Jm 6Tuؾ ^¤=kmJ[$OfTbq-ք}qڦ>_#pIk~G~C,aCKfP2$W# eT*56fvOvg"51^ZUz%k3<gĺo~)"f.#xa@Ōav07zqӚkn"yFeܢdYv99HgltI)%t]Ve yϣ?oD~i>-פZ#w^D@C5'#*kKo?am> T>8+e9|d~i~*֗_Y{ՌhjS\F4k|luDUV+_?mƨ-('ķWu]$0ģmQ2FԼ}ڜ b1h5y (d?"~4:N6/B2rW/{+>_P}ƖO [4Ã55@-9誊J>|qjaOF5#ko:~}B/EVPcNu-Wt^[+I%4i#xyCHexp`NA??tO;vl&&we !W !fʼn$'ặ׾#x0iVf!ӴHdqqd4 ;F?~#kj!3^.t;X|=itoiPe}#BPʟF?%}u=_'ĺ%b40|1;U  z_4PS)[?h?؏ጾ _ }&zmn$TW}?+ n^~liZK|`;ؚ7ir I`YPxd`Ak?&k@iz׎<5_|5KԼCkOk.} O,p2U2ͻj+''!! N(UE  qTZZv?ԡ{s&? ۏ?oĻ+Za-^c_WMSO~nHs7RLy7v?˹G(5/(5_ Q'H$(W֝q]fq8%$PntWxgxMrb4v^v:p$4J׶>?(hhڣ=£hkٷh$l6Q#!Q/ @8P]x⎻uI" \[6l YTמxG+ʰ0S+>f,m}zhsR28v*UhDuwŠ(Ϸ ( ( (sk/J^Yjw֐KKǝ esv3EFҾ_~y?}k^Ⴈ'ȇnxVTXV?+z5ܻY[ƿmyabVف YǚE OO$-ş$2ۈa'n!..dgkn+̾vKb6t1H,G@%+wM%Feeh\e?けKZDk'$cW#5jxx yAWi1O/c'ɓAF{HZjsdq11I2![8#}]V>oNI踺gB8T݌P{ȮI$ssZnmtWεUl}Oܤ{iPZIGYP ?+pUc䱴:-.]q=+fZ:Q> kӴfgX\DR>vb /)` xUR>WA7l{3V +Hzճ6 u$9czP@`{֕J01kRt[I`&ds,S'&h8w_߱Ïx[wXNE^"Ek&@Cٞ,2_b4`/|e/jM~*[(dQ 7bq_d[8.᭛Z[>üvs,]Z]Y=ooc믋Z_uoG4L vw2FI.# +Oƞ~/K 96:zgVԄt"$܄vhBPB .Q5?N|75;]\\hI0n k.:ϱ8;/X2 m>WOǟ?a\ٛ+_sVVdFR뵏ɾ$$1~|OA|;MIt %fѮkv 3hʰE%嗖@|NuOOZ}/Eu kF/D,]fI)Pw'`jFL )J*K]iml~KQJ" F.O'1xzgxpƣqi%F;ιb|~_}fm>$GI mק΄ __I؋_[C5-4uof_],R6Bjʯ"̛Aw Fg=1U>_7ľ4u(! R\7k[3=$ӬvF$+U?>06L&MӋ1QXlmUI*Vw2 ;.]_#]s@^]ᦕj9$hʉmDFDrnE$y_ cMӼSf=kBծ, "w4 YvI8eeIĀ2+1XZ,KUr/gѯKGBҌ~$~ƞ_<&ku^{ɒhe$~\ m{|M~rtjNo^s_koC쟲yD<ep?ХO_~6mKWxg4D[WZd]Z)ȯW& Cs #txoPy'Gj^ZGR^4* h ]Xj휣V~!|X8 Og!㸯ձVsg5i? (9ϡgqӼ%QrG%>p jx8GG܀T8Lzw3Nq]x #b4lftF1coFGgeik|\*~_-JM!2G:;Ja3Ιs/i>e5]}љg1-(sԅT+Vߧp :S}>e3W\$#n8cI_/+|?vIlⰲWfki$*$_~G ;6_mys/is(B:(퍤n k'(MX SNvy[6KxYZģ:[[Y1i(N*בS^*s_VAR+ЁUL ]ր,y~&3=h2ܚ{#O# ~ǃ) TrT4K2-cj$׿j\?yHO4FMmN:[~Mn k>)$Kd ?,L9"6\|;_ 埋|xR.-"$C(4)/ogt~͚&!5%R-uP:', %$)*I|huukdеKSӵ+EMjب$8wy TϬJ_T|$jڍGu.}W񅷆`oXxl5> L9 /yPLv$g/4t Qr~^5=/\oB~k-g>} ܉ʒ 6N˩ UgWlvk|})•/g}zjR:}۟хQ_}QEw_K mn~ϮtQ] H[t`|MyΖ/~B1)wԏ:?k &4(h^p@O#< 1-] ,qYړ k˟?_p@wlU6$Wsв?:xO|%u:ЋJF'VAu]ⱏA_߶eSǚ_u|m}K7nHJN]meǭta(*FRQRi]wf8)TQri7ey KW^.9]K }⵺$duR+o?nhD?ZLG#ڤ=WQԗRi Hɾ 'DfEZO̷[\FJG|>fXVHцrFͭ6Y^_ЭJے+Fotnc \?b/7-5ڮvJ?1F$ m'ş|'SEeѭRCVΉ[KpYPebYǷ>,m㡉iYr=6\ҽ[X|lp,J?+}EWgQ@Q@Q@Q@Q@Q@@~[>Iu*/Bҵ[$~㎵z?m{m5%+ }B^tjc'̫E #?li?74=|7y"Q#mN#$ p+/ g>Mkyݵed$r+rH+w|fyq־sIuu{2MF\yFE0C$#B~¦{~altX,k;H"8Bı`P?(eTSJ~K}kzx_Tk%=}IF1HwUB9~͎}+T/1OI2qUdjDNA i'Z_7~uQf\ _7P7~tqSFj)lt 628lg$`O9>ϞYzԁjyrHcYV8sJ#uSxT-ݽAYh|5tuw:!}-ki^F͞^?>1_?B?#: SڟO xF;k[Y)滾/43)XL2rAJ?g~6K}~;U^>~ښCɫ+~D7RCsC[2xY/,:` ~%i_~xwh(m[$xD? rໟF 0S~_+{lbha6rRs Y` w &ӂshO,CC?k4k oEnbxsgq*@܆_'u>w'jw2aHH$*ݳ W~'YF#NS:WINMlthY*QhRˮ?Ro3˯+5~ׅd/ZϏ|cs<:> ]` Oѩ|/-Q??qF7^C{o&5้#W]*TʟZ?(?o~¾# ӼfI2r=$.UeTiaܚv&WO4}s&xf=ά$I};%{ZJdwLO q༿nMԊWpOk \|f/kQxWOEGךJ[Ȋv0U';X* jkOiMai-R+%Ueb22 | aoeE|=sj2nFB Ɇ$*0XSi)KI53sxe2l>Rc8F劣O-~5W,lZ|w;3{Q?X?@ :+KuOP @ Ѹ go><| *敮\Z±"7RF =; Zm9+pVs$h!*1ՊI?FZױHmb`\*$bL2kvFAu}&յ<z/e";i4$L2u"e*xSC)˫`QVֶ[vƯw4u$ru<3y 8䃏Z[`bKrUYITrk.=⣼ Aup$p^hz5-[@?ZÊ/_'~G(Nzuv_OEWʟB ) _, o? n#זwy}٣۷n2F>"SPе6Wѵh!,71VS謳 qʔqu?d mL&SºMG|^{߳޻ԭn> ho&5 &R}Ӿ(>El~w:.=$[t%aл@qtSQ7xOF~o9T0\=ݼo'5 x?^vk7Qhu˛y7G7&A4?ko&GR^4( ̿,@|p^Ey3%ykV{;7շ)2I[E{ qx;Z`zrc_g^ KLdF%rݙҊ63ΤWFݯ_3dY~ NxJ1}R(T((((((( _?ſla{ȉjB(;:ƒ@cĦfPX.TJG۷?xCO^ ]i0 KUԑRG=k#~5݇tے`.P nL2pY[z13_u Zx>"Y\Ih7O [YN:4UR`7]7R⾍2e8u?i߄/~8~^'Ŏxu[ b%(!Y 1+ k.ʆ"S>&IZ4Թq,3 'ڷ~)|"׾xQѵbtMmj[ KɛwePA*eeN_qQ狺>66m/dжA/X6 r 6kc&./O Oԧob[;K-ys&FYr7)#_Џ}OLQm$:j$ Ho# p ?K}P0PIֽCouكO|k+x`}k3-:gts/4]{{˫rܓ;#9)?jo~^_74~Ī 6 ?~8"o11ԣ7NZk?aR36tRGr7/# :t9*]$ . ` _Qבz1|y j8бV"DڦRQOb̿P?&igk KFnnqmb΀3 !KoMݫ-:/ˑut=ιK{?C=MeZtcK8skū] /x8犣w$dU.9}OZ *FY5l0G[8@ 9ox `q^{NfU$()bjgu׃uh.EX/5KXQt&,yi#XypvOO>O ZkkB kSxkI X[ -R _ ɹBG1wo-49xGJL khǕ|Fː-Kp.U`iu;|ӿ4k,_Zǝ^9,|'xb:G5ђ|e|zOpx9` bvJP%c5͵y TڼAH3[߈䰘C)e+B(~"|#}h [yɦȨ9`2pR2ISS~^3ujQxN}Bk=/]˒%DfD,ncl~Gŋ]]#?kۛx..ѡ1$s# 22dz׭fpUx+-w? OWq:n77h岛ʸHeRE*#__P%"o|#t~ o<;eiFKdHU1Ld3go۸nmghnm'F2UHۣ+aA@3jx)A^ti'pxZKox@玵D0| 8,fn#lX|[GR8H=* +"8fw{(8:}2-@dWCSڃTu =kF}@ofC.$Ld5tF S h/k50GySĚu|(Rݖ"Ȥᕶ_|18wIKl[b]F4RmO4-P'# ~KԿž&&M7PB{gW9nfԱP]V :XNꌬN/忋w.N,ۭm༽>$qެ#L \7/ÉZjOּ?_ K6:Rjg r!R>aI@S+Zm]gR /?<_\ŤZKy1@  NN95W wuxƎ:=J]\8v[pвŕ@G&s|g/ો{{Yi,k"MqpW̑<Tnd^w'¿3}xn;+;xHªXUىf`f'^Xz^3ҍj?}~GUEWzEP_6]k+ث #ǚDo{tiS༻m1 9ϕk?&yRxM[ʺ#w\P I?mxZO Yd"$vPw)I73rCp/o |0D߆-ö1i}V֑DHp{k; 1󿲴uwva_o Ks'4彃MӴ)\*H ?IxkōC@5 5>{-cO,i"C(Hj(~,jۏ:k}G$H!{}g???)_7?`Uk[̎A,/&ViĿ_-635MJyEQ~AxZ·!w]fVO]aټpۀwrOpG Qae9VNR|Vn~+f|MԫC ]ESi-uٿ͞Oܞ?g{E}* b'hmpi*8$o9^_|?-/܁3G,*O޸o8wmOo č|?ml{YL§J~WAm:R}6|S; __]H ĊYK0X$_χ|<"/m[;9솙r$t9B\eB_~?&k /-Og[`+N2A2 ||uYNg85%'ѽ$~,f6'VQZ+&V[kK?O;~<-4d+ ׉%{a?|z/s_I @y]KHEY_\XVy&Y%#r=7O ?o\xg'\>k^4'6\E-˫˸w3ςa0f\ ZniMwr{];ӏ^SJIBj-mŻ{Z?YWo>}"_}wi$PݝǦ1޻(O+}6xQϵ,XLqLdp| gm xH^%lY]Ef6 @5 ;}C e&^F2f[[Ś$=m6-|w Eج4GnͿydݝJ>9γLC*ҴedZtW%u}5̟ Ki_i%C{-_C0U'+'?_Wz'ztBUUڤ,beo*\+¿|qxKiͯ@$0t -b,I$I U`(Va{-6^x-.,L$^G^0lhʜԛM/ym]{״GgxySqޜSV?[]?G ],g$}%m|-rmn;qr>%O|"񮿬|d *ڹ+ګ0rnaJTokIvo< yURۺ.MuEWQEQEQEQEl)|~uxcVh!A%u'J*Os-k?omC@ca$͵D+/laYXu^aS~>F--KQitm2pC*:~&NG6TGyerᄘld~߳g?7hmo-LDD8<AV 'mj&܂'r9ր=D8`O_'O?мO;^0ZCSO%#cInT#1>xT~qAowg#3~i1##f޿!h//? wiLֺTm@\[$潬]T矏Vg5ͺUbh$pG@n(#?F;Oj 8"A>jt89㚰1VRM؊.$bblsNd8=+F譞AK020?:#Moo7Z!jܜ^c!H"{Y zܞ1]P#PFO~{÷_X ǯ_st8Njn1: O#5O,5X䃟5ߴnKwXFl=o7C"X94[] -Z[&eYNJꑴH "8PK~g|2][~w.iNӴf*̒}!UWˑ#ݗa#ڻL+O(TzsN8BB

Bq/$H ;*g IZ>Me_>6WjL}(SKKX&*\: .#. 4yS^ˣaUV_E,O&'Ǿ_EsG6:҆E^@]܅/~Ry'O.1XN'9nadQEIAEP_3`dCvG6 \xK44xnFzyhi??j27v~ EݟM̉$w& 1X°pI$$?ӗ>,x_/?G^j7Og$x*\{6૿mLJl_j>jWy4șt]fr~iɉYnKUfwo ,i>i-mg5r(}[zO_ ~Ϳ洵H[4y"nکn7(QI$Brѿ"4em.Ms3Ik}[=6 ;7"ƨ6'R@|koYH 7/qq`qsV$wp4 VZ^gml kikohBhUT76yVQqu#D8{,?߶n_<6ݻc3'gU0_YU'ޖvյXW>x;TWH oxX O:KV;H +S o /;\x`{ǥAjmu%%@5O7]>&3yMiLjsv q`nJ!p }@bujwgKYPutr0;\99V 0s!9ZmĮZGU9PH cw85~߳;$wZc>&ŧE.ShK80kZ]vWq,O HUՇH 8 Q\EZk FH+83r*4I| \xx-><Hܝpd 99_]1> QԴxJq6OҦ+pi(X+/Q [7xbj8Ӆ;6+-l*fGyzʌTit}6W:)7_ACײ o|/ iw.:4{nSjC i/s4^5l$cWkgiOǾ N}k?viYΑ#a`d_B''5osO4h-%ղYÕż++\ʎ"ze%$++ݭˣvy]u:҄qVѻY=~QEyhQEQEQEQEQEQE翴O?ڃcFML f{KK cr2ʰ*p R@2OSj:]λDoR=QpJƻslSrebއOڏ|Oi^ 5MڥͭGI3N.Pg)_[ h/ i$Ӵ F;Y eyA8_mngែmvPӴ"Q{:9TUw21~\H%};Ldz{N\IzvX xk%ƽ],ңrGon]K`)K+$m_W_b~ t$8&0 wRƲ:BK  y5(LV:w=N;'~?Oʒ*r@3}J=hr2(((((((((((((((((2=E5LMgcJpF@;J:9U&UTPrBNM\ ݊]AW;?{dV61F=MR.Gc62Z_G1^eKKpH1k~3zLN(@7_$z?*}W_ڝ-C?ڪTGW_Pc޳~4[5wle>\nPae,B?GnA' t@zࠗ.,#KŮl#NO~y_mqtRAr?0?1b?hC#ymNB+OϐEc4(h7xSiu#":Zv-d im&/ Z#.մH2}Mh|HH>5n r  ~ի9L.Uò]wZx)T0=(P>e;F~M]Ƈnv*LUL>m+ϡ1*axƏE' kҼp& JG60Ú'8-?upjZ|)Iy4l7L@"$RyJ*')'9)(V23EQEQEQEQEQEQEQEQEQEQEQEQEQEF:Fz\dG"lvrqU8# zx\MgNGB+Ud$-MRřOЙ# n+qĞw j9mʈbּ&d @5/t+|kʼm Vռ98pv\z|YV6={O~\I=|q>\XŻD^%{38\^/WWeL߹#ں!cW8[w,Y7:KH>ر10ǵcϠ۱R=hܮRs#olsITcqjgê*QE&ӌcRcI(VyvVG8F#sMMs>>Ԭ3JƷ!u>kƹm?7L&Ou~_w+!0ϵDCgG:#^_WM}!&93+ּ6b7+8Ø?|Q,^w%޼w !Gc?&#qQ\:iYB Ldu\ּ c WxkOӆ\hA֞M3]frѕcj8L(ݱ/y5m1V}UsZ6#3RÞ I9~=I5$h} +s95 昣cs֐Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@(aҐ9!xR 5BFGjHT6r: lQ5NKlIUs09,H5/,ێεߴ*Fj,,rȒW9Iv}gd5_B>~ -Q=aZ`ݯԻoZ7¯Z|7 ڮ >! GCLnl@boâ쇏+"\dP? ش>x2㇉熿ceoTK`[^AZ~RPh|-pp?ٮA%}ڭtPWtpbslRH]zcpK0TCa +7;09 *c*@KM'n\Z H1|HU@8$g&@1#! HE>((((((((((((((mobile-atlas-creator-1.9.14+dfsg1/src/main/resources/mobac/resources/images/mobac16.png0000644000175000017500000000165512122526606030560 0ustar paulliupaulliuPNG  IHDRatIDATx][lU93-nKٶvͦm+S Fфg_L H"`HC%Z.Ԯ+l펻3srDף;pL&.av4Wv{ޑɽCuvP\/5z ^O!Es |,J` 3I5 =mFd^[ϸT@KA,N&~t{vBk dRp %<qboKdYwb|>N@F-Pj " RT حz[  .G (&Ɨ{oD4_'փ{93E2O00- \]YͩbsSClU:P8 agѱɈIpv\Y 9<۠ag禉{V%r\Y#@).l`O|?+BH- _A%U+sL`b~dI2(F=_@Aȿ?EQp1;yQ!m~8iHJAzޤCmը+5MӠ*8u @ Mdw}wP XXbXVdzrd2y}0ioo_f|5"G#B0097_gRDQ`'V-mm:6@`h2#t\~ȏ7le2rk;!"raݪ cip}6Ѫ܎y<ܑyhJo"-"O.sx^(q:'{05(Wԙ_IENDB`mobile-atlas-creator-1.9.14+dfsg1/src/main/resources/mobac/resources/images/arrow_open.png0000644000175000017500000000073112122526606031475 0ustar paulliupaulliuPNG  IHDR;֕JgAMA a pHYs``GZRtEXtSoftwarePaint.NET v3.36%WIDAT8Oc`:z?N f!ގ Wj! la 4 /Pb:@Ÿek xĮ=?{+l0?Xϒd_ b&!@iwA"MiV7W dbQa]V@5_{SSC@li]IL"0~qN]d#60,%_1f3Xj`?BmTd@ӡ6" C̋,3ϐkljX==FΊ0gbgl ]s/ԉdm"sm=bǿIENDB`mobile-atlas-creator-1.9.14+dfsg1/src/main/resources/mobac/resources/images/minus.png0000644000175000017500000000025312122526606030454 0ustar paulliupaulliuPNG  IHDR Vu\gAMA a pHYs::6)QtEXtSoftwarePaint.NET v3.317w)IDAT(Sc`` /'#Ky.b9 $s,)vcIENDB`mobile-atlas-creator-1.9.14+dfsg1/src/main/resources/mobac/resources/images/arrow_blue_up.png0000644000175000017500000000331112122526606032164 0ustar paulliupaulliuPNG  IHDR?~sBIT|d pHYs CtEXtSoftwarewww.inkscape.org<tEXtTitleArrow Blue Upâ*tEXtAuthorJean-Victor BalinJL'tEXtDescriptionjean.victor.balin@gmail.comQtEXtCreation Time2005-10-30OȑZItEXtCopyrightPublic Domain http://creativecommons.org/licenses/publicdomain/YWIDATH[o\WoO3c`;vծBHB$P/z \p\ (g?q(EZB 6MRƱ{<ŚIvK[Kڳf=}$$gyBDL8."2iٯ]}ׁMs8A]A?˧矯~u].ȳ8򡤻T'GD4o" ;.VGDQGf9F+:TW+}o \8<&3w07"IM{lmh{O/_ܟxwZ ObcIw6iG >OσGN|*?qӽcǨu77z4W6Qׂ|?~_'#cfYKϰku obw/9_r,pq OH6{Y pc?&qpq3|G. gof뽇8PJɐ%C^ !|\o|;wSzGD~]}9P(p!f}{g0}sO"gO=FSg"[hsRn'E *8>ĝ[E]xsD=>#Ie.4\5ӝ4Ѥ"M$F$R0:/Yܧ׷Xe0ȚF}L9O)Bv9|NT#풲]h*Lԃ!Pa\Ͻk/o4F3_J[~C0"K5Z ooNr$3r#Lh"dIMz1CY ag(JQ ѴXuGJ-c5]!ʦn[`ڵȨ%hql-r kqSj[ZÅxўHq00`,2d t :ʆ ^l|k(v՝é7UV=I7́b}Qfvtor/ňn@8"/20 `wOQIp\g{UXpV劺4, g*%?¸a0*JXM1VARTlwGA bx$- E Aij&/Jy^3;H;jsPP+S z#P- ec}0'2j~,px1P$7{XdS@0?sѫk;جV|:DHۙPt &Q*&Ga˱zl恓$tZvPWNHa(x<֫W <ߟNz3{ofdEa3_ti<P,6FuȚ&HB JHDM>@`dȔIxyHsps^ "qy:,2Ih𗑷$5>$]TH| oACPd}Y ,dh@X cH1~Rnvb\GQ>$0`@%"XA^ RSPRAt _NHSRfWK@eSC P+wwa#hJ9""Zo{d|`/,X `||*k64#CM=]$G}X  yL"pTP"0It|?s}XI| *hëK㱡m)ή̹yf/6 V 7mR(g4ʽV `/Q@Q-}>TY䀪ḿZߨDX_GJ;"+OoeQRDL8&$Fߟ[{3%DqQ&hQ@}ILfB>Yѯ-Ƈ?Wyi ]]XH"wW$s'GCiРA*o}͔/kMrFBF#@G$O󑾋p 18SǢL Id4WZ?'߁X>̆- . z:`͎ u <ӊhoACEu8"'Tm 3جzU:y- tǣ.Q=x-i>W5IMK\2@ImYg|*kHx6T6AQerʋ)]M[l&,voIdxxMta>sT` EGQFFS/! 7AH"hK?j{ ޮ`PF5b|0w˜̺aCmF8%@y Y [ͣAy?UkL!V!SF[RƼy[er˸M_Z8\mt3PZ&H@*!؛}rҍ>}LU2@Xaq=)E-AݤfgM)K 2,n`m2ܯEmUTǂnTb=FxXѹVCr:kuGS 87J]:]\mkղ9˨sp f&Ihv<BʅLih#$R m9$iG8,Z$4w' '^<I}f.#5M( i\ Δ{U1 @ir*h9L9Z{!n*f /j\/еcxqT 7܉UAi3v 2yHE <H`UkB hJ'5IJ*R%Včm Dc;N3!1n:)6{TDs}t: Ij d<UY#*̙!I =C^ t I_sI6D)mg,DEL)SRU XB ,l6;EIх $A6K@\Ba{Ĭo<({JuQK EimJhZ@LXj T]x3F5{5WcᡆFK,?byۤ~։iNI;91jTqpmb6fڠymۻ9~aF(KF?颲tiڴc #4::>j( TxIЬ\h\ +3 ^;޿(\L0:WeBhiҥ2gaˮ\SP̤&p9^gDr9[WhqرI M, Lϟc,'^Fqٱ2y^gHؓ}Λ[9JifΜHDEE\ f/ٌzP]Sσ 3QKQC9bSef# ]jGM qüoy Y>]։YyW XreV`"u)NphITZ># @:` ?vzuJ%Tzid5w?ᣯQ[Qs%t >u 9‚Yܔ~w/c֔3h3,]9%4#(!EU@#P nA(R:%iG͜BBpe4a(Q%#A3 ?#dl_p`aԈq$D[`>yڏfW ,[VXXtO NU2 UD\hmtEDh6$d>N=?ɹfH ӆ 2¢j+ҫ']>$҉6]^5u,_ ? %2ZO 4܌ZT=D*^xTj=x|hΝOmoc{/gsԩŤ20a'd.4 S$s746\ `)$yt2C#t;c>Ŷ^V̙UGX,uk6م`† G.7S'|G3|\@a}(Da802?8e;VDD !2/8oH`+J)L2! lb&ËG-9|d>L1^d'I e‘A'.$`m\ӨbJύڝ5Oa?c#\>1DPFp{YVo؇8@sY8vh?O%M ]pM!@i<@`|f˓K-IoAp^q.c*`iurUC0ܯS !(YxBہƲk {*S"+K)uVĉo^AD |HhBZs;d^nv `@_ Rn3` {.R)ԛwV[Bp@ k˄=ct8hhV.O|3}ycGwZmz nu'\8/8'd5wq zJO%31>ž v-_[ U7o׹~kPFuʛzc=|?դR@01`O͞; K$ˍ+IENDB`mobile-atlas-creator-1.9.14+dfsg1/src/main/resources/mobac/resources/images/arrow_closed.png0000644000175000017500000000115012122526606032001 0ustar paulliupaulliuPNG  IHDR;֕JsRGBgAMA a cHRMz&u0`:pQ< pHYsaaøtEXtSoftwarePaint.NET v3.36%IDAT8O;,Cam $N݂D\bPSBPAZT&*eh#00`fQ^Tq7vN&-7Dk0m rjT!ajr`dK-2;l^CgZVv ѻv˙ee[W\ n^o:|Di>LcXvoЧV^[Hy5ixpvqF&)*G=(:yE|/cP:rm6?gA׳8R(Γgн @p U܆X-%Y3Q_> 1SfFEC$U>I0F~&g. ******************************************************************************/ package featuretests; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.security.SecureRandom; public class SimpleHttpClient implements Runnable { static SecureRandom RND = new SecureRandom(); public static void main(String[] args) throws InterruptedException { int threadCount = 8; Thread[] threads = new Thread[threadCount]; for (int i = 0; i < threadCount; i++) { Thread t = new Thread(new SimpleHttpClient(), "Worker " + i); t.start(); threads[i] = t; } for (Thread t : threads) t.join(); } public void run() { try { for (int i = 0; i < 100; i++) load(); } catch (Exception e) { e.printStackTrace(); } } public void load() throws MalformedURLException, IOException { String url = String.format("http://localhost/tile?x=%d&y=%d&z=8", RND.nextInt(1000), RND.nextInt(1000)); HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection(); conn.setConnectTimeout(5000); conn.setReadTimeout(5000); conn.connect(); int code = conn.getResponseCode(); if (code != 200) throw new IOException("Invalid HTTP response"); InputStream in = conn.getInputStream(); ByteArrayOutputStream bout = new ByteArrayOutputStream(32000); byte[] buffer = new byte[2049]; do { int read = in.read(buffer); if (read <= 0) break; bout.write(buffer, 0, read); } while (true); System.out.println(Thread.currentThread().getName() + " retrieved " + bout.size() + " bytes - url: " + url); } } mobile-atlas-creator-1.9.14+dfsg1/src/test/java/featuretests/SimpleServer.java0000644000175000017500000000710012122526602027210 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package featuretests; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.awt.image.IndexColorModel; import java.io.IOException; import java.security.SecureRandom; import java.util.Properties; import javax.imageio.IIOImage; import javax.imageio.ImageIO; import javax.imageio.ImageWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import Acme.Serve.Serve; public class SimpleServer { static SecureRandom RND = new SecureRandom(); private static final byte[] COLORS = { 0,// (byte) 0xff, (byte) 0xff, (byte) 0xff, // white (byte) 0xff, (byte) 0x00, (byte) 0x00 // red }; private static final IndexColorModel COLORMODEL = new IndexColorModel(8, 2, COLORS, 1, false); private static final Font FONT_LARGE = new Font("Sans Serif", Font.BOLD, 30); private static final Font FONT_SMALL = new Font("Sans Serif", Font.BOLD, 20); public static class DummyDataServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { BufferedImage image = new BufferedImage(256, 256, BufferedImage.TYPE_BYTE_INDEXED, COLORMODEL); Graphics2D g2 = image.createGraphics(); try { g2.setColor(Color.WHITE); g2.fillRect(0, 0, 255, 255); g2.setColor(Color.RED); g2.drawRect(0, 0, 255, 255); g2.drawLine(0, 0, 255, 255); g2.drawLine(255, 0, 0, 255); String url = request.getRequestURL().toString(); String query = request.getQueryString(); if (query != null) url += "?" + query; String[] strings = url.split("[\\&\\?]"); int y = 40; g2.setFont(FONT_SMALL); for (String s : strings) { g2.drawString(s, 8, y); g2.setFont(FONT_LARGE); y += 35; } ImageWriter writer = ImageIO.getImageWritersByFormatName("jpeg").next(); writer.setOutput(ImageIO.createImageOutputStream(response.getOutputStream())); IIOImage ioImage = new IIOImage(image, null, null); writer.write(null, ioImage, null); } catch (Exception e) { e.printStackTrace(); } finally { g2.dispose(); } } } public static void main(String[] args) { Properties properties = new Properties(); properties.put("port", 80); properties.put("z", "20"); properties.put("keep-alive", Boolean.TRUE); properties.put("bind-address", "127.0.0.1"); properties.setProperty(Acme.Serve.Serve.ARG_NOHUP, "nohup"); Serve tjws = new Serve(properties, System.out); tjws.addServlet("/", new DummyDataServlet()); tjws.serve(); } } mobile-atlas-creator-1.9.14+dfsg1/src/test/java/featuretests/TileCoverageTest.java0000644000175000017500000000472012122526602030006 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package featuretests; import java.awt.Point; import java.awt.image.BufferedImage; import java.io.File; import javax.imageio.ImageIO; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JLabel; import mobac.mapsources.MapSourcesManager; import mobac.program.Logging; import mobac.program.tilestore.TileStore; import mobac.program.tilestore.berkeleydb.BerkeleyDbTileStore; import mobac.program.tilestore.berkeleydb.DelayedInterruptThread; public class TileCoverageTest { public static class MyThread extends DelayedInterruptThread { public MyThread() { super("Test"); } @Override public void run() { BerkeleyDbTileStore tileStore = (BerkeleyDbTileStore) TileStore.getInstance(); try { int zoom = 8; BufferedImage image = tileStore.getCacheCoverage( MapSourcesManager.getInstance().getSourceByName("Google Maps"), zoom, new Point(80, 85), new Point(1 << zoom, 1 << zoom)); ImageIO.write(image, "png", new File("test.png")); JFrame f = new JFrame("Example"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.getContentPane().add( new JLabel(new ImageIcon( image.getScaledInstance(image.getWidth() * 4, image.getHeight() * 4, 0)))); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); } catch (Exception e) { e.printStackTrace(); } tileStore.closeAll(); } } public static void main(String[] args) throws InterruptedException { Logging.configureConsoleLogging(); TileStore.initialize(); Thread t = new MyThread(); t.start(); t.join(); } } mobile-atlas-creator-1.9.14+dfsg1/src/test/java/mapsources/0000755000175000017500000000000012122526602023372 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/test/java/mapsources/MapSourceTestFailedException.java0000644000175000017500000000542612122526602031766 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mapsources; import java.io.IOException; import java.io.StringWriter; import java.net.HttpURLConnection; import java.net.URL; import java.util.List; import java.util.Map; import mobac.program.interfaces.MapSource; public class MapSourceTestFailedException extends Exception { private static final long serialVersionUID = 1L; final int httpResponseCode; final HttpURLConnection conn; final URL url; final Class mapSourceClass; public MapSourceTestFailedException(MapSource mapSource, String msg, HttpURLConnection conn) throws IOException { super(msg); this.mapSourceClass = mapSource.getClass(); this.conn = conn; this.url = conn.getURL(); this.httpResponseCode = conn.getResponseCode(); } public MapSourceTestFailedException(MapSource mapSource, HttpURLConnection conn) throws IOException { this(mapSource, "", conn); } public MapSourceTestFailedException(Class mapSourceClass, URL url, int httpResponseCode) { super(); this.mapSourceClass = mapSourceClass; this.url = url; this.conn = null; this.httpResponseCode = httpResponseCode; } public int getHttpResponseCode() { return httpResponseCode; } @Override public String getMessage() { String msg = super.getMessage(); msg = "MapSource test failed: " + msg + " " + mapSourceClass.getSimpleName() + " HTTP " + httpResponseCode + "\n" + conn.getURL(); if (conn != null) msg += "\n" + printHeaders(conn); return msg; } protected String printHeaders(HttpURLConnection conn) { StringWriter sw = new StringWriter(); sw.append("Headers:\n"); for (Map.Entry> entry : conn.getHeaderFields().entrySet()) { String key = entry.getKey(); for (String elem : entry.getValue()) { if (key != null) sw.append(key + " = "); sw.append(elem); sw.append("\n"); } } return sw.toString(); } } mobile-atlas-creator-1.9.14+dfsg1/src/test/java/mapsources/MapSourceTestCase.java0000644000175000017500000000754012122526602027575 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mapsources; import java.net.HttpURLConnection; import junit.framework.TestCase; import mobac.mapsources.AbstractHttpMapSource; import mobac.program.download.TileDownLoader; import mobac.program.interfaces.HttpMapSource; import mobac.program.interfaces.MapSpace; import mobac.program.interfaces.MapSource.LoadMethod; import mobac.program.model.EastNorthCoordinate; import mobac.program.model.Settings; import mobac.tools.Cities; import mobac.utilities.Utilities; public class MapSourceTestCase extends TestCase { private final HttpMapSource mapSource; private final EastNorthCoordinate testCoordinate; public MapSourceTestCase(Class mapSourceClass) throws InstantiationException, IllegalAccessException { this(mapSourceClass.newInstance()); } public MapSourceTestCase(HttpMapSource mapSource) { this(mapSource, Cities.getTestCoordinate(mapSource, Cities.BERLIN)); } public MapSourceTestCase(HttpMapSource mapSource, EastNorthCoordinate testCoordinate) { super(mapSource.getName()); this.mapSource = mapSource; this.testCoordinate = testCoordinate; } public void runMapSourceTest() throws Exception { runTest(); } @Override protected void runTest() throws Exception { int zoom = mapSource.getMaxZoom(); MapSpace mapSpace = mapSource.getMapSpace(); int tilex = mapSpace.cLonToX(testCoordinate.lon, zoom) / mapSpace.getTileSize(); int tiley = mapSpace.cLatToY(testCoordinate.lat, zoom) / mapSpace.getTileSize(); if (mapSource instanceof AbstractHttpMapSource) try { mapSource.getTileData(-1, 0, 0, LoadMethod.SOURCE); } catch (Exception e) { } HttpURLConnection c = mapSource.getTileUrlConnection(zoom, tilex, tiley); c.setReadTimeout(10000); c.addRequestProperty("User-agent", Settings.getInstance().getUserAgent()); c.setRequestProperty("Accept", TileDownLoader.ACCEPT); c.connect(); try { // if (c.getResponseCode() == 302) { // log.debug(c.getResponseMessage()); // } if (c.getResponseCode() != 200) { throw new MapSourceTestFailedException(mapSource, c); } byte[] imageData = Utilities.getInputBytes(c.getInputStream()); if (imageData.length == 0) throw new MapSourceTestFailedException(mapSource, "Image data empty", c); if (Utilities.getImageType(imageData) == null) { throw new MapSourceTestFailedException(mapSource, "Image data of unknown format", c); } switch (mapSource.getTileUpdate()) { case ETag: case IfNoneMatch: if (c.getHeaderField("ETag") == null) { throw new MapSourceTestFailedException(mapSource, "No ETag present but map sources uses " + mapSource.getTileUpdate() + "\n", c); } break; case LastModified: if (c.getHeaderField("Last-Modified") == null) throw new MapSourceTestFailedException(mapSource, "No Last-Modified entry present but map sources uses " + mapSource.getTileUpdate() + "\n", c); break; } } finally { c.disconnect(); } } } mobile-atlas-creator-1.9.14+dfsg1/src/test/java/mapsources/MapSourcesTestSuite.java0000644000175000017500000000740212122526602030173 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mapsources; import java.net.HttpURLConnection; import java.util.HashSet; import javax.xml.bind.JAXBException; import junit.framework.TestSuite; import mobac.mapsources.AbstractMultiLayerMapSource; import mobac.mapsources.DefaultMapSourcesManager; import mobac.mapsources.MapSourcesManager; import mobac.mapsources.impl.DebugMapSource; import mobac.mapsources.impl.LocalhostTestSource; import mobac.program.Logging; import mobac.program.ProgramInfo; import mobac.program.interfaces.HttpMapSource; import mobac.program.interfaces.MapSource; import mobac.program.model.EastNorthCoordinate; import mobac.program.model.Settings; import mobac.tools.Cities; import org.apache.log4j.Level; import org.apache.log4j.Logger; import unittests.helper.DummyTileStore; /** * {@link TestSuite} that tests every available map source for operability. The operability test consists of the * download of one map tile at the highest available zoom level of the map source. By default the map tile to be * downloaded is located in the middle of Berlin (at the coordinate of {@link #BERLIN}). As some map providers do not * cover Berlin for each {@link MapSource} a different test coordinate can be specified using {@link #testCoordinates}. * */ public class MapSourcesTestSuite extends TestSuite { protected final Logger log; public static final EastNorthCoordinate C_DEFAULT = Cities.BERLIN; private HashSet testedMapSources; public MapSourcesTestSuite() throws JAXBException { super(); HttpURLConnection.setFollowRedirects(false); Logging.configureConsoleLogging(); Logger.getRootLogger().setLevel(Level.ERROR); log = Logger.getLogger(MapSourcesTestSuite.class); testedMapSources = new HashSet(); DefaultMapSourcesManager.initialize(); Settings.load(); for (MapSource mapSource : MapSourcesManager.getInstance().getAllMapSources()) { if (mapSource instanceof DebugMapSource || mapSource instanceof LocalhostTestSource) continue; if (mapSource instanceof AbstractMultiLayerMapSource) { for (MapSource ms : (AbstractMultiLayerMapSource) mapSource) addMapSourcesTestCase(ms); } else addMapSourcesTestCase(mapSource); } } private void addMapSourcesTestCase(MapSource mapSource) { if (!(mapSource instanceof HttpMapSource)) return; if (testedMapSources.contains(mapSource.getName())) return; EastNorthCoordinate coordinate = Cities.getTestCoordinate(mapSource, C_DEFAULT); addTest(new MapSourceTestCase((HttpMapSource) mapSource, coordinate)); testedMapSources.add(mapSource.getName()); } public static TestSuite suite() throws JAXBException { Logging.configureConsoleLogging(); ProgramInfo.initialize(); // Load revision info DummyTileStore.initialize(); DefaultMapSourcesManager.initializeEclipseMapPacksOnly(); MapSourcesTestSuite testSuite = new MapSourcesTestSuite(); return testSuite; } } mobile-atlas-creator-1.9.14+dfsg1/src/test/java/mobac/0000755000175000017500000000000012122526602022272 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/test/java/mobac/tools/0000755000175000017500000000000012122526602023432 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/test/java/mobac/tools/MapPackUploadSelector.java0000644000175000017500000000513712122526602030465 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.tools; import java.io.File; import java.security.cert.CertificateException; import mobac.mapsources.loader.MapPackManager; import mobac.program.Logging; import mobac.program.ProgramInfo; import mobac.utilities.Utilities; import org.apache.log4j.Level; import org.apache.log4j.Logger; public class MapPackUploadSelector { /** * @param args */ public static void main(String[] args) { Logging.configureConsoleLogging(Level.DEBUG); Logger log = Logger.getLogger(MapPackUploadSelector.class); ProgramInfo.initialize(); try { File mapPackDir = new File("mapsources"); File mapPackUpdateDir = new File(mapPackDir, "updates"); Utilities.mkDirs(mapPackUpdateDir); for (File newMapPack : mapPackUpdateDir.listFiles()) Utilities.deleteFile(newMapPack); Utilities.mkDirs(mapPackUpdateDir); MapPackManager mpm = new MapPackManager(mapPackDir); String md5sumList = mpm.downloadMD5SumList(); String[] changedMapPacks = mpm.searchForOutdatedMapPacks(md5sumList); for (String mapPackName : changedMapPacks) { log.info("Changed local map pack found: " + mapPackName); File mapPack = new File(mapPackDir, mapPackName); try { mpm.testMapPack(mapPack); File mapPackCopy = new File(mapPackUpdateDir, mapPackName); Utilities.copyFile(mapPack, mapPackCopy); } catch (CertificateException e) { log.error("Map pack not copied because of invalid signature", e); } } if (changedMapPacks.length > 0) { Utilities.copyFile(new File(mapPackDir, "mappacks-md5.txt"), new File(mapPackUpdateDir, "mappacks-md5.txt")); } else { log.info("No updated map packs found"); } } catch (Exception e) { log.error(e.getMessage(), e); } } } mobile-atlas-creator-1.9.14+dfsg1/src/test/java/mobac/tools/MapSourceCapabilityGUI.java0000644000175000017500000000637712122526602030557 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.tools; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.HeadlessException; import java.util.List; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JTable; import javax.swing.table.AbstractTableModel; import javax.swing.table.DefaultTableCellRenderer; public class MapSourceCapabilityGUI extends JFrame { private final List result; public MapSourceCapabilityGUI(List result) throws HeadlessException { super("Map source capabilities"); setLayout(new BorderLayout()); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.result = result; JTable table = new JTable(new Model()); table.setDefaultRenderer(Object.class, new Renderer()); add(table.getTableHeader(), BorderLayout.NORTH); add(table, BorderLayout.CENTER); pack(); } private class Model extends AbstractTableModel { public int getRowCount() { return result.size(); } public Object getValueAt(int rowIndex, int columnIndex) { MapSourceCapabilityDetector mscd = result.get(rowIndex); switch (columnIndex) { case 0: return mscd.getZoom(); case 1: return mscd.iseTagPresent(); case 2: return mscd.isLastModifiedTimePresent(); case 3: return mscd.isIfNoneMatchSupported(); case 4: return mscd.isIfModifiedSinceSupported(); case 5: return mscd.getContentType(); } return null; } public int getColumnCount() { return 6; } public String getColumnName(int column) { switch (column) { case 0: return "Zoom"; case 1: return "eTag"; case 2: return "LastModified"; case 3: return "IfNoneMatch"; case 4: return "IfModifiedSince"; case 5: return "Content type"; } return null; } } private class Renderer extends DefaultTableCellRenderer { @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { this.setHorizontalAlignment(JLabel.CENTER); Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); if ((value != null) && (value instanceof Boolean) && ((Boolean) value)) c.setBackground(Color.GREEN); else c.setBackground(Color.WHITE); return c; } } } mobile-atlas-creator-1.9.14+dfsg1/src/test/java/mobac/tools/MapUpdateTypeLister.java0000644000175000017500000000321612122526602030204 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.tools; import java.util.Vector; import mobac.mapsources.MapSourcesManager; import mobac.program.Logging; import mobac.program.interfaces.HttpMapSource; import mobac.program.interfaces.MapSource; public class MapUpdateTypeLister { /** * @param args */ public static void main(String[] args) { Logging.configureConsoleLogging(); Vector mapSources = MapSourcesManager.getInstance().getAllMapSources(); for (MapSource mapSource : mapSources) { if (mapSource instanceof HttpMapSource) { HttpMapSource httpMapSource = (HttpMapSource) mapSource; String name = mapSource.getName(); name = name.substring(0, Math.min(25, name.length())); System.out.println(String.format("%25s %s", name, httpMapSource.getTileUpdate())); } } } } mobile-atlas-creator-1.9.14+dfsg1/src/test/java/mobac/tools/testtileserver/0000755000175000017500000000000012122526602026516 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/test/java/mobac/tools/testtileserver/servlets/0000755000175000017500000000000012122526602030365 5ustar paulliupaulliu././@LongLink0000000000000000000000000000016100000000000011563 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/test/java/mobac/tools/testtileserver/servlets/PngTileGeneratorServlet.javamobile-atlas-creator-1.9.14+dfsg1/src/test/java/mobac/tools/testtileserver/servlets/PngTileGenerator0000644000175000017500000000425412122526602033526 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.tools.testtileserver.servlets; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import mobac.utilities.imageio.Png4BitWriter; /** * * Generates for each request a png tile of size 256x256 containing the url request broken down to multiple lines. * * @author r_x * */ public class PngTileGeneratorServlet extends AbstractTileGeneratorServlet { private int pngCompressionLevel; public PngTileGeneratorServlet(int pngCompressionLevel) { super(); this.pngCompressionLevel = pngCompressionLevel; } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { BufferedImage tile = generateImage(request); response.setContentType("image/png"); OutputStream out = response.getOutputStream(); ByteArrayOutputStream bout = new ByteArrayOutputStream(16000); Png4BitWriter.writeImage(bout, tile, pngCompressionLevel, request.getRequestURL().toString()); byte[] buf = bout.toByteArray(); response.setContentLength(buf.length); out.write(buf); out.close(); response.flushBuffer(); } } ././@LongLink0000000000000000000000000000015400000000000011565 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/test/java/mobac/tools/testtileserver/servlets/PngFileTileServlet.javamobile-atlas-creator-1.9.14+dfsg1/src/test/java/mobac/tools/testtileserver/servlets/PngFileTileServl0000644000175000017500000000457412122526602033500 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.tools.testtileserver.servlets; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * * Returns for each an every request the same static png file. For performance reasons the file "tile.png" is cached on * servlet initialization. * * @author r_x * */ public class PngFileTileServlet extends AbstractTileServlet { public static final String[] IMAGE_NAMES = { "tile.png", "gradient.png", "cross.png" }; private byte[] fileContent = null; private final int imageNum; public PngFileTileServlet(int imageNum) { super(); this.imageNum = imageNum; } @Override public void init() throws ServletException { super.init(); try { String image = IMAGE_NAMES[imageNum]; InputStream in = this.getClass().getResourceAsStream("images/" + image); fileContent = new byte[in.available()]; in.read(fileContent); in.close(); log.info("Static png file " + image + " loaded successfully"); } catch (IOException e) { log.error(e.getMessage()); } } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("image/png"); response.setContentLength(fileContent.length); OutputStream out = response.getOutputStream(); out.write(fileContent); out.close(); response.flushBuffer(); } } ././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/test/java/mobac/tools/testtileserver/servlets/AbstractTileServlet.javamobile-atlas-creator-1.9.14+dfsg1/src/test/java/mobac/tools/testtileserver/servlets/AbstractTileServ0000644000175000017500000000617012122526602033535 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.tools.testtileserver.servlets; import java.io.IOException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; public abstract class AbstractTileServlet extends HttpServlet { protected static final SecureRandom RND = new SecureRandom(); protected final Logger log; /** * Error rate in percent [0..100] */ protected int errorRate = 0; protected boolean errorOnUrl = true; protected int delay = 0; private final MessageDigest md5; public AbstractTileServlet() { log = Logger.getLogger(this.getClass()); try { md5 = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } } @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { Thread.sleep(delay); } catch (InterruptedException e) { } if (errorResponse(request, response)) return; super.service(request, response); } public boolean errorResponse(HttpServletRequest request, HttpServletResponse response) throws IOException { if (errorRate == 0) return false; if (errorOnUrl) { String url = request.getRequestURL() + request.getQueryString(); byte[] digest = md5.digest(url.getBytes()); int hash = Math.abs(digest[4] % 100); log.debug(url.toString() + " -> " + hash + ">" + errorRate + "?"); if (hash > errorRate) return false; } else { int rnd = RND.nextInt(100); if (rnd > errorRate) return false; } response.sendError(404); log.debug("Error response sent"); return true; } public int getErrorRate() { return errorRate; } public void setErrorRate(int errorRate) { this.errorRate = errorRate; } public boolean isErrorOnUrl() { return errorOnUrl; } public void setErrorOnUrl(boolean errorOnUrl) { this.errorOnUrl = errorOnUrl; } public int getDelay() { return delay; } public void setDelay(int delay) { this.delay = delay; } } ././@LongLink0000000000000000000000000000016600000000000011570 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/test/java/mobac/tools/testtileserver/servlets/AbstractTileGeneratorServlet.javamobile-atlas-creator-1.9.14+dfsg1/src/test/java/mobac/tools/testtileserver/servlets/AbstractTileGene0000644000175000017500000000462412122526602033476 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.tools.testtileserver.servlets; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.awt.image.IndexColorModel; import javax.servlet.http.HttpServletRequest; public abstract class AbstractTileGeneratorServlet extends AbstractTileServlet { private static final byte[] COLORS = { 0,// (byte) 0xff, (byte) 0xff, (byte) 0xff, // white (byte) 0xff, (byte) 0x00, (byte) 0x00 // red }; private static final IndexColorModel COLORMODEL = new IndexColorModel(8, 2, COLORS, 1, false); private static final Font FONT_LARGE = new Font("Sans Serif", Font.BOLD, 30); private static final Font FONT_SMALL = new Font("Sans Serif", Font.BOLD, 20); protected BufferedImage generateImage(HttpServletRequest request) { BufferedImage tile = new BufferedImage(256, 256, BufferedImage.TYPE_BYTE_INDEXED, COLORMODEL); Graphics2D g2 = tile.createGraphics(); try { g2.setColor(Color.WHITE); g2.fillRect(0, 0, 255, 255); g2.setColor(Color.RED); g2.drawRect(0, 0, 255, 255); g2.drawLine(0, 0, 255, 255); g2.drawLine(255, 0, 0, 255); String url = request.getRequestURL().toString(); String query = request.getQueryString(); if (query != null) url += "?" + query; log.debug(url); String[] strings = url.split("[\\&\\?]"); int y = 40; g2.setFont(FONT_SMALL); for (String s : strings) { g2.drawString(s, 8, y); g2.setFont(FONT_LARGE); y += 35; } } finally { g2.dispose(); } return tile; } } ././@LongLink0000000000000000000000000000016100000000000011563 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/test/java/mobac/tools/testtileserver/servlets/JpgTileGeneratorServlet.javamobile-atlas-creator-1.9.14+dfsg1/src/test/java/mobac/tools/testtileserver/servlets/JpgTileGenerator0000644000175000017500000000453212122526602033521 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.tools.testtileserver.servlets; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import mobac.program.tiledatawriter.TileImageJpegDataWriter; /** * * Generates for each request a png tile of size 256x256 containing the url request broken down to multiple lines. * * @author r_x * */ public class JpgTileGeneratorServlet extends AbstractTileGeneratorServlet { private final TileImageJpegDataWriter jpgWriter; /** * @param compressionLevel * [0..100] */ public JpgTileGeneratorServlet(int compressionLevel) { super(); jpgWriter = new TileImageJpegDataWriter(compressionLevel / 100d); jpgWriter.initialize(); } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { BufferedImage tile = generateImage(request); response.setContentType("image/jpeg"); ServletOutputStream out = response.getOutputStream(); ByteArrayOutputStream bout = new ByteArrayOutputStream(32000); try { synchronized (jpgWriter) { jpgWriter.processImage(tile, bout); } byte[] buf = bout.toByteArray(); response.setContentLength(buf.length); out.write(buf); } finally { out.close(); response.flushBuffer(); } } } ././@LongLink0000000000000000000000000000015100000000000011562 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/test/java/mobac/tools/testtileserver/servlets/ShutdownServlet.javamobile-atlas-creator-1.9.14+dfsg1/src/test/java/mobac/tools/testtileserver/servlets/ShutdownServlet.0000644000175000017500000000300212122526602033541 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.tools.testtileserver.servlets; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import Acme.Serve.Serve; public class ShutdownServlet extends HttpServlet { private final Serve server; public ShutdownServlet(Serve server) { super(); this.server = server; } @Override protected void doDelete(HttpServletRequest arg0, HttpServletResponse response) throws ServletException, IOException { response.setStatus(202); response.flushBuffer(); server.notifyStop(); } } mobile-atlas-creator-1.9.14+dfsg1/src/test/java/mobac/tools/testtileserver/TestTileServer.java0000644000175000017500000001312712122526602032311 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.tools.testtileserver; import java.io.FileInputStream; import java.io.IOException; import java.net.HttpURLConnection; import java.net.SocketTimeoutException; import java.net.URL; import java.util.Properties; import javax.servlet.Servlet; import javax.swing.JOptionPane; import mobac.program.Logging; import mobac.tools.testtileserver.servlets.AbstractTileServlet; import mobac.tools.testtileserver.servlets.JpgTileGeneratorServlet; import mobac.tools.testtileserver.servlets.PngFileTileServlet; import mobac.tools.testtileserver.servlets.PngTileGeneratorServlet; import mobac.tools.testtileserver.servlets.ShutdownServlet; import org.apache.log4j.Level; import org.apache.log4j.Logger; import Acme.Serve.Serve; /** * *

* Provides a dummy HTTP server that returns a png for each request. *

* * @author r_x */ public class TestTileServer extends Serve { private static final Logger log = Logger.getLogger(TestTileServer.class); private final int port; public TestTileServer(int port) { this.port = port; // setting aliases, for an optional file servlet PathTreeDictionary aliases = new PathTreeDictionary(); setMappingTable(aliases); // setting properties for the server, and exchangable Acceptors Properties properties = new Properties(); properties.put("port", port); properties.put("z", "20"); // max number of created threads in a thread properties.put("keep-alive", Boolean.TRUE); properties.put("bind-address", "127.0.0.1"); // pool properties.setProperty(Acme.Serve.Serve.ARG_NOHUP, "nohup"); this.arguments = properties; Runtime.getRuntime().addShutdownHook(new ShutdownHook()); } public void start() { Thread t = new Thread() { @Override public void run() { TestTileServer.this.serve(); } }; t.setDaemon(true); t.start(); } public void stop() { try { notifyStop(); } catch (Exception e) { } destroyAllServlets(); } @Override public void log(String message) { log.debug(message); } @Override public void log(Exception e, String message) { log.error(message, e); } @Override public void log(String message, Throwable t) { log.error(message, t); } public void setTileServlet(AbstractTileServlet tileServlet) { Servlet oldServlet = getServlet("/"); if (oldServlet != null) unloadServlet(oldServlet); addServlet("/", tileServlet); } protected class ShutdownHook extends Thread { public void run() { TestTileServer.this.stop(); } } public int getPort() { return port; } public static void stopOtherTileServer(int port) { try { HttpURLConnection c = (HttpURLConnection) new URL("http://127.0.0.1:" + port + "/shutdown") .openConnection(); c.setConnectTimeout(100); c.setRequestMethod("DELETE"); c.connect(); if (c.getResponseCode() == 202) Thread.sleep(1000); c.disconnect(); } catch (SocketTimeoutException e) { // port is unused -> OK } catch (Exception e) { log.error("failed to stop other tile server instance on port " + port + ": " + e.getMessage()); } } public static void main(String[] args) { Logging.configureConsoleLogging(Level.DEBUG); try { Properties prop = new Properties(); FileInputStream fi = new FileInputStream("TestTileServer.properties"); prop.load(fi); fi.close(); System.getProperties().putAll(prop); } catch (IOException e) { JOptionPane.showMessageDialog(null, "Unable to load file DebugTileServer.properties: " + e.getMessage() + "\nUsing default values", "Error loading properties", JOptionPane.ERROR_MESSAGE); } int port = Integer.getInteger("TestHttpServer.port", 80); TestTileServer server = new TestTileServer(port); int errorRate = Integer.getInteger("TestHttpServer.errorRate", 0); boolean errorOnUrl = Boolean.getBoolean("TestHttpServer.errorOnSpecificUrls"); int delay = Integer.getInteger("TestHttpServer.delay", 0); boolean generatePngForEachRequest = Boolean.getBoolean("TestHttpServer.generatePNGperRequest"); server.addServlet("/shutdown", new ShutdownServlet(server)); AbstractTileServlet tileServlet; if (generatePngForEachRequest) { int pngCompression = Integer.getInteger("TestHttpServer.generatedPNGcompression", 1); tileServlet = new PngTileGeneratorServlet(pngCompression); } else { int imageNum = Integer.getInteger("TestHttpServer.staticImage", 0); tileServlet = new PngFileTileServlet(imageNum); } tileServlet.setErrorRate(errorRate); tileServlet.setErrorOnUrl(errorOnUrl); tileServlet.setDelay(delay); // server.setTileServlet(tileServlet); server.addServlet("/", new JpgTileGeneratorServlet(90)); stopOtherTileServer(port); server.serve(); } } mobile-atlas-creator-1.9.14+dfsg1/src/test/java/mobac/tools/MapSourceCapabilityDetector.java0000644000175000017500000002711212122526602031672 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.tools; import static mobac.tools.Cities.BERLIN; import java.io.IOException; import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.URL; import java.security.MessageDigest; import java.security.SecureRandom; import java.util.ArrayList; import java.util.List; import java.util.Map; import javax.xml.bind.JAXBException; import mobac.mapsources.DefaultMapSourcesManager; import mobac.mapsources.MapSourcesManager; import mobac.mapsources.mappacks.region_oceania.NzTopoMaps; import mobac.program.Logging; import mobac.program.ProgramInfo; import mobac.program.download.TileDownLoader; import mobac.program.interfaces.HttpMapSource; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSpace; import mobac.program.model.EastNorthCoordinate; import mobac.program.model.Settings; import mobac.program.model.TileImageType; import mobac.utilities.Utilities; import org.apache.log4j.Logger; public class MapSourceCapabilityDetector { public static final Logger log = Logger.getLogger(MapSourceCapabilityDetector.class); public static final SecureRandom RND = new SecureRandom(); public static final EastNorthCoordinate C_DEFAULT = BERLIN; /** * @param args */ public static void main(String[] args) { // *************************************************************************** Class mapSourceClass = NzTopoMaps.class; // *************************************************************************** Logging.configureLogging(); ProgramInfo.initialize(); try { Settings.load(); } catch (JAXBException e) { System.err.println(e.getMessage()); } DefaultMapSourcesManager.initialize(); MapSourcesManager.getInstance().getAllMapSources(); List result = testMapSource(mapSourceClass); MapSourceCapabilityGUI gui = new MapSourceCapabilityGUI(result); gui.setVisible(true); } public static List testMapSource(Class mapSourceClass) { return testMapSource(mapSourceClass, Cities.getTestCoordinate(mapSourceClass, C_DEFAULT)); } public static List testMapSource(Class mapSourceClass, EastNorthCoordinate coordinate) { if (coordinate == null) throw new NullPointerException("Coordinate not set for " + mapSourceClass.getSimpleName()); try { return testMapSource(mapSourceClass.newInstance(), coordinate); } catch (Exception e) { System.err.println("Error while testing map source: " + e.getMessage()); return null; } } public static List testMapSource(String mapSourceName, EastNorthCoordinate coordinate) { MapSource mapSource = MapSourcesManager.getInstance().getSourceByName(mapSourceName); if (!(mapSource instanceof HttpMapSource)) throw new RuntimeException("Not an HTTP map source: " + mapSource.getName()); return testMapSource((HttpMapSource) mapSource, coordinate); } public static List testMapSource(HttpMapSource mapSource, EastNorthCoordinate coordinate) { if (!(mapSource instanceof HttpMapSource)) throw new RuntimeException("Not an HTTP map source: " + mapSource.getName()); ArrayList result = new ArrayList(); for (int zoom = mapSource.getMinZoom(); zoom < mapSource.getMaxZoom(); zoom++) { MapSourceCapabilityDetector mstd = new MapSourceCapabilityDetector((HttpMapSource) mapSource, coordinate, zoom); mstd.testMapSource(); result.add(mstd); // log.trace(mstd); } return result; } private final HttpMapSource mapSource; private final EastNorthCoordinate coordinate; private final int zoom; private URL url; private HttpURLConnection c; private boolean eTagPresent = false; private boolean expirationTimePresent = false; private boolean lastModifiedTimePresent = false; private boolean ifNoneMatchSupported = false; private boolean ifModifiedSinceSupported = false; private String contentType = "?"; public MapSourceCapabilityDetector(Class mapSourceClass, EastNorthCoordinate coordinate, int zoom) throws InstantiationException, IllegalAccessException { this(mapSourceClass.newInstance(), coordinate, zoom); } public MapSourceCapabilityDetector(HttpMapSource mapSource, EastNorthCoordinate coordinate, int zoom) { this.mapSource = mapSource; if (mapSource == null) throw new NullPointerException("MapSource not set"); this.coordinate = coordinate; this.zoom = zoom; } public void testMapSource() { try { log.debug("Testing " + mapSource.toString()); MapSpace mapSpace = mapSource.getMapSpace(); int tilex = mapSpace.cLonToX(coordinate.lon, zoom) / mapSpace.getTileSize(); int tiley = mapSpace.cLatToY(coordinate.lat, zoom) / mapSpace.getTileSize(); c = mapSource.getTileUrlConnection(zoom, tilex, tiley); url = c.getURL(); log.trace("Sample url: " + c.getURL()); log.trace("Connecting..."); c.setReadTimeout(3000); c.setRequestProperty("User-agent", ProgramInfo.getUserAgent()); c.setRequestProperty("Accept", TileDownLoader.ACCEPT); c.connect(); log.debug("Connection established - response HTTP " + c.getResponseCode()); if (c.getResponseCode() != 200) return; // printHeaders(); byte[] content = Utilities.getInputBytes(c.getInputStream()); TileImageType detectedContentType = Utilities.getImageType(content); contentType = c.getContentType(); contentType = contentType.substring(6); if ("png".equals(contentType)) contentType = "png"; else if ("jpeg".equals(contentType)) contentType = "jpg"; else contentType = "unknown: " + c.getContentType(); if (contentType.equals(detectedContentType.getFileExt())) contentType += " (verified)"; else contentType += " (unverified)"; log.debug("Image format : " + contentType); String eTag = c.getHeaderField("ETag"); eTagPresent = (eTag != null); if (eTagPresent) { // log.debug("eTag : " + eTag); testIfNoneMatch(content); } // else log.debug("eTag : -"); // long date = c.getDate(); // if (date == 0) // log.debug("Date time : -"); // else // log.debug("Date time : " + new Date(date)); long exp = c.getExpiration(); expirationTimePresent = (c.getHeaderField("expires") != null) && (exp != 0); if (exp == 0) { // log.debug("Expiration time : -"); } else { // long diff = (exp - System.currentTimeMillis()) / 1000; // log.debug("Expiration time : " + new Date(exp) // + " => " // + Utilities.formatDurationSeconds(diff)); } long modified = c.getLastModified(); lastModifiedTimePresent = (c.getHeaderField("last-modified") != null) && (modified != 0); // if (modified == 0) // log.debug("Last modified time : not set"); // else // log.debug("Last modified time : " + new // Date(modified)); testIfModified(); } catch (Exception e) { e.printStackTrace(); } log.debug("\n"); } private void testIfNoneMatch(byte[] content) throws Exception { String eTag = c.getHeaderField("ETag"); MessageDigest md5 = MessageDigest.getInstance("MD5"); byte[] digest = md5.digest(content); String hexDigest = getHexString(digest); // log.debug("content MD5 : " + hexDigest); if (hexDigest.equals(eTag)) log.debug("eTag content : md5 hex string"); String quotedHexDigest = "\"" + hexDigest + "\""; if (quotedHexDigest.equals(eTag)) log.debug("eTag content : quoted md5 hex string"); HttpURLConnection c2 = (HttpURLConnection) url.openConnection(); c2.addRequestProperty("If-None-Match", eTag); c2.connect(); int code = c2.getResponseCode(); boolean supported = (code == 304); ifNoneMatchSupported = supported; // System.out.print("If-None-Match response: "); // log.debug(b2s(supported) + " - " + code + " (" + // c2.getResponseMessage() + ")"); c2.disconnect(); } private void testIfModified() throws IOException { HttpURLConnection c2 = (HttpURLConnection) url.openConnection(); c2.setIfModifiedSince(System.currentTimeMillis() + 1000); // future date c2.connect(); int code = c2.getResponseCode(); boolean supported = (code == 304); ifModifiedSinceSupported = supported; // System.out.print("If-Modified-Since : "); // log.debug(b2s(supported) + " - " + code + " (" + // c2.getResponseMessage() + ")"); } protected void printHeaders() { log.trace("\nHeaders:"); for (Map.Entry> entry : c.getHeaderFields().entrySet()) { String key = entry.getKey(); for (String elem : entry.getValue()) { if (key != null) log.debug(key + " = "); log.debug(elem); } } } @Override public String toString() { StringWriter sw = new StringWriter(); sw.append("Mapsource.........: " + mapSource.getName() + "\n"); sw.append("Current TileUpdate: " + mapSource.getTileUpdate() + "\n"); sw.append("If-None-Match.....: " + b2s(ifNoneMatchSupported) + "\n"); sw.append("ETag..............: " + b2s(eTagPresent) + "\n"); sw.append("If-Modified-Since.: " + b2s(ifModifiedSinceSupported) + "\n"); sw.append("LastModified......: " + b2s(lastModifiedTimePresent) + "\n"); sw.append("Expires...........: " + b2s(expirationTimePresent) + "\n"); return sw.toString(); } public int getZoom() { return zoom; } public boolean iseTagPresent() { return eTagPresent; } public boolean isExpirationTimePresent() { return expirationTimePresent; } public boolean isLastModifiedTimePresent() { return lastModifiedTimePresent; } public boolean isIfModifiedSinceSupported() { return ifModifiedSinceSupported; } public boolean isIfNoneMatchSupported() { return ifNoneMatchSupported; } public String getContentType() { return contentType; } private static String b2s(boolean b) { if (b) return "supported"; else return "-"; } static final byte[] HEX_CHAR_TABLE = { (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', (byte) '5', (byte) '6', (byte) '7', (byte) '8', (byte) '9', (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f' }; public static String getHexString(byte[] raw) throws UnsupportedEncodingException { byte[] hex = new byte[2 * raw.length]; int index = 0; for (byte b : raw) { int v = b & 0xFF; hex[index++] = HEX_CHAR_TABLE[v >>> 4]; hex[index++] = HEX_CHAR_TABLE[v & 0xF]; } return new String(hex, "ASCII"); } } mobile-atlas-creator-1.9.14+dfsg1/src/test/java/mobac/tools/Cities.java0000644000175000017500000001333512122526602025522 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package mobac.tools; import java.util.HashMap; import mobac.mapsources.mappacks.region_europe_east.FreemapSlovakia; import mobac.mapsources.mappacks.region_europe_east.FreemapSlovakiaCycling; import mobac.mapsources.mappacks.region_europe_east.FreemapSlovakiaHiking; import mobac.mapsources.mappacks.region_oceania.NzTopoMaps; import mobac.program.interfaces.MapSource; import mobac.program.model.EastNorthCoordinate; public class Cities { private static final HashMap, EastNorthCoordinate> TEST_COORDINATES; public static final EastNorthCoordinate NEY_YORK = new EastNorthCoordinate(40.75, -73.88); public static final EastNorthCoordinate BERLIN = new EastNorthCoordinate(52.50, 13.39); public static final EastNorthCoordinate MOSCOW = new EastNorthCoordinate(55.75, 37.63); public static final EastNorthCoordinate PRAHA = new EastNorthCoordinate(50.00, 14.41); public static final EastNorthCoordinate BANGALORE = new EastNorthCoordinate(12.95, 77.616667); public static final EastNorthCoordinate SHANGHAI = new EastNorthCoordinate(31.2333, 121.4666); public static final EastNorthCoordinate WARSZAWA = new EastNorthCoordinate(52.2166, 21.0333); public static final EastNorthCoordinate VIENNA = new EastNorthCoordinate(48.20, 16.37); public static final EastNorthCoordinate BRATISLAVA = new EastNorthCoordinate(48.154, 17.14); public static final EastNorthCoordinate SEOUL = new EastNorthCoordinate(37.55, 126.98); public static final EastNorthCoordinate SYDNEY = new EastNorthCoordinate(-33.8, 151.3); public static final EastNorthCoordinate PERTH = new EastNorthCoordinate(-31.9, 115.8); public static final EastNorthCoordinate BUDAPEST = new EastNorthCoordinate(47.47, 19.05); public static final EastNorthCoordinate MUNICH = new EastNorthCoordinate(48.13, 11.58); public static final EastNorthCoordinate OSLO = new EastNorthCoordinate(59.91, 10.75); public static final EastNorthCoordinate BERN = new EastNorthCoordinate(46.95, 7.45); public static final EastNorthCoordinate LONDON = new EastNorthCoordinate(51.51, -0.11); public static final EastNorthCoordinate INNSBRUCK = new EastNorthCoordinate(47.26, 11.39); public static final EastNorthCoordinate TOKYO = new EastNorthCoordinate(35.683889, 139.774444); public static final EastNorthCoordinate TAIPEI = new EastNorthCoordinate(25.033333, 121.633333); public static final EastNorthCoordinate WELLINGTON = new EastNorthCoordinate(-41.283333, 174.766667); static { TEST_COORDINATES = new HashMap, EastNorthCoordinate>(); // TEST_COORDINATES.put(GoogleMapMaker.class, Cities.BANGALORE); // TEST_COORDINATES.put(Cykloatlas.class, Cities.PRAHA); // TEST_COORDINATES.put(CykloatlasRelief.class, Cities.PRAHA); // TEST_COORDINATES.put(GoogleMapsChina.class, Cities.SHANGHAI); // TEST_COORDINATES.put(GoogleMapsKorea.class, Cities.SEOUL); // TEST_COORDINATES.put(MicrosoftMapsChina.class, Cities.SHANGHAI); // TEST_COORDINATES.put(MicrosoftVirtualEarth.class, Cities.NEY_YORK); // TEST_COORDINATES.put(MultimapCom.class, Cities.LONDON); // TEST_COORDINATES.put(MultimapOSUkCom.class, Cities.LONDON); // TEST_COORDINATES.put(DoCeluPL.class, Cities.WARSZAWA); // TEST_COORDINATES.put(YahooMapsJapan.class, TOKYO); // TEST_COORDINATES.put(YahooMapsTaiwan.class, TAIPEI); // TEST_COORDINATES.put(AustrianMap.class, Cities.VIENNA); TEST_COORDINATES.put(FreemapSlovakia.class, Cities.BRATISLAVA); TEST_COORDINATES.put(FreemapSlovakiaHiking.class, Cities.BRATISLAVA); TEST_COORDINATES.put(FreemapSlovakiaCycling.class, Cities.BRATISLAVA); // TEST_COORDINATES.put(NearMap.class, Cities.PERTH); // TEST_COORDINATES.put(HubermediaBavaria.class, Cities.MUNICH); // TEST_COORDINATES.put(OpenPisteMap.class, Cities.MUNICH); // TEST_COORDINATES.put(StatkartTopo2.class, Cities.OSLO); // TEST_COORDINATES.put(Turaterkep.class, Cities.BUDAPEST); // TEST_COORDINATES.put(Bergfex.class, Cities.INNSBRUCK); // TEST_COORDINATES.put(AeroChartsIFR.class, Cities.NEY_YORK); // TEST_COORDINATES.put(AeroChartsIFRH.class, Cities.NEY_YORK); // TEST_COORDINATES.put(AeroChartsVFR.class, Cities.NEY_YORK); // TEST_COORDINATES.put(MicrosoftOrdnanceSurveyExplorer.class, Cities.LONDON); // TEST_COORDINATES.put(YandexMap.class, Cities.MOSCOW); // TEST_COORDINATES.put(YandexSat.class, Cities.MOSCOW); TEST_COORDINATES.put(NzTopoMaps.class, Cities.WELLINGTON); } public static EastNorthCoordinate getTestCoordinate(MapSource mapSource, EastNorthCoordinate defaultCoordinate) { return getTestCoordinate(mapSource.getClass(), defaultCoordinate); } public static EastNorthCoordinate getTestCoordinate(Class mapSourceClass, EastNorthCoordinate defaultCoordinate) { EastNorthCoordinate coord = TEST_COORDINATES.get(mapSourceClass); if (coord != null) return coord; else return defaultCoordinate; } } mobile-atlas-creator-1.9.14+dfsg1/src/test/java/unittests/0000755000175000017500000000000012122526602023253 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/test/java/unittests/AbstractAtlasCreatorTestCase.java0000644000175000017500000001336312122526602031630 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package unittests; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.security.SecureRandom; import java.text.SimpleDateFormat; import java.util.Date; import javax.swing.UIManager; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; import junit.framework.TestCase; import junit.framework.TestResult; import mobac.exceptions.AtlasTestException; import mobac.program.AtlasThread; import mobac.program.Logging; import mobac.program.ProgramInfo; import mobac.program.atlascreators.AtlasCreator; import mobac.program.interfaces.AtlasInterface; import mobac.program.model.Atlas; import mobac.program.model.Profile; import mobac.program.model.TileImageType; import mobac.program.tilestore.TileStore; import mobac.tools.testtileserver.TestTileServer; import mobac.tools.testtileserver.servlets.JpgTileGeneratorServlet; import org.apache.log4j.Level; import org.apache.log4j.Logger; import unittests.helper.TestMapSourcesManager; /** * Base {@link TestCase} used for testing a specific {@link AtlasCreator} implementation and/or downloading of a Atlas. */ public abstract class AbstractAtlasCreatorTestCase extends TestCase { protected final Logger log; protected final File testAtlasDir; protected final SecureRandom rnd; protected static final TestTileServer TEST_TILE_SERVER; protected static final TestMapSourcesManager TEST_TILE_SERVER_MANAGER; static { Logging.configureConsoleLogging(Level.TRACE,Logging.ADVANCED_LAYOUT); ProgramInfo.initialize(); //Logger.getLogger("mobac").setLevel(Level.INFO); TEST_TILE_SERVER = new TestTileServer(18888); // TEST_TILE_SERVER.setTileServlet(new PngFileTileServlet(0)); TEST_TILE_SERVER.setTileServlet(new JpgTileGeneratorServlet(90)); TEST_TILE_SERVER.start(); TEST_TILE_SERVER_MANAGER = new TestMapSourcesManager(TEST_TILE_SERVER.getPort(), TileImageType.JPG); } public AbstractAtlasCreatorTestCase() { super(); log = Logger.getLogger(this.getClass()); log.setLevel(Level.DEBUG); try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception e) { } TileStore.initialize(); testAtlasDir = new File("target/test-atlases"); rnd = new SecureRandom(); } @Override protected void runTest() throws Throwable { log.info("running test \"" + getName() + "\""); super.runTest(); } protected void createAtlas(String profileName, Class atlasCreatorClass) throws InstantiationException, IllegalAccessException, JAXBException, AtlasTestException, InterruptedException, IOException { AtlasCreator atlasCreator = atlasCreatorClass.newInstance(); createAtlas(profileName, atlasCreator); } protected void createAtlas(String profileName, AtlasCreator atlasCreator) throws JAXBException, AtlasTestException, InterruptedException, IOException { String profileFile = "profiles/" + Profile.getProfileFileName(profileName); InputStream in = ClassLoader.getSystemResourceAsStream(profileFile); assertNotNull(in); AtlasInterface atlas = loadAtlas(in); createAtlas(atlas, atlasCreator); } protected AtlasInterface loadAtlas(String profileName) throws JAXBException { String profileFile = "profiles/" + Profile.getProfileFileName(profileName); InputStream in = ClassLoader.getSystemResourceAsStream(profileFile); assertNotNull(in); return loadAtlas(in); } protected AtlasInterface loadAtlas(InputStream in) throws JAXBException { JAXBContext context = JAXBContext.newInstance(Atlas.class); Unmarshaller um = context.createUnmarshaller(); return (AtlasInterface) um.unmarshal(in); } /** * * @param atlas * @param atlasCreator * @return directory in which the atlas has been created * @throws AtlasTestException * @throws InterruptedException * @throws IOException */ protected File createAtlas(AtlasInterface atlas, AtlasCreator atlasCreator) throws AtlasTestException, InterruptedException, IOException { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd_HHmmss_SSSS"); File customAtlasDir = new File(testAtlasDir, atlasCreator.getClass().getSimpleName() + "_" + atlas.getName() + "_" + sdf.format(new Date())); createAtlas(atlas, atlasCreator, customAtlasDir); return customAtlasDir; } protected void createAtlas(AtlasInterface atlas, AtlasCreator atlasCreator, File customAtlasDir) throws AtlasTestException, InterruptedException, IOException { log.debug("Creating atlas " + atlas.getName() + " using " + atlasCreator.getClass().getSimpleName() + " to \"" + customAtlasDir + "\""); AtlasThread atlasThread = new AtlasThread(atlas, atlasCreator); atlasThread.setCustomAtlasDir(customAtlasDir); atlasThread.start(); atlasThread.join(); } @Override public TestResult run() { TestResult result = super.run(); return result; } } mobile-atlas-creator-1.9.14+dfsg1/src/test/java/unittests/SQLiteTestCase.java0000644000175000017500000000225612122526602026720 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package unittests; import mobac.program.atlascreators.RMapsSQLite; public class SQLiteTestCase extends AbstractAtlasCreatorTestCase { public SQLiteTestCase() { super(); } public void testRMaps() throws Exception { log.info("Starting test testRMaps"); createAtlas("HamburgPark", RMapsSQLite.class); } } mobile-atlas-creator-1.9.14+dfsg1/src/test/java/unittests/methods/0000755000175000017500000000000012122526602024716 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/test/java/unittests/methods/UtilitiesTests.java0000644000175000017500000000315012122526602030556 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package unittests.methods; import junit.framework.TestCase; import junit.textui.TestRunner; import mobac.utilities.Utilities; public class UtilitiesTests extends TestCase { public void testParseSVNRevision() { assertEquals(4168, Utilities.parseSVNRevision("4168")); assertEquals(4168, Utilities.parseSVNRevision("4123:4168")); assertEquals(4168, Utilities.parseSVNRevision("4168M")); assertEquals(4168, Utilities.parseSVNRevision("4212:4168MS")); assertEquals(4168, Utilities.parseSVNRevision("$Revision: 4168$")); assertEquals(4168, Utilities.parseSVNRevision("$Rev: 4212:4168MS$")); assertEquals(-1, Utilities.parseSVNRevision("exported")); } public static void main(String[] args) { TestRunner.run(UtilitiesTests.class); } } mobile-atlas-creator-1.9.14+dfsg1/src/test/java/unittests/methods/MyMathTests.java0000644000175000017500000000421612122526602030006 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package unittests.methods; import junit.framework.TestCase; import junit.textui.TestRunner; import mobac.utilities.MyMath; public class MyMathTests extends TestCase { public void testRoundDownToNearest() { assertEquals(0, MyMath.roundDownToNearest(0, 10)); assertEquals(0, MyMath.roundDownToNearest(1, 10)); assertEquals(0, MyMath.roundDownToNearest(9, 10)); assertEquals(10, MyMath.roundDownToNearest(10, 10)); assertEquals(10, MyMath.roundDownToNearest(11, 10)); assertEquals(12340, MyMath.roundDownToNearest(12345, 10)); assertEquals(1024, MyMath.roundDownToNearest(1025, 16)); assertEquals(1024, MyMath.roundDownToNearest(1024, 256)); assertEquals(1024, MyMath.roundDownToNearest(1025, 256)); } public void testRoundUpToNearest() { assertEquals(0, MyMath.roundUpToNearest(0, 10)); assertEquals(10, MyMath.roundUpToNearest(1, 10)); assertEquals(10, MyMath.roundUpToNearest(9, 10)); assertEquals(20, MyMath.roundUpToNearest(11, 10)); assertEquals(12350, MyMath.roundUpToNearest(12345, 10)); assertEquals(1040, MyMath.roundUpToNearest(1025, 16)); assertEquals(1024, MyMath.roundUpToNearest(1024, 256)); assertEquals(1280, MyMath.roundUpToNearest(1025, 256)); } public static void main(String[] args) { TestRunner.run(MyMathTests.class); } } mobile-atlas-creator-1.9.14+dfsg1/src/test/java/unittests/helper/0000755000175000017500000000000012122526602024532 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/test/java/unittests/helper/TestMapSourcesManager.java0000644000175000017500000000460112122526602031612 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package unittests.helper; import java.util.Vector; import mobac.mapsources.MapSourcesManager; import mobac.mapsources.impl.LocalhostTestSource; import mobac.program.interfaces.MapSource; import mobac.program.model.TileImageType; public class TestMapSourcesManager extends MapSourcesManager { private final MapSource theMapSource; public TestMapSourcesManager(int port, TileImageType tileType) { super(); theMapSource = new LocalhostTestSource("Localhost test", port, tileType); install(); } public TestMapSourcesManager(MapSource mapSource) { super(); theMapSource = mapSource; install(); } public void install() { INSTANCE = this; } @Override public Vector getAllMapSources() { Vector v = new Vector(1); v.add(theMapSource); return v; } @Override public Vector getAllLayerMapSources() { return getAllMapSources(); } @Override public MapSource getDefaultMapSource() { return theMapSource; } @Override public Vector getEnabledOrderedMapSources() { return getAllMapSources(); } @Override public Vector getDisabledMapSources() { return new Vector(); } @Override public MapSource getSourceByName(String name) { return theMapSource; } @Override public void addMapSource(MapSource mapSource) { throw new RuntimeException("not implemented"); } @Override public Vector getAllAvailableMapSources() { return getAllMapSources(); } } mobile-atlas-creator-1.9.14+dfsg1/src/test/java/unittests/helper/DummyTileStore.java0000644000175000017500000000546012122526602030330 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package unittests.helper; import java.awt.Point; import java.awt.image.BufferedImage; import java.io.IOException; import mobac.program.interfaces.MapSource; import mobac.program.tilestore.TileStore; import mobac.program.tilestore.TileStoreEntry; import mobac.program.tilestore.TileStoreInfo; public class DummyTileStore extends TileStore { public static void initialize() { INSTANCE = new DummyTileStore(); } public DummyTileStore() { } @Override public void clearStore(String storeName) { } @Override public void closeAll() { } @Override public boolean contains(int x, int y, int zoom, MapSource mapSource) { return false; } @Override public TileStoreEntry createNewEntry(int x, int y, int zoom, byte[] data, long timeLastModified, long timeExpires, String eTag) { return null; } @Override public TileStoreEntry createNewEmptyEntry(int x, int y, int zoom) { return null; } @Override public String[] getAllStoreNames() { return null; } @Override public BufferedImage getCacheCoverage(MapSource mapSource, int zoom, Point tileNumMin, Point tileNumMax) throws InterruptedException { return null; } @Override public TileStoreInfo getStoreInfo(String mapSourceName) throws InterruptedException { return null; } @Override public TileStoreEntry getTile(int x, int y, int zoom, MapSource mapSource) { return null; } @Override public void prepareTileStore(MapSource mapSource) { } @Override public void putTile(TileStoreEntry tile, MapSource mapSource) { } @Override public void putTileData(byte[] tileData, int x, int y, int zoom, MapSource mapSource) throws IOException { } @Override public void putTileData(byte[] tileData, int x, int y, int zoom, MapSource mapSource, long timeLastModified, long timeExpires, String eTag) throws IOException { } @Override public boolean storeExists(MapSource mapSource) { return false; } } mobile-atlas-creator-1.9.14+dfsg1/src/test/java/unittests/helper/DummyAtlasCreator.java0000644000175000017500000000273012122526602030777 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package unittests.helper; import mobac.exceptions.MapCreationException; import mobac.program.atlascreators.AtlasCreator; import mobac.program.interfaces.MapSource; /** * A simple {@link AtlasCreator} implementation that does nothing. Can be used * in case only tile downloading and saving in the tile store is the test * target. */ public class DummyAtlasCreator extends AtlasCreator { public DummyAtlasCreator() { } @Override public void createMap() throws MapCreationException, InterruptedException { } @Override public boolean testMapSource(MapSource mapSource) { return true; } } mobile-atlas-creator-1.9.14+dfsg1/src/test/java/unittests/AtlasDownloadTestCase.java0000644000175000017500000000275712122526602030321 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package unittests; import java.io.File; import mobac.mapsources.DefaultMapSourcesManager; import mobac.program.atlascreators.AlpineQuestMap; import mobac.program.interfaces.AtlasInterface; public class AtlasDownloadTestCase extends AbstractAtlasCreatorTestCase { public AtlasDownloadTestCase() { super(); } public void testAtlasCreation() throws Exception { AtlasInterface atlas; // atlas = loadAtlas("Germany10-12"); // atlas = loadAtlas("HamburgPark"); DefaultMapSourcesManager.initialize(); atlas = loadAtlas("Munich6-16"); File dir = createAtlas(atlas, new AlpineQuestMap()); assertNotNull(dir); } } mobile-atlas-creator-1.9.14+dfsg1/src/test/java/unittests/CordinateTestCase.java0000644000175000017500000000623712122526602027472 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package unittests; import junit.framework.TestCase; import mobac.utilities.Utilities; import mobac.utilities.geo.CoordinateDm2Format; import mobac.utilities.geo.CoordinateDms2Format; public class CordinateTestCase extends TestCase { public CordinateTestCase() { super(); } public void testCoordinateDm2Format() throws Exception { CoordinateDm2Format cf = new CoordinateDm2Format(Utilities.DFS_ENG); assertEquals("03° 30.00'", cf.format(3.5d)); assertEquals("-03° 30.00'", cf.format(-3.5d)); assertEquals("-20° 06.00'", cf.format(-20.1d)); assertEquals("20° 06.00'", cf.format(20.1d)); assertEquals("-13° 54.00'", cf.format(-13.9d)); assertEquals("13° 54.00'", cf.format(13.9d)); assertEquals("00° 06.00'", cf.format(0.1d)); assertEquals("-00° 06.00'", cf.format(-0.1d)); assertEquals(-4.25, cf.parse("-04° 15.0'")); assertEquals(+4.25, cf.parse("+04° 15.0'")); assertEquals(-20.1, cf.parse("-20° 6'")); assertEquals(+20.1, cf.parse("+20° 6'")); assertEquals(-13.9, cf.parse("-13° 54'")); assertEquals(+13.9, cf.parse("+13° 54'")); assertEquals(-0.1, cf.parse("-00° 06'")); assertEquals(+0.1, cf.parse("+00° 06'")); } public void testCoordinateDms2Format() throws Exception { CoordinateDms2Format cf = new CoordinateDms2Format(Utilities.DFS_ENG); assertEquals("03° 32' 59.99\"", cf.format(3.55d)); assertEquals("-03° 32' 59.99\"", cf.format(-3.55d)); assertEquals("-20° 06' 35.99\"", cf.format(-20.11d)); assertEquals("20° 06' 35.99\"", cf.format(20.11d)); assertEquals("-13° 59' 24.00\"", cf.format(-13.99d)); assertEquals("13° 59' 24.00\"", cf.format(13.99d)); assertEquals("00° 06' 00.00\"", cf.format(0.1d)); assertEquals("-00° 06' 00.00\"", cf.format(-0.1d)); assertEquals(-3.55, cf.parse("-03° 32' 60.00\"")); assertEquals(+3.55, cf.parse("+03° 32' 60.00\"")); assertEquals(-2011, (int) (cf.parse("-20° 6' 36\"").doubleValue() * 100d)); assertEquals(+2011, (int) (cf.parse("+20° 6' 36\"").doubleValue() * 100d)); assertEquals(-1390, (int) (cf.parse("-13° 54' 24\"").doubleValue() * 100)); assertEquals(+1390, (int) (cf.parse("+13° 54' 24\"").doubleValue() * 100)); assertEquals(-0.1, cf.parse("-00° 06' 0\"")); assertEquals(+0.1, cf.parse("+00° 06' 0\"")); } } mobile-atlas-creator-1.9.14+dfsg1/src/test/java/unittests/KMZTestCase.java0000644000175000017500000000276612122526602026226 0ustar paulliupaulliu/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ******************************************************************************/ package unittests; import java.io.File; import mobac.program.atlascreators.GoogleEarthOverlay; import mobac.program.interfaces.AtlasInterface; public class KMZTestCase extends AbstractAtlasCreatorTestCase { public KMZTestCase() { super(); } public void testGoogleEarchOverlay() throws Exception { AtlasInterface atlas = loadAtlas("HamburgPark"); File dir = createAtlas(atlas, new GoogleEarthOverlay()); assertNotNull(dir); } // public void testGarminCustom() throws Exception { // AtlasInterface atlas = loadAtlas("HamburgPark"); // File dir = createAtlas(atlas, new GarminCustom()); // assertNotNull(dir); // } } mobile-atlas-creator-1.9.14+dfsg1/src/test/resources/0000755000175000017500000000000012134265562022312 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/test/resources/mobac/0000755000175000017500000000000012122526602023363 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/test/resources/mobac/tools/0000755000175000017500000000000012122526602024523 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/test/resources/mobac/tools/testtileserver/0000755000175000017500000000000012122526602027607 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/test/resources/mobac/tools/testtileserver/servlets/0000755000175000017500000000000012122526602031456 5ustar paulliupaulliumobile-atlas-creator-1.9.14+dfsg1/src/test/resources/mobac/tools/testtileserver/servlets/images/0000755000175000017500000000000012122526602032723 5ustar paulliupaulliu././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/test/resources/mobac/tools/testtileserver/servlets/images/cross.pngmobile-atlas-creator-1.9.14+dfsg1/src/test/resources/mobac/tools/testtileserver/servlets/images/cros0000644000175000017500000000502612122526602033617 0ustar paulliupaulliuPNG  IHDRkXTgAMA aPLTEw3$ pHYsktEXtSoftwarePaint.NET v3.5.2iCIDATx^nJQ&b\$q){)aa[2Pg|] \e]x~^we.kڿV `` o_Zs}XoXFޟXD?g`}w՟.S3 <xL,ԟV๿0K `J"2t dTT`Q0@`L & ޟ%CW~AO>L-Po 08PoV/T/R/P/N/L_ 0@K` ~90m A5Cht/ޯ\@ЯZ@үX@ԯV@oT@oR@oP@oN@oL@oJ@oH@oF@Љ m @~p}@ T(`; =B~_, @w |$~E@pA`~Tp| ~$D p hWD?Qҏp@ T?A0 IF`? $<3T~*B BB?@$(|fN@?I @ *(? @ p2H? !@8 ^"Bb;&.+/-~Dw;%9 |1@0'B u  p^"R@ @za/W 0bj!~0Oh it~$@s~@` DM?^ h,@c8~ڏ`~&G A`~"G @D.@{ p d*@{ F?M% wp`p]\~G~@LY *op \-v>f^V~Fu6U&5z>j^Z~Je:E*% c7 Fo( M@0V` x cWF _h,0vQ `@ u9UYK< Li2\I"l)| 00gI 0k@` iar{8 0 H-pXKJ!g ^xX& 0z^ϗ\=8Xn(-[qt w0ѻIENDB`././@LongLink0000000000000000000000000000015100000000000011562 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/test/resources/mobac/tools/testtileserver/servlets/images/tile.pngmobile-atlas-creator-1.9.14+dfsg1/src/test/resources/mobac/tools/testtileserver/servlets/images/tile0000644000175000017500000023557512122526602033624 0ustar paulliupaulliuPNG  IHDR?1gAMA a pHYs(JtEXtSoftwarePaint.NET v3.5.1N8IDATx^}xTi6AwwwN@wwwwq']ٽ_| ,+w#dO[~Lkށ;{h>X?[_=7_WՁ;_??ӟ~/_|ijjj|||dddpp999o߾ /PPPhhhTTTBBBJJJfff~~~QQQYYYuuu}}}sss[[[gggOO ;?GeF|#Ϡtooooll%UKȌM 6u0Sұ44DJxb&_bbNus)DZ\D\፥@Hddx%zU& +**jjj Zx ^3Bُ?̣ PlxUޏrE SWWT  +###9991.95-=#++("GRÚ_\OD晇gr?T;@ {|NGgiy=>8P&34:nHc 'i^~sGLgp\brzF:ERSS RQ%%%ZZZπjio?D lh??dAKI7:J%%%!#&6.)9%#;+(FI+K8%>ȼ/wD yGA^;"1QI\wI=&9q)\?&cbN~I~ Dzo%$&#B(>>P ~OamÈ0r:Az ,%ȸdhπHWPG ;W+'oS[wckWkg_GP7V~e,T]zC/){gm9vAB;v`&^":k'.]bLc[W$ʲ%ae CZ-#'d;17544C!- ˌ`$Y}r,&Ldb2ee-VrEz*FNzvrZn^)iRqp9Ԉ"E3) =Ci"(7dOhfe$%DFńGD9xP4>'K g,;"&!aŬ/AKό0:ܸ1~gWd9rP {Dd Q`"8!<" u_hɾQ4/#=81%L>0 !s D (s Q26Ew G1.pEl?B ,gblfJ͂B sf'¶ǁ g/F#ƺSuq8y+~ > > ^I^)ֽ,dXǵWer+ +AUL1 A5\T0~2"ayΣr)」}A AS<6 O{Wx x9BeF{,#Ts}ӑ*@2;DUߎ_쵐GkoX r/ bɜ^->!Լ#^vb/1rCl)HeeY1ce]Li:4[:! ÚӢzrCjêsN-f ;oox嗖fQ)a`; !p7w B@0\0clvX҂T2G<8P{'$@=r(YHa ((YRZ J@cB"}Bbb;oS.Vc zOWAd9 & $а !Vxm67157-+?⒲29 H*p$x" `" A1aJ1V#€#G'<))qQv.^.!Ѡ׷BwQWIp Vsy mv;ntegJ:^Oĭ<5:C 쿫:t\tMwM}͎ p8q8%pRaUgsNM11 MN؏Xq_&#ӡ{M>K29#hyM񡊧ț5i^t~E "& bFiD:eL: b~x cϬoI];v[Vn[mcI!;2ZNa Yy ^p ),*~ $=aJc,]7<} 8h?PAM@psB چ8z9ʿ4vtMH{ozW|97TnK*yXk9ze~_7wKWDG|PlKP{@9C ߗZB^O+=Tt}\S0H6=5A9^1n9q57ع)g0]'%%ۊ5ykN+MK ISFӦ3ffg6ܶ>%d_᧶nX56"g>^~/ŵ-bS+٩owH Gq 0@-(a fh+i5tէ+᧫>:.D𙡮5a11㏈qUҵ}(+dj_P+#{3%sM6_xYseu4>0ffjblgGokh컰EI Shp]rzksքք3Dn ۚ|֚˶n9l}ky(TnK6n33&H s[Z ԳKlowBKn%<_oo91y<oxSF%0!!=/&9;"!#$&5.9++})w*1z D cCѿA_̇GV1 =PG$.)i6.b V7q ~[XTb,((j-y[/UV_pZci͍ xE_hĺGeff($]YcqUKym[im[IM[qu[@bm)Mw]spƎmG:kO>bG9gK9gqz-}\Kx|uU'6{v;v[s6䳶$n[@  ٭eDQqeMOs.dA- ҅ >௡_@AQ_$݌ٸ?1r~>y -;ȃ$%ZW7vkJPs x?-`]T?8 f]~E\>4 6G!9o###ljrމzޑzގlyIoo*^qˍ˴:?$u!p@lw=|i%nuHȃ9!xXu ;7^vAf2v:V~~o Ke ,=J2G"b{t9O>dS>=T |@Vѵ@3칂K2n(8xGf$eEx%jޔ9dP$9kq!G~CĜ~G㩪ãm=Cq]ȇl˜.sDy2+ԚrޑêK>nPx]I<.o/9΂`p($:5,6-<>#2!'NF-f=5ׄ#ڐ8c6DŽ]R+z趟nϸ&>6v$THY^r}UwnD7yw/םF຀s϶g-3'O2qвi 2!GE|?t^g|-z>MJ؋hyhXE''d'dǤG$G&g+*Z   BpK `SBp$ 2C`Kfb>9J~>88fdQ RxO/Ċk:z})s5/'cfgHr?3[˫57 Gt' )C>g3hҮ!FCՇ׏C VAO _zL%$^"]/E/ek\|خ/y.Ň D^//``vc_Xsu=;[oɩ7E4<̂R1<4.+-<$6-})ĸ`ׁf#W%-Gp!؀/CC@VFu =h?|CL;y4B?%HKLKJIJJɌ{oPzjU,|"UxGdHo)tX@Fho}hyOW]VrV{xn'(i\DBQIK*A  7`Ei7^gd4p+u'l~'d<,*Р?h?0~(c !/04@@Rrjl|rxt_pGmC9ۓ sQҝ:QK}r[>. >jP"4YzH54Ҽah~@dnysTU2Z/ҴI2H "&A+tAߡ 'ؿ͋\rыB>\WvZw~Ol/rzlW^XZ>.5?}yum#yh3r߀8+@Sċ &+a?!/|pvGls?#ᓖ6(,7_^4 ᄅW} 'UWj{s{HjqY$"vܳ'aM }`B8aJ.ar$&WCHWC_%9 4+ CH&cQ+\׼_w_tygE]){*@Q/#%Z@Gt@6OQ3h!E_"C%^(L!a1Q1II)1QqoCb=BMl|uīE'eRJs!^s[繚ۜ5#7qd=jz̄84 NSXp.vGS z=X"2 `  R`7@'WB/ o63"f~z KQGP0pyxX:x1qQ7t0v4240V7QzRqBgi4"fsCCegj"Zr&ͽ3LK-fz̔ s֓\6P|ϙO1;'~<[gdlxv5T7dJ\y݇zZ#hIˍ(2. ;Go9 wT:|"r1‘+/n{,knyzqV󑚟1t+ } {@1&KH!J@eHQ3a70>̀E[bOE }u"[!098-4%8C9I8J[9=ozܜI+S֋9|~QKi/,iMo̬+=n_0/ EM1d\( 0!BwGTr3|3;xU>6H1ϐQuaqU5~H膇[ <"h@@>7|-+B+Ghk=O e w3Mؠ.:;d "MIW0#?#EdBF? lkW;.H/>r!y{Hj!WXqZa9|7Ed-]#S ܭmhojkh(n\K9ez~Sk︝{&\-54{?wu}R]bXͯUdAqAc1Gq;T\ |4-/?bq [+(% gzZJ(Ȭ -L _hYɠ^{u#z[+y| kda DhA!/}36M/T`[ vrhL )TՇ]!>v&v^"Jg/;&ƶSSCuK.qI2s.8"+w$m^[B+=>%?3.u"SSx%睷"4'L+DpX|ywn A]4"L|'%0"X1~ b&;t)7vvH".&ԻIlr7ww0I`~'v[Z^+sjӊ brlC2%>ӍMc[A" ?o3bΈ !#PMu6Д($EC;\ z>Ʌ]D{#Ə>|`듉qCk?NU8 =*?r.fi)YEIEIij T>q}Ίxʒp z3m;LKx#䲬F0=# 74^6+,A߯q ˞&QJO;.I;H߂P%PGxNV/Ku/z׫BVj*;뻪[z:J껓߷:;K%{Y%O#A0Y&?0cx[Da\VH %IѠ(& :٩2#hʄB,K$%siu{k\mYs]rbi_NDzeYoMK+,z7~xLBSA(S#2_cO⏛uD6Yѭ$]{XDGXcpqmOLvsxk4T(ὲHRrH3/K̫o6r3":q!KT E9a5M*@?Q/  Z; *n}Mgm~6k-° Jyն\o:׀_;>>3,5A0בgk/dcE: s.,I$뀬򢪶1vwhTmk ʖº>Ϸ%enGSQ0LB({BA遼PdPf=2KF!? I|]7߱[t>lg -d^YW\;<2Ô?~vezmLml3&q-QFaA NlMލ=F]@( iLL,,GBaYS2&s.{A8tЪ`.N2ćO#U`rrjck"2+x'6׶C/b0}T}va15Pty|;164Qcs!j? A;:l?h?@op: 'Mz-p-0ms򱑰CGs@oDk(>i5WM9N讹j~Is'}hCDGXK0%umuAզ>I]C`~`Fj^0F~Ee2gu#}8r0zȗ_nnn< :Ϥi)iAq2obڊ%ve,ݣar%4Aֻ6uHGu)O)S3T=mMA†;<ʓ|S$y%KEIWx+d_WL@`|bBj1V BE\`Lzҫ]`0~Ptw;;;#/$A@ #..He#R.׿'eSPQ+"G:䣰DDz܀zˆzҔzZ(gl(g$n'Yg9hw;,씗d/"1%F&F; j#:#"ABM7ft-^2磔˅V/J_,yѬmy ˟<O@ii>M<{G}V@S"~T>Y")yǢ׏|`@DVY[\_Apz]I}$fz~'C Ry Jz<}?[<;J w?x` #/*x.󏌊 uRϧJ|"R:^.~م + _\zR^cd;i?)*dn;YG9g*+םrd{Azqh<ac>7w 7v'%5~i_.j_!P!Xyۨbr {)T~,COE mX~C iӶJ,vL%~sr>*EKD h6;6%Y2wd!ԧyq MCAvVמּ 7щ 9] -Eu=m>b )TL_čШ* s ~bB W8kV9@;*8>xP~ |р "?:n^aFV^L^S"m{~kij,nUu]Yec`FЖVKr`i'8N' ²=v$n~<9.zr\buF&V׻(?>%F6%V˸hI[w:Ѭ"2<`,X"|U4>Tԣ)˺YD{^6*_+]{*&TB`_E/7Hd5| M1ݗNVHϐ?8:;<9< fc%`?0bbȜ+FQsΧB ހ᷵urrbh>;#܃=^([]vI t7dA؄Ѫ&ψ\q_\~tY٧ O'ҏi? |(<0Wy{U|>o^QI0 ,)?Y.Uj^765,ZŸ a&;6W<H7L7ʼo{IXWjӛ[JカP1Pi6d٫;Og+r}\:Hr5B:hVon-~J$J!I`qɻBǡC.[2茮!F.D)cGjH3t1F@ <0o n  ?GP2 KF?=ڛigf&R!48:ЙԚUh{O)sW8`Oʊpʆk?ۉxօs염ỚoS:Iv kC3C*}K݊ S^-UX~ a&,ٰ &Bx]*r- 17~v1N noAu7̫6ȗR@Teh9<,Fʕ*mZ[Q9 '4º٤T)W6/iӗI,M`d4&&! feblFG͢Qt p! A* m1p T]=...3KM`%3#+:-pS_]+X[PR]76Mم5qƞ6uf;mm(Dv!r(bg'ăLc*{Z" mzrH4$U_m?7/׏p|9peF*m-{C;,ݒ^"[XY@9~?G``s,CxO(<8BE xZЛkO\:4_j8oZ{HfJ*6`5bUl \ JH-./U)Y&Q.Y)U%];[CMvbQǮ-#;{74L|DO!i\'aJ-Ꞻ!m`]h[x$>`ڑx(y`%FEbtB!"0C #[L|dL\)m'T믫`wfqzx\sU'c^i?B"L] N̚'{Ecb)_,4}5A8Hsȏ؟-T0E"B1)" S֗PEJ^pE/_(]Dz|2ՋKWg{U.Q;Orl ɖxHqHqJq͖㐮c[ЪәPW8;92H# k׋i?k\D`LbŲeeV,:W/W1109<#۸|~ 3%{%f4 an<1XF@^ B%%6!tl?jpiM QїUؿDd4`Rӝ"zhG?|ڏA3I咞 p hH0$iA-1U%IW"W3_f4PZD-ddGJ),-S&].]) S&SDUD`CzO\Pe_'>Cwd 4=ƅ)Ϝ> F=o*V@!V.^:[dU2a['F?:Oah(ٗ{aAuռgƆBž.zBz¤KHx}-rcm=;E(E[[WpRuY1\p:cz}Zеx5|-~3~EW>_%ICB24ddc~Sھg,..f_ ԾTRĪ(U@ϗ]XPn,fѩuT)$2sW.#W![Gi`r̖6Wnܡk*nڟR;>0ԧ_?Vw6O9)~+O#Sn:J.Rˤߟ1(mI*ql3417Nw_lybF"0pxT`DMV1r[tZ[&`.`m"dx_qO5TC"g3rަf&eai?ۺ<tbqwё'i?9OkQ1d8ʍ[w'y Cha6 <NJX #< dRH7/VMDŽ*QTr"y 2 Tt=uճ5PȂW#\|SiZmM/{ ǺFN}O,y868|§?u|W9mJ']\h|U_~Fq; Ŧѿ*|Í-,}a `@1Z2c;?}yh}9d!n5/~{zsw5yJuy{cMh 1ˀD>;CRr,XN/.FEH|Iɤ;)i$tfAs@ɏɠO c_~ YOc)_ ~P+Zd-lBņe*)4r5Rd4`"Hk5QAA r9'׳)4)47 ;MRڧj'V gw'EWtNL}OO]g̑kN]+7)߰(5o-jƊ􋱛:w҃*2ebfdh0 !f`lb[~xYIp[_1pz~=B/5^.vv/ϐjb5zݹ0%W| R^jø΂qF04O0nc /t6G?w+]h" .Pbx󁌧=odJg$n *?~fg 62@? | QTdwM13)G3.,g=Xa:CFaOx ~FH?QncYN`jB8)#>dએi?E HN\\EL+7s)6aOo*"&PhTTPl`WjdSjfSjaSjť vM~ܚڶiW / G-C_rƮ?8[X 7q}yS3=fx-'5N>:2B܃#+MHMHGp&DmBhm^v?:?:?t2iM`>73'5Rsɖ=2uN-KsgSK7'h?=E0Բ*2̹,u`}@Y1BHnn&n%o'1Om ysIO/"?/Ʋ L/+)=Mk)RH`&~rNҷbb& - 빔j9ؕ[*T$ltQXٸY~~ 7OKhX:}𯎹|n}d6|+YdiZpvGF!!Q} E-Fch dh4:̨M*k@ l t4@[?034142RzsԎ3zt󹒚oP(ķɀzD~p_V\RZX\ZPTS/*?:mViI@WwO[Gx&3wהb.qg?i?`¥0Z·-l?h?~tb~|ғҳ$"кS7a]:Ah.v9Xt ~:`91ퟭ&\FU Em; ڶj_o>[ځK']:hz]UzQ f^^}FþEcսm {Y BQhg֥{#P (|hph$VV /B5/`)bxPςn6461TT}*t薓~rODU!"*2_`!fǾr’”w~Fz!zie4@ۇk*?s,Xy1gFi?ۍٷ8V$)gl?M'=+' bE9hlJ|~2Q$0՟-u^Un~댡}'iuP@:j]lHA:hղM~^]ʱV٣)Jbaiq5ß1 ;@ Emy4h[?>*{)ѡAX${`Cc\x e@_#b@$BcuoJ-@q}ѡ( v d~t LURH o?4C2?ަG$d|`FR?,0`w%1۹W_rJ4/v{60ۏi?Ab>h?fKH)gzU5Wf6Vň>KS$1ƒ3~\iOA,:+R(4i 6J.NɈ9w}iP浪wHf'f'V>nɨҮOƄCv[t<GVn#+Spgѣ? sr_ " p9OwChPPz OúQe~"#Y6%06f[Y P{GcseM=Qu~!y{^:qCohvλ| ?Et•$5 mSm5q^uzSW6}]faCfQcVQSBN;^+<0z)Jj /v¼{o's {iĻ{D,\"0l@1~0d9+ŠzT-d-4L> )sM`A) -8L>6e0vܦ]CuyDxPX9rߏIE tf޳ʰgv/V/ffU.-G܋[?Y=cc;P2!1ײ{e>\ XgwBCo;N/av+}e[UCGK;7ۄf4KAA1P4~^G yOP}KKKx䏓(*$yGHoHVf6CH}BOUIyՖ_*ju`}; A*olS55255srn%~ X2_/+bА\ ] U1՟ ?>n1hU1NT ܆]cz\m&mw^'y2JH~2tu`ioz_RzڸhԘnRhXC.̈́O_r[?x& %Xg'}v_+o[>4.[>c:j; .QW 7 0F(%O>o7W /=! X;rvq'W3k׆VZ&J^a1@~!-)+/@ #+aEi{u.6s5~jh|ҦgTXaJwHJSċ qjR2_~!ᇁQ}zI=rǻ>M|S藊O@x@ neGLo~EQ$ tGd֩W4N +/j[җ+R@J9pݺ?9>s@}ohԝ>8Cȋ7$ 6=&$Aڜ *_] _-| A=#qSS\Vs,൛uޙ+ǗO "\r$j4Z,zc.=AZ6Ƃa |-[(MFoxC3ux N-BhgpHo`opxTlrJ 7x~U]]mMmmֻ\KXr4^ufCsb˅Q&~J4x5w|q] x  "]%߈JzKL?N1ڏB"h`9Id* HIu$zWڃ X1~c<ҝj8@5tivqjvjռô׹Y@Ӏ+nGlXETMZ9|J%i1T>\A="16W<4Z;5q}pW`@]HgX16' @TFGq̿UcvbnMk[G[;LKb.15X@)QUaȾ@ϤZ/$ zTC8="*:<*:*6.)9>!@.pxÕU񡲺&"1%VD粸l1!vIzif>AE] ׍Ԟwlqy>p©gy_F~(K}~n?1@ uߐApwK]p+x]VLFeCck36̇Oc붷tƦTV467GW  [ >" QoBg܇٠u7?--$=_F W@_VE1Շt'F{pO'I7e㶟H8C^fSz9^w/xӲ\vNS&ܾꞩ:g܇?.z{ڇ?L%Nh$Bna٤S~:j0$?n~t x2prhhVJR=تGsc WK[p;XMFxJYuMcC#t``<{>3 fBI_#''?b((4/bt011C 6##zzH`̔eU7$?~jEul.IH:yF%EW{ǖf &H [~/r9brJ,Z-2B9` ;@/{C0@i E]A柾:DxL4a ) 'XQ #F<-UB" VפUg|v*^,px^[A ϾJVK&CTtP;;aO|=$`0~\&N&6& mȵh:mhFƊ\wS5@!s'_ f\-k.۔*{vL$pZj:,b̿ :ؽ4J5XhعƸyI=Fo=~ɩM~%]2ZB*wT5W{WeGo!ABFanaYEXtD#aD%p TFlS<c?bB!HP $}_h!C6"692.%*>UłJkx˹Z{'egT7{yҳxwy֕+;7?'x!x)x% b_ ?$)ě۸?{b2,/^֐`l3s8~0Cw E k1Oƴ2еӋsuzl[*4+lhAŦwCFm *:?u~1̝?J5XeֵߦcLhO?-J4Kاpяq-7\+ O pm\;x$s1}rZzrEڎq Euu\=F玡`i>QFQ Y+cN~ =?tRC"Ba#WCAMA]QCQ떸n> ^,|^j'8&:\tn)9ggs;pse?Fv#q'q{xHKaԫl|l7٠u-f2@~}1C-$bF0O~j?\H0x u+\%n2&,. *&ǎ^h;4xLjH̘Ec⏎ş >>6f8ۡz\G~ofhȧ>~S}Ԛqܡ¡ڑα!FO3+hU'w N@ (MRsR;N 3u ΄slJP AN-%OG"٦G~Ct Q/J/T\` ^>-. uΛcwuzQsqe.Y}J+im~Ana/>v5=3+;ۛxΏt>|1J8'_sn'ξy'N Rw@!~hڏg~@*I`k0/ZX-Cn4Q,] ]1dޞLU:馨`@ڏ| M0 p]bؽʸsUSG܇7/24\k3tmjȍQq }clٍx )% UtL@CsHfU3ŐN޼>lrW۫Tģ]*\od]Ektv]{q3b.~`vAN@ y M+F 0H <мlS@OPtzЦ[`htto@ɩ1m` ȴQiKMbL%H1meڦCin-=20a>h|Ȓ 1{N,']XNA߿YKDy=r_ϟh|Ȝ[c,'YN`9A䋡lW#9oĂs'idhz~?~Q>gT"`)Y3_ڏ$kt3YC~ 34)o)`_i0t ~1`7y+A7CFu'?M/}9)~wr] oیڞ8S/6y0NN-2̊jhS&Qk@]S{hrk[J^ kzIQ&2: ! ?:e .?EFu-?12VVf`#cC$~LlxDɻ[ynLD6m;Yvbe.>,XYa9jȓ I7Ӟ,g|XCLI~#VL k|a..9%K9Kم˨#TI"]%?4}j?~dD~hAL):@i0!6AvvgFSt *(oXe v?rGyu/UnXRPu-:kʰ}=<]$OuI*ئԒ^im- Nzo*iqYkB.oK0UФ:\MKBRW)hm#` J88;9W=6pf|ٛG^p|Nesg Xvh&aݯDzߐ AsV,GmYwb9rҝ 7\ `V^h$^!A/{ }oqPq=eBs^~Q.RA$ ՓHI /i@ʟE`j:Hj?OF A 1pq|1l;U32YeK䯠!Eʍn\rڕտHUwZD;X$we"9;eD*ڻP$,_K[gu}KQem`#͈u=Ca0I`QMbx#c'/n^6vfVF4}df ;n\Sn{:kYQ`Y3VTeݣIu~}Y,'XNyfz>@ O ])[x|Qp^yQMbuzD#Tt3U_69ʮʡƮƮΦ BVģ^\VaL)X28~nFl4 qr qI +l=P|Tv?no)x? =(5a(SXx _(ZJh|NŢwʾ;\ Z k@?V W8\.De-8 炐 ClvJ@?`cIN^F od5$eUdull}BC_ Sw9-'o9)Nd:P ôUi,5Yir'in?ֳ<P +lW ?)Du?Yl.RN2r6r t}0xZxD4,io¥2GuJ|js;4:85:9 n5;Ъ];HTAqO `8pcX%e,c q? tg7F`g5D '\ V=PKF/\#P!KWoa$ 9Eg(BjC`N/P?Ot#gy/0T⩈'b<}*,mniDGzkY^~ز³w 0ox-^̢(]y.M=o23,d94 ̾0~~<O(~EuwGO ϊ%2*~ 0!0GiR *- T[Qo[ѶD}VBZs48!]hoƺ}(ZTL+xc~Lc>Μn8 t8N7{]I~4/Xa JU{UeBs>u>] } E= vmheߚXؖ[UU]TSQӀKѫ( @miIt cQhZ6zu>qtSp_yt_DTJUf^a߿C1g^Z}k֚Z3@ Pi&0Paީ`y1$@#`{<3,,gYxY·.F]s'qÔplu}  {P(~ª,RmE EK5ۖn_ݱLsɛ_ KnNnvMZ@@b_dtP <`<NhhțɬC4[6=&zgy؁{p'?~uP7' paF\4&߻Nybru eI()`WZ'NB_(TGG!JK`m(,w9Ύf)E%C@Ua3dF ;HB/?h=5->u{;};BwI RғR1U7Q2.wܲCg=k5> fy nuݚ,_3fޫǼU̙Y) Q@ Iq+K݃i@ i)5Lh^ +5Sj2WeJh/?kǵ=P Ѵ[0h?fRC]Fl!sAq0bҙ18_3U=R5Z1sx? Ovä]ư_eMkW]qմcELcbqw0 P~`xM0{DZa"(0/I" o@ F|*z5{:u<7o.r|nJ%scB\~g}JZ}Y`gއ-p"0pc>Ōy </tB {o'C Ov7G_@x{ń'%gr`;@* a`3GurJjl5aM2@_?~L0aLAgXᣇ܆t=6&;ޏ0;quSfQc'G;w0|1 h_6hGO}j / aQ"VeWW1?18 .wy0Z@P: @2*bvl4&DhH"~!B6$BqUXZʚsҐTҽ ȱe ZǼUe 3m*"&, Y|f (a@<- `QPc t 8S O\1bM>4է`2uiqdI1 <L _k?J'u2|hч?~} },8jx:#NCRqc~eSMCǿ~QsCUxjI\}MJ|eem#?4'0aC(iP fN;@5 '!m⩮czG@~癇U^qk]^}uu4 rZ{4`]KSuCi׀y17q: j"1z#PCa i8H4@(Ѵ |&scϢ'^%N"HHɔd"&>aE~C?;|qE9mz-2r5pL4~B)eR7{ 0WmҮ} &&cbE$bގfۿ*AԱiS`\d?}~Z[5'a 0:67[7Wh`~K}2>3# 99%2*/*o&Ü9k`P`A@Ky`s{s~'\'8òyg9PW]`YyeUXV`^} j󦗤R{V8FޫƲK .-L{Nr:FhW _gr1r ˕x֫4S, Po C0xQ 4o D{`qMChs1iB/&=gp&xƧ,l@!FQ#bq{[?1O}mrǯyBa0nw}4N*¶wp'3֝Ima@~I#cm]-5]}CP005E@o@&GDyyq Щ V` b 8Wei楧UgyHxYW^`^qyP<;L"B`KVpSQ!V>`t%a#s0r. Xx#0\yi2Xdac aPx¾YM] 9~7c2t';@0.l0N"L]0 ̛@Uc?>Y83,سϴMM*WOmܧ&m0b$neki(z0x 8+1:9'!$)q ]XR6 8&=*1+- ##޽OIώIH J q3wQ|c%fbdGLC* B\? o@1m{-z}9~Y!8KXúy嗘_fZqi%AoWa^ϴT0< -X @٥@کDUH b=̇mY08@ ˁB؏;\0 Q 73Xo@x/c < (b \2Ms9d1 |}{@~, ڇZ§qǵ*tb] ;.bFGOxO`?bd%ᣂQc/c^ōNj067syķMz:Jv*6lj͆f-B::r:2:cZ_6>ydU~߬Eu]QpExVce#6sAktRu3?ȔE%A !f:*zv*f%t/ {"faG-[P~ 8'an^o}Ķ$iIe'g-9ʹiYe.! $D@m$(t%@Q`!'l8ا= Lw@=pw(j*{O-˽>~/^M^qi)%9O\yuz1P u 7>#nzN$Lu( e"ac@ J0@:G q% [/E^ı^@-,Fz'DF,΂/8^ϑn+ KP@ ZP 6~AvP}H{_IP`@OEC?ϭSWZ6 VçEL`b |aAٸ򑤚ͤ8GڴWo\]Ϡqjpx}EÄI5se7UԯcYyJ|"L䳩`-q2݄*Yo|+~4(JLwQ21 {tECԶ]_wNbsvN@1,2@ ,8~h s7n^2Jڼ7x /ǚ̋O1/9C\~u%K,+LS145X? m|BUU%ia82mU`ަ̼vh ڡs~/狘y-|z @J@:p= =V Ĝ`5QXPdt#T#41(D 3? h!W#Fy%~m̖><8iH9CuWlvi)2QxX"'/ʩ"ll0|meYd~Δ|\9O˷ bez AwW{_kT}mc1uae{YJI-Ȳ)5y(oD?w<}يla[ō<a9J^ꋄ#p 1,7WY?1NkȔBu۲=*6_8X} ~9xym[AaSgb*pf[uL%,?OXqeEe(\̼>GOISlF Tvka 1<t“pƇ|.B0b(B8 ^@\Vl0OO @2x#C=^.L(#v>.FL hqP+(o@|p:8!֫8za2$ Ø@N:UuH}g]z/Yi':gk/}ӶQeA7M UtPG S0;\W2ܻN .-+OHͅ|USf/B̆/4q}aRO?P{c _AOm Mmm>ry1EǙd1LK1-9ϴ¬=V0y̺^I4$Q@7,0f9z.'|8< <͂ZX6=,q)0l"Dat|lb7Mp ΀gx/3Xh<06Ǻ 7 Q30ӗO~SZ8MF c6@5b2 h;HXG@;YdN |5vv|+ͰN5a9hm~p<{OYE/z/8r}Iޣ>cHxdZl:{N%K Xnsk`)߃@+v g{nӼBP !Utͻph/PiYEvĔ,8i=On'.z}1 79 WPp򋎉Ab@a@+`Y۹>~8Va[MZ~e)8˦c7ga3k, >eYQ&1M6IQ(sP8E٧EuL>Ճp7`^>rod(t] 7YogdXS;ï,+Lft I8 <PoIhA0-%:t=p8M5bA~y˦4'R+~䛌rr3FUSƴu3'`0{0g(g 0g gJ&i&a,%m+:yz}u3  N@A@"p&Q g [(CVc 卝X @~xR+|_X[mObe~i =do{9 R#4,, ?TIc(\^il;viQ+O_wk9s \fܛ>P f^e /7;gW]xcڜߐf9 FXG4!G8XЩ醈,BYxYx+.@|)n1;"Ƃ 1"POZ"LE]#bqmh L(% EoIze& %C#qhM31UG9a0O5g1voL!y,l,~u.VQ.q01.v$lnD[@) : - D@Sqcf#Ö6^XyU?N^_"LƜc9 s!X2苾``At ]qX Y# SWR_"i$ ^M `C0&G<`EJch\z%14vlQ.&FX1dzu_`Sէ-~7?-`9M7Mll 60Ŷy|ޏ9y?&>}o!ɱ1X91<:?4?7ӍC/Q l3.^D :1󖧔O{wTL|!y@``ދW W |<ƃ|BJSg-|ix3KZz  BP1i LXLkZ۩κ5 5)9< /{ͻNן|'P8U`C-Y*bXS6[SJ+fTqTA1Zh0 ECxU`$ 82`ֿܨ ~ ag\  $7`;Fp~U aFHj0O.}Gz;A%x =W[i=~? cçɏcƦ`\x(ͤ|p0xڐ􊐴򆆦V 0$# e@ 5E-OH;p~2oC|B֎GOrrv6)AK]s[/]X 5=$m|J jaւz0@05Z:F& e;ymK ̻y1|Tx#|8#1'@/,kBGO؞rT,+Z񲆂1Di8f=HuB}Lc:(.t&C|]?LÏ>vLWN)Di% f覎<cՋZ?>t| S#tbvaLAK;C3dRelRd,b2+k4Чq GkQ<^@Ǯ{H<օ @a Km=V YkmЍ5{/ty@CkaL34cO>cZ N@wam+MưNIgZ&#p~OXSgXW/_ <8sc]߇ƱA5%YM)<.}+A@Rl%*Wo%(>`>N6K`A"qE)o -|dpL*ȫâ^;+h@`?G@ `֖',[=$oC7F'="J)|P,;9g-ͼ 6Xuai +nJZ Ofy6kYf ,a;4w{j `ͻz—DhN`I/r+n&n&n U$B%^/^@ `=PoyڽK0'>"Q#Cq@-Nf?tsD%y64)V eXh%jįA#jw*1O; nԢrKZ}Cb`uVEŴ ̰Z- _ɨ uiQҒBYꊳKg€Y+͢1഼0 ôE cH-]P ckHy|K3Y|\c'8+ XJO~+^GY\Iھh*x pTyYe1?̇%P@?4kj]3}Λ_t{-O F{S@q^g> >&}ܿl}d3 Fu_C;0o}{{hr|cǜIcq) )DG{LMŠ@@kkZz#3."d5Q^9م5N80: ;?a+DLm oB0!.:F]v0 ځma[V h Z'8k=, @.0ұAښöI']g<(^P lFX1Gu'嗇+$A^q!@ P9pUxg=_1X@CXV#tTܤZ {k68? 9]ut fLVvOu ҮWS?L&|}d@&'S&kǓjƒkJ'?L}趟cڏ_8o;50J>L %o^hwU0 0 M t|BA!b¬͏<^ѻ&6`(xKkcSs) 7WQ-=A]v<uyʪ D舆x `P&ȄB1x鎠L4`Qp XC2 / O|cAG}Ayai1xёф˱ s,}^8wٳysww80'@~RDyVJy|VljȇR`O:h=l 7AqP `~&€ˡf Y8>czpΠmŗG\뾹:K;^r0Lm#h&_5k[]tRT@AiJI&UEc^c&f1ezi95XcNa,h`ʲiA.@?'v{% a|M?H]t"XL.y>|0/>h?P.4#GI+n^r= ?[VZ[YpCCB\cǤDf Hf&%4^ivHsLwN8e3P8S.Z'X a]vNjVaP b  :2晷mrYdy(~kzi#)F|` fş ,l+x<OL+W<1p= @Z~,c2!1@ :|?ţ//IfP}zb@"`g Qxd+=Ԟ5^sҊx9ֹXP) CBCBF%f6.[6u b@ebn>uӁPh8, (EAЂzd!V2}+Wk38S;$ؠ f #&iALNߴWv8A( N ;L?]!R]c/zb6yO(<- 0 Yǰi~?p%b 1EA[Rxo^ˏo}</OW{ zQHN@οŶ.52[._^>=c(@]t"`-613}rVi(,*,+,Bni3:6[a}`~@mhɀJ t!:3i.EPX5IbOǃ?_ +l jvyh׿ۏ7鋯{7:\~iש~~ bA?BBϞjGxGM/_%+"$&ndzxer"EAmM̨>6GN@ee&n1@ )@]`ZBa,#IA~Fˌ ;Wzhfst">I=6-B[dž J <7̈ hHgs |>xʿ cDå x@sn!F `\S!qL,/MJ@_E\맽S ~'G}|^rѲEKOwqʛ>`i;<*;jx[xѴEybF9yGYFM2 ؄td3*eDaQ + yl?U퐢ra ĝ9_Rpu,F5e|Z"y&AmWՑPX cd$QKQNI2FZJsT&F"_#S#=BJHF0)@j``AW$!ukxStD،_ѓ?ΫqGg(Xrj;|(HQ:xpAxNܧ+g(\ÊR Z_hZ43wN@hwG$I (CB ˉ lR¼.N*Va82XK8"! … bk­L1\Ci\Ƨobz ldNƥPVM4:Wb%X$2pJY )]kXϤK% hbxz~X\I-hc֑x鿅=_=_/tЧ@j A^yMfr x{<|Wo>yCY+=c^?;)vq'aye NDݒDx$Hb|a@4LjHwu P׼e5&- p}k\IW&uOL0R[```.m>a-W|惿YԧYE-|\{@p^IglM9XLG/ܹ}-9m%k,X4X3zxmkXKEe㒳&Nq,XM0db?AU p@8Cy yP{s]YaIšYF$ЂiR= 0'#i'jY4ᡬDŦ2aMUڥb/K/}_X_Ê*2b(1IW5|뾂+\}Pw|{/Gs1wE)ϰgoJ#|ܸ:`0aUZ !7j9r煋3Wd4xE[4j9M>Mam+ίK˚k?$6lct?(C8NyE,X43Ie6ΣII1VTc4Ehg tѣhԇe` >BO΢M g . H$frH JCȔ1 0?@3T5ߘV?_頪TbZ%|M|3鏟}b5󞼿 6,"P[ۦZl=}myۑo @ڰDnqUhdW{-5lvJA%*Gyghjbxdz6jkˍ b`(# ymY Di+E(MIA!G -$Q8^ H( ?,-5/_-MoM3K}aTѢl u! L_]co&mq?7_Ӟ|ovú:}\ }^ٗb?hR`oΊm=EFdlYa0vgʬ<)@Woܹs5:5yc:*+cfx5u%YEl<& 6phbpE. Tm\ĤײwP/^g~??OS<zT9(%MF//`ۉ7\I;3}q" 5m{7>q䥫7ns׉ՎF>y FLL׸ܦdT-hkjdo24 TU׷d9%n[1F11P-x(l,'CٴhA%*LNg mNGU kW3'0süBNAL:a+F@WnXʰY H^a(B=1CS/ذ3C_wao|_s/g~_`x ^1ЗX9E_x9 EIo?˷~z΃M"Kvj:.cƼw8sisWN,׌`}0$NS$N|y`^Msx sfNE 6z|f#α\Mc'fdN CP jx$PN@?^-wGòM p"$a L.MfJi6DqvE€4A`@6Q#}ҏ1&M_0 Ʋ[|oO\c\[.SʳٯAe,loɓ~}78"lȤ%6ܳ7o/] }hH):!  t4@eMsX 3`SC'DgyNg9NmTDGFDR(h'H:XiPw=mbw|('WH` mW<{뻽_ zE:g/@z/|) Db)>xFFۨ&46ZlH]tVUG̅> C1e0"G1Ti\ah_0,>kX+ q3+tXUQ՜5wiqƶaJ !9 tEl`֌.=@OR8,/ RjKAhTy#kH9$)-!rTal]ا4 e5W_򊁴W*a@:Lb^+ 0?- ҐI}nU鈖/ &πK1^%g[S;Bώ]zmsUʶ$nJ,ݐ0gmlAGT҈𬖰-ae5Y6iVjAò`x0tW-X=q YsׯYvQ% JevR,CpLIco6<)^>N)KN@^k)2{T=KL+U]m]TxqD7"!8n]P(*Wc"9Sg']0O24 (5FT$'@eBV.I1 f?hQJOu! }igUx4aG<Aa'ag?3z;u|z^~X/֤\ oWܱ۷l\u0vCx2J;ʛ6ΪZ`)@ZQc۪?)СCr͜Ј슪wvn\nڵ_Xh00AbAV# yЁ@- P!$VaR@yCjM}k0@WŶDG}Iht S5BĂ21%r" IUDz0 I=4{'p zc{0c0`0x<_|]P`WJt9y TP yߺ^n5!ptQPZsqÆٴ?knGdNU$J/nZf /0qa{BZ(K5 ظq[mѲxeV~șS-ǡ:Hao)#=s>vYH@m1mcRV*lSʙ-03"foވyhb@V+- e/ԘJX.eaIS J?qe}lfU%iiǨ{XI `]u V> n$cvG?'5rWl^$W룔wg>L=MIng |뷗m8<|䪄ٲp#˕<ҌRMGϬXzv0=^Njm_1bة>!)Ӌkt߰`ێkǥe器0 3)) mVj8}C$}$tɨm4cJlR2,]64^H:= ]>6[jL7= @E}ЃI4J5B OƝp$;/]B礄,Ʊn.$He6xp~.TcgS~tw_1 ׌W ׫˯y|K$@IC4M{OUnqCdžNݼPáxd s7l +l]`\TVHLYs4.Zn݆ 6o޲mMYiꆶČD TQFm"12Qigg8[KT p8%ιk2N`Oȹl476Q,hDG[I0P46Lb ! ҮyXJ{2E\j1Gw0ovu0{_gO0zw߽k(Xś:l{˽Ti}g؍9 ~->  26n]Ut)s j[],hv`z={[pnKHLklh#H5Ȇ =X#)8SvSSKQIq!=Yp&JJ2r:c#^a@_./ǀvgA4q3Պ M>uJ/ftLMr.,Ң 6f>_e#O'rn~gA g>#!т^o^:Y?]=@Oa3p7_șmw;vs/lyrye`i9s/ؼq0=^7ͭYT2aqիW lܸq֭۷o߹slؼaↈ;d61wPiRFhNs)dgwa@>Ilk{zhM;ΜUHs =!uތֵ=yMًg_ܽЪuiXc%r'sǎݻwرkMֶu5M+Rr}'pQM7 N1(mqpsj޳xP;qhc#TιjYX)bH`1fm0LuW(hi&0MQ/3cTzŀ\B\c! f~Y'~w?ٟ|7`O {JυA1zOw!dPQA^`Lxw^r핳/pK/^ڸ@.@gȨ"$Zy#'\ u٠ܭ[ap7mڄؾ}]8xȑ'jVNZjODM 2uKε*#OB$i|(#-0B{cʃ2PEyb$1(Bl@Hjv+}N/6<1T0G\ I!bb؎/Ve/Iz5 k=Χ~X?OdH~? @k.]޸@negC)EK7oeh&zz Z1yj[Rlb459GFnՎU2Վ34C&4TPv~ bifNȩG3'66Lv%, ފi@ߌ'Gy6&F QfU6O%uM&Ґ]K~ØOW"_ol#E5z6Zjx?{|ѡ@" & hhA/^>t /ې8y"D9mw9=ׯc~:/l|,K={,+V=CG$1w"0mf0 `cb%at sjG2psQ3 Pj QTA|zM€ 5Bp| 1Wװ-TąkLE6ZgHxU`-NyU3Wd#YӀA̲G|?=aRP>W꘾^0y%m f~ 9KBͳ 5L\Q^߱k~>`. WuK@~.] 'j*u{N FL)6wrE$(Y*)j*d%ɰ9iz.Yn9l-9P!;<7L[jh0azgʊU!YZذDDžuҥGBݷ PXry$E+9.sG'Ft9![v*je80RalskCI(и,(C X#Jfj`M`@ "&u1M抲bbu &uc|)$m# pFHbWzg?`4Fiaл+ kGٔ:\k>rC@D`݇+[zGُ?2 +߲,hx}Ky 8~;ŋ/[Bar[lzNL@+kϬ/`͌:Ŕv)jtw4j'h(x,8Իp\5gAZ )3T`@?@SuEɴ^c@!>z j`9-Б`w'X] izv ٥{ɜIȗE.zo??`tH!z*H<[+S\wx E$Xi_FR~^4nI%O9K_W gGb*~ ")'@rw?0֌@ߧo!)Y7MCKdD# 'f\Ho~ =?GBhG,QϥxkmG>>r}ɓ<ώh?i=]3ϰ~d+! H{wAzswb~ːk. &#R37_tߟ/|%^riH!BDz(: w Xۊi3I@Rb\qV%a6LWi䀄TJ2(7ȳX߽X jz#k 6i_〥cqhE! f2QHB%ıL?pkwI~ P1Anu/pIoUogo~m, z=᧚{iw CkdE#(@lSawܾyev&nF].##fT7wltsS_d _`HK8" $PAhhi[љ6 %p'0#,Ѱ`X.#Mr ^  |K҅˰2!u&~ ]itY &vy'Tʐ[EwU]κ Fgx8W`<-,@VuLA?i/:~qهO]" "pe/[:ogtqY/[;R" ?0RaD PyN4n溦ºS'̰^"9Z*ӵbP;yLH$j AZH =+7k2݌j,c11 iX?x~[L>0|נ{G5mcHL'3cF"n,g{7E1"X7oys|Ӯ{H7K UNxtzC¦{5g_Wrӧ[_nB[?_@QpMTA7/GkIjψ}3&#3wU[;9wyA L)/Al@u` (FLǪe[bSK݃ұQF+RZ+yzDjp]aӥX ȎVH 5B*d< #4#k4hFAj`ШfoIR4 fa[-&w74nyL'0p~}L: ;vqGWO@ڢ m<8o}GoX|+)za Pܫxnݫ+E+\adT#_\a:/qxuڝ%FLwc9&+68;,}^qm ;>y<@ hU o^7 0㲇C @~~M\b _-  EA4.fʋ IT #-Ç,\61s=#$Zzd$UT€v*C@m|",wUx}(!!1+jEݨ6KSu܄P &RO+8F0ˇNGj?ߺc@?#HQP)TC6a#x(H?>X Cy_e0:``xhY4B:EᜠpS8 Vܼf<Z% l} x,< PcPOX9LDHHT!'O F}8t՛+cstQb1{X);&2UT^۞%=jU-r/G<Ɋj4lRj& h.W0@4Zֱ%``/ aG5Ἥ!ĊkM߼''r"qe'` z&`:g}z!䯶gK!C~>oݺ}Kt΂eJDs8>kz2a!i0}FqHPP C,0 JDQnXp7nޱxٚԙQmjLtTI0?.? Dh4B6b30bZUÊXh=&J( *svգ~bbFr٠EQ4!s4n4c\\wȕ?~Xa@=Ãq=!!ǀ٫'{z!o[WWCqa.^>uFǕ(׿b@Vy]G.J(h/&Lxg. ɓ'u"QD_{سw6mپm %Mu0ZQ3$QQ%Bl6rsmZ qҘu|W B#8XHy,Eۦ-w6 ZEb(}<*?[vc˱7.~ƻ|W"i0+$E /`t~>M~=nk)wi\yḢ~{+Tѓ ~Dԋ{#?sn+o׼2>nx,KA)i*;x<|gˠ۽@7Pi~G&xkPu4zV~N0' #c0йh Q&$ P/=T<ຐT-'!JB B4O=*5 nHb~a]~+c5,*Nb虧f-ҹճW?@fGna (/fONz/7}"aHS ^ 󭖬ZP]3:&h-:0;:?rzea[]zxUUX,sh BEYa+CeЈ(1Xc`݆-3PXŀ! ta@ٶI4MR[6E!k P{C< Fb ޭ*XmWVVqh#cj$@H^EH_YwW'}=DuAS =^ hAr%$<<å[4 qQm'w?l M;ԯMh ܧxEN̫jYnVa_^&@JdWVDI¸q/XN\`/B@1Baqf} }*(ʦT *n_]  BB~%!S8=@09tvn(lNi5<|{<h uuQjͰpLBO{W 0QF~-ń Z` %W")G.0 \I35m8u"|u?Ri+bϷ~Уʠx0 x$:8p!*)B@7kIua6iu@W e<0 mFM*1 N`pD"`6 tT€V#jThRJ2oʷ]5zoJ$ia`:au6]_εWч>%j$p :IWHbڪXI(!? 3/yyASG:Iѱ~2}QEcs- YnKeC{Z~]HRۄ^IAGEdcz{KWo oOJ=';ĂdP%cd"5 S6rq:9j@$Bns)9.#í&p,zEq0 `~ 53 g{{i) |.ac )f{)=(= !- WZI- ^oqФ-;+7t^;zW^{΃G~t^aS /xa E3}@?H4 Om*:>v$0⼸-dJ9 ;lڳwݢIUYVSxMs5p L99a]n޾ 6N_>=/"!-Pw<,a>C5&f 攌~#-"8Fمi`" 뢋i%bPWd,Ը `|V+иAB+A*~jJ񨀥 7`0+PYZGd¦3[άʡoܸ?ǟ0 An0TD_}'_W}G~| Q=3>C,_8" ǨS34'mzoA߶`uˊʊV,ؾcwiMĢ~q*HC!=~֕;ot$d P461IP䝓]f-)Y0-?2iĸM8!y0fN΅d&],KIn|&JEHU0pB&*30+@DRp,e8 F+nRx pפ d7\soP=<{ȑ\˯?7}t/wݛoF \=ᳱ Vq.P\p*:ƯsH 9#BΘfVI:jIޭJ8 PU*֙mtJ⓱cF{nz-G_7M=k||O[E"KOT?O`G!L_hz1{h $)׋ӿ|K_8vZ߶sM':mܴp^KP|x~CKJm۽ w'xB'@~+\҂":$fq0 /FHItoܼaaǔrI hQ:BUCj̝u\c<Ԯ@҉S?HZ X%)׈ F11ER)bag՗/|Kf~y0<+s kLۣ 1wxoAj5yY\/>4jtH?ɝxƄ8Ϝ=s)G) 8nMqF">IYulDz@"hb@p4K^i1"{jIuQ^+e6o[Ҿ!*h4G_LEuz$%)$rdi<[b6l4Ls]sʧPAt0Pp`I9+PL PPͳfL# Z6t )br)SYv`Dt#"u}ؙy͇ο;ξ;krc^ M1~){sϮ{g7p~c7O^~_{ֻ~gryJ3A :ZP5b!շ;x'7m߷vέ;1Mб9,IReY #17;έ{CX7EW䬦A0} iA&qx/谙-׮ `Q^,1e5kț?)sl!xNNU;L3pN7va얥u6rU:"Y6 0@#Ely/1ІȝJ Y6dߴƩ?S|kG/~ ûgQAփ]ߺVAً絜m:^{*aٻ]m@Pn9(gOJќƓ9'pf5YynK;_?s7| ,*yDۮvjϩjm^ *"J#8d#VY?z[̠ 2&$(Y޹ }D?EPU  TL hz.9\  rb<9@c(+?7lBx(ƆQc1Ie$m\1Fi R]3]32inq&?y GC,,! ؀֓uA-;z$#~ Ǵ 0\g>!3ݷ^/?aGzGJK|!~wN:9íG_+j=_H'|BS,;3CiSaReN+OL/Ҹؾ7|U;֩s-,YWv'S^FA~h#lܹyWcòU5,`ֿwdUEfF9eU7'NsU$RHD~HO! 8$@q:"D3H ALDH yT`@J$h#w@Xxf5aA&3]0` gahe` Voi#cM>IXssc%Xp T8P8d)rIݕTO}Bę1`FBFvTElLbuYqv幺ڕPJSӓ Mo @"b%OsgTZP0V=V6ճ}.֩ !I>Sȋܹ畷1a6X?x,kQ0o.]ǧOUcꂮ]q4R$!41P`:@(f+9ڰa#&>MMmUU00(DӄVzb`m:7Xu̢qQã%igebMb h!越;8MnNpMSmeI J,0 Iya@FM%s$P,FvF4iיj4vٰU)3fl[2dn>jV縍C(h?Lrtrtwa/v aBEf[Ol)زxkw+_,آuԿ |9] A.X%kN\Kee 1~֥+|3]"<')k^eWx-vo_K{ ~R,T "7Wȉ'Kĉ(yFEPq󫫫Ol޹c{CČg)F6 3 799f[8ch @esn9Y94RiQb%8u.Q!11E!ELW@Iv l;Hs3@A$j)q&"` ,Jv4Ve-!sʳЙF`F ,y/g?q.3o7 7vQ`v3Yie9 >b{SpиY);aIDAT y8QՏI[Wq݋ ԽNv/;LiY?-q/_czha7(n<6\J-ֿjK.[ؒ[6&b`耘٥u oC4*Tr  #ݒ B @pq!y ]bmXHmeay}LJQ`DVPDNPDnPc3|;DF`Kxazj[ V@"PT&j;Yd,"0o@`5ȄtUѩGp$ .~4#?0Ԭ=Bt;~n3 Xb0A6sHJa0vf`dj5?Ucj;zxy+zuB^NtJw?"&!/+̯.jiY޹s|ϏJZYPSVڶzˁ#WԽxR@(^Dx}ŠVI7(/ӯ('DX`@44`&:[7mܶy㶒QJj)F;,[gi?=sZ$C{ JeWO'zxM_€Eh*tYJ1yy0f%(/E \3R$,ը=k`Q$ ~F6j h@|q#1GΞbca($5ecN_n1€|QLk!+!$\V]ڼmk֭YzՊ+P%01!c\gĤX{N9w] A-*R~ϑAOh:IBlW E oѥBQj7o<xMd4] :14];w޹{Ϯ=-3frbcd._Ĥ0r8-)A.Q:Jm0W+W)"26pB8C1]= {HQA0Y.o 4JQ; q vǬ`4AM[ |1`L=zz >x2 *;0*JϹ~m:s0bYhc^^AEK.|9XvҶM4V7,mmhi4%jҝd7-Y}IHY~`"K<'@ ''C r>C\ |4'vXY`INamdrcHN!DH@bT<2֦X{1RxfMG+OlO3YdiȔdS6!'t`EH+JuoYg*X,̬5]ϿaPpc1 }0R2}EKǽo%N_zTd='8)yZgX?%zunX^ꦬʸK*kZjˣg1~/J;Oe??iV@5 "H w$E%]\HSs%,^ ți4uq{hج!VJE,SWM0pJa37oR0&SUlMBӽv,iKHfǼ#Vdfz%vēʮePG ,`nd(;\\5hFT h0n? =UQe]oLP d_\X'rA4BNZRٺ;A~ϋ;uX/P|]eKk&'r J +]P|ތ99E ZnߵWnំ^t#@h4@4L .DC%i ` vLX`ȁΑ%0u0 G YQl+v3餶qNSxdX =s,t}jibCAw^76|NfȣuTwM5Tv*`#rDII L|k,n?++JQ[g37zXp04MW<"eVm.޼ƽ~{ܥO;)XX_K(Յ\'.mțS5!>;/,5.m9eTTUV/S:v`/D#oA1׮_:9p@QD0 brטX3- DJU"> 邁b2YR=oRNiX/˒xʅ#ƎdbJ&iOW _5&>U,1_6+MQUn]oY`UѕF|}r8 !|a3onpdϑW}xW~񋐗zZT#K܉Zy RdOʉJKɞ qQǪ5{rFǟ|HWi0RcpH nWDBT 0z`hh"Y?-[!,4.Z^^0vZVytRa>S dKy/mH;*1u+ =PT 4I*VP=EzR$4f1"J 6H9 w5 U)R*!HP 2`` DQn=op@͐FAn>G>GϳpDR%z*w>=^ bT"c'7,s>x>zh]YTs˭?܉,]5Ms*?.vWH9Bࡋ.#K bߗLQ7 _BLb?RcȂ CFE X%&JCAvC!Zj͂ŅsRGKWSF0;*1ЭCLDm\*j) ]H@x@V9J P*m067[Oix lKZDs0N:v7,(ָzWW 7h\=w,.x f5#9lKeUPq꜎m'wk4S^C7+oO~Cv~E5/lilnJ9/"}º5wBM^[b%۾C g4,#Dj  JxМ9`@";`!]n e ae| D&b ՘@i&>QC 8/])Fڵ  y*R9cl~+ qYPT@^l]n?*z_Rkᛳk^{ӹYJgJt,.^bO{pE]rڃN*540En̂qy9,YIP) ?asr@PT앁 ^/0e(~NT3'T8MSUpsPXg^g0@ЎhAڸm²3bB|,m,"9{u=LeI,"  @P|=Tqԅ RY 2nDLn^oTUAˌGM蹭KߍJ~㾇ѣdjOIis;w;vĹ ޾}N=T/T aT'ڃ(N1uVe|DB(b_+Fa0)4BƉB+Щ#Ĝ9Q1AҐ@U Z mbbu` C |CGWqWLEHBD`pjNa1K 7kQ!w(><*/AiwHdn/F)M>+bLVz-+>e4O6 G! s7¿:|"c/X<]Gk3`⊮p1aTΈXsIF{`"Z CBAԄ=H{8v=ל#-̱ .3-4SKĦިp ^,>Uv)B-& wIUm;O9OG_>͡E֏꺜)1SfU/XzCn܄`PSp/_:t0@ur9IeBh5`~ r?0SF7Qْ,_o0Wh1@0!E|N` m'2"d"Eï?Ǝ..0mԋCGC]y3 q2]e9J| L<1nzqݫ`tssxŰd홪@sr?TK %NGPWG"_l~\jި S=MI/Fiu[<~uZNOr9/r=\a0?.B]*C<@N,bܹr V2 h$:׬]W>1qb[8.^::nQv0frW  ZڝI3,n h7Q#:B?MDB3`YDi#(B8Xam;ʿpw +sF'ML^=3}C00N;v}q[== JlAJʫPJNE•; NiuKg<@\zq!mq!`"axfr7 @(p(0`glHK D䇐 |Tm*>ASQBp Af1c7#s2TpˏM/7z{2}>NapU:Č-*n۹砼‡hOW}oh,|H엍 D kT/nZ ?x;=,=y.B̔i?M''2EE:5vpZ<J)"։ґf\_VL> ݦAL=]P ;^~pӁ*b4qS]ݲrdb~eys@jČzɚD /ib>*/8\f* .DT4Rp,2nmmnnI*odC%aGJER@F$Oi:Yu]/ʩTfGv2D$R!:@:f̬Ò \RLxe4Ui``Ž\XD+좌]^Uw/_L1Q?x,mb55,7>-(`Z' ݨɽK1$\\ӴQ`~@RL\^^iH'SwVr 1iZQFCa#eL Uj@a@ )R<>&TgZD- zM'ڔ Ne`[€$8@;9<7evfjD}$c7``T#Pmc'Za%;?#vz&,k^fӺ˱k^\,ǻ[@U:W9uI+jف"d|t79_"l$x~j%(&$X.(L`1| tCJ,jjHQJABD1(T!zC<$)6f M O譲+FE83 kPG=RB+e9"O$/t*ӑ\W0<%anJv8}xaq*įݮHv]}¦ >zr^LFyae˒kۋ?Ԟ]vݏ?WTlv[ϫohC}pOyW(?wï35? DQ-эؼQ"dJk`um7!`/04B17PX؍?,f:Rx %먥aHx.唪M3 a'+0ƋAv(E0d06RɐAxLvra7Э# WXw;VSbfϪ[=Ekm\>L&~󈋟 {*+-+).֏@ygρߦ:h٨2? !ąfHR7=1-*+)ƒRf{**OM=>i ŏFց<~^UÂ`s9YS<1snRLLup 왅SGFx>.,`9xNY̔ O&־*X X?+г5 b9|uiDSf*+(AR#Aہ iG4OP U 9R9f҈~bY*IzF&цÀ`s@JrlCSNփJh-sx]yfU47/\z  U'Q<UxvrdT3GybLpU.Hˏ`;g ;oGqai9s"RN22R9]1C{8$.\]˄aYܙL0 ZwRDʩN@2 LP @A!QO;֡ݎUjv쾟k@8(}pus@rBE#| ((hii)ӧLY^>y~m4zgϟKc~(\T=480і1i8KlטI1ɩYA<$tی8uB`C1*3Xȝu D\@6p RY)-BBPNۍp!Pp`E"Vi( cݎU$P2tj-,89K3FaO6n`?Ic3Q nza*Mg0=qtĩy%0?A̜]PQݰ|%R0_(|A-/_|7=pgΞ[fÜQ a. R +>Ёyƈ3y`%㣶m`oloظ!' r4i,$$c@BBG?HБXi5G.)|[\L6u 7tǮsa`' 4t O-])~qqqQQQaQa~A~άYSge*kXԾsi)ƹ=Cŋ|_tzhhi4W޸+Vj&i3'O~Anty#ޠ; KQIGϒa&00kj7CJb`~@ A EH?H:V1trXM}ccIF&:FTzZybNuVC’ҳfE0B\|PP\׸~QS99Xpy>iȹ!_H[N޲m/[U۴$r|T -ȏ#"EA*3/Ȧ"dUf?!c )R[ 2楦$?0ޟ @P5b0`=Nvmճ̾QAqs 8-3rg\[޽x=?LrO1͓&/`ȗSh+;wT0GX[:?Z1S"D~@" r:$ !j3/I)"HI*SyC6i{t1),dxxYg"|O*ѱ;u} @ԴgϞ=sLhA&qWܼu7x!6jංOny k :W? oqe(ڻp]K۔̢F qdo9RBEtFE(<,Fh!Y@+)W"y<lhG<ÿ #tgqA'Ѳ)@%@la}:;[6ƄOMԃ7O2F1*j Jh ht'z@NOT6U nx[ Ѓ@tʵm,]]Xј_`Vim^IMàa!c^1T @=` G u 5vrs_DjKMǀdOFA9 |0˗ 1kȨp)̅11"BQ܆=#ibw/hGʅHpbuO9]{uˎ}U KX`Ra@'6`>I=K/á#-XV3eȑc@N^cוFQ)Y l0PP tzsp2@34P:sKwٷүav?Z~UCFk1&<,zJVVbEH>ri>TN;!ŏT&R4Y{skBb.ml1Ey11Ν`)(b6u3*!qSf^+!2L\2WNeG[c'( %f !Pi ,`-`u]`x!HɡV!ܥ+zMOtX {ISR2" vݺC_pƍW Smhv'22}0~1Jp~9;,~Qd Q5Pp{wͷ: X3mvԙa Y>! #'"o@4S@ptH)I){TH>Ax XM1Z@2X'Z x&v4CYVa8 ࡇ}{;>  VclxLN88xZ FMC/_rh.`7#JP+FE; p0rG>ANde+:.[]pi٥Rq zYP#Oe2 u0@8hT(C|afZ$n}>zVc8G1]f(OOC7VRXxY6 s^fM_3 2\+L':}2}q6L @Og Qk%.! MAa͛0䩳knK+6*̄'e.{XKבT#yɦ/简)ڣH*CG #] `y]6u:a`y/6Y?%,Fڌ0,m|pdzAyú;OpbJl!#4Y?e]]9Z 6cSZRKvƭ lؼ Hf 1.*= <{|<SEH0f` (;Z O,tX1"9fZgXS[%> 0!-ÂM lƨAYVZx>sڌ>aߤqsSf-Xb#nrBߤ[ /[67Z ߨT.ko>{qiZVQd^̢y⧻YRy=5 x!$(t! $SeǂX"fFV;g0Ȓcn Q 53t㣲ew=殶||5Cp r2%>zau7l2k7nȃNLl?.oWyu*"7  \{!w?~CG1iͳJÓ1*}#􇌄Rdhm4ݵQ~:a>` /#K>R>"`GiN Z0w!V>zCP1Be>ı 6m;vpڍWӇ焰&*,[ۻ@}w\:ϔGd,)e. bDuсNi]&=|1QncPR=Gx p6BWyX? Ȭr p7`XhH2DM~I5pF[dǒOf^ 6tzr8u=%aT~)1.~]|#GOvr3q\>\$U(%'iV s_+ߴ[< v<` Ѽn;xl"Ω)._77}fYjN }#lٕnB`Ie!Lm;!1)#kގ_ddx`A,A0c'OM-IY9kn權 rk/[qR PQGGHo (PKiUD޸!9iρcvؼ}-;nضr+;* O-ȂQᝄ IJQV 0(i9Yg:cAvy<g0A(=/(J6.4~TiYǚWwnƐ [v!G}ϡCN_r7E@ʠ*NӜοˋp-|YI3ç%%dOϚ?r̐&%Ovs`2.~cLL`aƶ0\qF'p/ėۏ>"(oB"NV;//gRBvXb^^<ԙ%u94j6Auo>㒮9Uku/ ^IB)Eɠ C@ h׾n^ضiɪ+T^ZjuÒ-[\:xn]~iUzNIԙc#F#0(Po}~I+vxx` 2:7dʄ̄Y jT,(j[8֚ƥP Wհue vnu7n+| GD1.jxև#np߶lk@'J)5S( x;Wݸ|څsN=q';~ܵg7ljZVXZ;5x|TG@x! Ey0m㥂ÕM+_ω㧄'dRUQ}'&DyڑGa)HϜ;sr:Jw~C)݃ v/eדARA,"nG nJ?EB@){n\k]t-;wee Fs=Qx1d o:- ;HYvMGS{3Yd! 0 RN! 0)2 #$`m9믿Ϝ v޿y5Z׾bͲZV<,i_X۱s#(.OזMQ6wAp_(BЗ7m[|goggoggoggog]~~7|~߁߁KIENDB`././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootmobile-atlas-creator-1.9.14+dfsg1/src/test/resources/mobac/tools/testtileserver/servlets/images/gradient.pngmobile-atlas-creator-1.9.14+dfsg1/src/test/resources/mobac/tools/testtileserver/servlets/images/grad0000644000175000017500000001010312122526602033556 0ustar paulliupaulliuPNG  IHDRkXTsRGBgAMA aPLTEklnprtvwxz}g pHYsodtEXtSoftwarePaint.NET v3.5.2iC IDATx^坋4OY\YԅEAVN̡OLfLJ/}t7 /s_osݻߚ;ܻwÏ{z=z~~Vc<W`>W`>_`@+0B0G@-u@/u@6 M.;@'_* !|>G.s ̿~[0;CߡwgG`;( \z`TDKIAށ4.$$`§Ӓ'&7 ܞ- MEd8`V&7<bb`Y\0"@~%\1^1!pL# G/w;j$] 4C,BĠL`b`#1(F 8j( )b\v!'jtWZ] ڵO-a%'A5% @`Z~5tg01pԨ-AcȾOWGEC1F @,i,ըP t)bt%t K$ !?J 4h11z<++@Ib!,/ @lB8IA13A\v ŀO0QjhRQ#DdLR _N$@SUh8+ SǚF0Z 1bѣDC4S>h\T5"LL1L``a* gR#L:5|Ϥ!5R !LLt~lO aTIRhz%E@GTάg>$@;e1KHX X 8hx Q{bx |8O |a~l(@@rJH# 8L@=S&`^JXG L=9 LejDp48FTpK WY[,'L'l) LK`;<3)d'SAlS#ը;8tR)؞I1wL]#] _gRd* H/Tz&6jTj`Nѥ6G2h00"'PG`J%[ 7LjL2%`B]Ո@AgoM Ո3 NY헇;<୎]Jzm @fT>1y(??Q(A0$v10 ȓ,< SY~1#{&pdD X4LȭF1 Si[b0Fb@oSL eqm؎"L3/qL] N2jb9:~7|:F:5 Ijs2F]a؞'@S9wz&,GoI4t1=,4w$;LT#5n ^[$QT "`>]Ġc$"oW=) T@1z2 t #SE汯&`(j#4W H3+A0M1ԓ4_*`KFp$5BF 9at"|1p&maZH@݀@ Ja*`FՈ32%\U1 1FrK'd@:T!+LH,b &L5!c1S>g3L5(}Th*aH@M<~&|=:Y<l d*0613@;jОT~b0Daa0tY<',> J@Dj"B_dA=Te#mB A 3 H#NJ95@_z1XОTe1oFSE ߹q60STQEaCs&qTHhu dXeqX 䆩` r2U!T*aa+ {9rre&0ڙ;j `,3 `@u1 @l0%dpQl5* Q-M 9z_ P8LU (,%H%Pg8 ŲNKX$PC B`|2UYHdsGor]_^81(@T( jH'@S9[$CϤ I=:eq>5M 0{e "̓IENDB`mobile-atlas-creator-1.9.14+dfsg1/README-DEV.HTM0000644000175000017500000002350312122526622020452 0ustar paulliupaulliu Mobile Atlas Creator - Readme for Developers

Mobile Atlas Creator - Readme for Developers

Welcome to the developer documentation of Mobile Atlas Creator (MOBAC). First please read the standard readme for all users.

Table of contents

Code access

If you want do get your hands on the latest source code of Mobile Atlas Creator you can check out the code from the Subversion repository at SourceForge:

https://mobac.svn.sourceforge.net/svnroot/mobac/trunk/MOBAC

There you will find the latest sources of Mobile Atlas Creator in form of an Eclipse (v3.6) project. All tools, libraries, sources and build files are included in this repository.

Compiling MOBAC within Eclipse

If you want to run MOBAC from within Eclipse you only need Eclipse with Java Development Tools installed (included in all Eclipse Java editions).
The root class for starting MOBAC in Eclipse mobac.StartMOBAC

Compile/building Mobile Atlas Creator without Eclipse requires Apache Ant) which is used for building the jar version of Mobile Atlas Creator and of course the Java Development Kit (JDK) installed.

Building Mobile Atlas Creator

For building Mobile Atlas Creator please run Apache Ant on the provided file build.xml

The default build target performs all necessary tasks for compiling the sources, packaging the classes to the main jar and the map packs and then minimizing the size of the jar using ProGuard (lib/proguard.jar).
Additionally the build steps include a call to lib/svnversion.jar which is a Java only version of the command svnversion (bases on SVNKit). This command updates the SVN revision information in file src/main/java/mobac/mobac-rev.properties which is included in the final jar of Mobile Atlas Creator.

Guidelines for publishing custom builds/releases

If you modify Mobile Atlas Creator and you want to publish it yourself please consider the following guidelines:

  1. Chose a version/release name that makes it clear that it is not an official release: Change the version string to reflect that.
    Example: 1.9 beta 3 XYZ edition
    The version string is located in the properties file src/main/java/mobac/mobac.properties. Change the entry mobac.version to your custom release name.
  2. Do not forget that Mobile Atlas Creator is a GPL project - therefore publishing the source code together with the binary release should went without saying.
  3. If your modification is useful you may consider to present it to the Mobile Atlas Creator development team. Patches are always welcome. Useful modifications have a great chance to be integrated into the main branch.

Map sources and map packs

Since version v1.9 map sources are no longer part of Mobile_Atlas_Creator.jar. All map sources implementation are located in jar files in the mapsources sub-directory. Those map sources implementation packages are called "map-packs". Map packs files always starts with the term mp- and they end with the term .jar.

For implementing new map sources in a development environment like Eclipse it is sometimes faster to load the map sources directly from class-path rather from the map-packs. You can enable it by setting devmode in settings.xml to true. Afterwards map sources will be loaded directly from the bin directory of Eclipse (if available).

Developing a custom map pack

For creating your own custom map pack you have to create a new Java package below mobac.mapsources.mappacks. For example lets assume that the name of the new map pack should be mymappack. Therefore you have to create the package mobac.mapsources.mappacks.mymappack. Place all Java source files within this package (sub-packages are also possible).

Additionally you have to create a text file named mapsources.list inside the package mobac.mapsources.mappacks.mymappack. This file contains a list of class names (full class name including the package name, one per line) that should be loaded by MOBAC as map source.

Background: During the build process this file will be included into the map-pack jar as META-INF/services/mobac.program.interfaces.MapSource so that it can be found by the ServiceLoader.

Building the map pack

Map packs can be built separately using Apache Ant and the build target build_mapsources:

ant build_mapsources

Apache Ant is already included in Eclipse, so that you only have to select the file build.xml, press the right mouse button and select Run As - Ant Build.... In the dialogs that opens deselect the build target all and select instead build_mapsources.

Each sub-package of mobac.mapsources.mappacks will be compiled and packed to an map package. The created map packages are saved into the mapsources directory. Therefore our example map pack will be packed into the file mapsources/mp-mymappack.jar

Source code overview - important packages

mobac.gui

This package contains the implementation of all dialogs/windows. In the sub-packages you can find the related implementations of used graphical components - e.g. mobac.gui.mapview.PreviewMap - the component that draws the movable map background used by Mobile Atlas Creator.

mobac.mapsources

Holds the infrastructure and the implementation of all map sources available within Mobile Atlas Creator. For implementing own map sources that uses an online map you should derive your map source from the abstract base class mobac.mapsources.AbstractHttpMapSource. Map sources should be compiled and packed to a map pack so that they can be automatically detected and loaded while MOBAC is starting-up. For details on that topic please read section Developing a custom map pack.

mobac.program.atlascreators

Holds the implementations of all atlas creators (atlas output formats) provided by Mobile Atlas Creator. Each class in the package implements exactly one atlas output format. Of special interest is the abstract class AtlasCreator which is the super class every atlas creator is derived of. The list of available formats is maintained in the enumeration mobac.program.model.AtlasOutputFormat.

mobac.tools

This package contains additional stand-alone tools that are not shipped with the Mobile Atlas Creator binary release. For example the mobac.tools.MapSourcesTester downloads one tile from each map source for verifying that the map source is functional.

Participation

If you are familiar with the programming language Java and you want to contribute or participate in the development process of Mobile Atlas Creator feel free to contact one of the other developers of Mobile Atlas Creator listed at SourceForge.

mobile-atlas-creator-1.9.14+dfsg1/CHANGELOG.txt0000644000175000017500000007166712175453754020612 0ustar paulliupaulliu******************************************************************************* * M O B I L E A T L A S C R E A T O R * ******************************************************************************* * V E R S I O N I N F O R M A T I O N * ******************************************************************************* + = Additions since previous version ! = Bug fixes since previous version ~ = Changes since previous version - = Features that has been removed ======= 1.9.14 (2013-07-29) ~ Custom SQlite map sources can now be specified using a relative path ~ BackCountry Navigator format updated - now SQLite based atlases are created + Japanese translation added (thanks to "u/ta-ka") [patch #33] ! Not translated tooltip corrected [patch #34] ! A problem with MapSourceInitializationException fixed (#245) ! Memory leak fixed in "TwoNav (RMAP)" atlas format causing an OutOfMemoryError when creating a large atlas 1.9.13 (2013-05-29) ! HTML injection via Atlas name bug #242 ! Workaround for Java bug in JPEG writer (if source image has alpha transparency) implemented + French translation added (thanks to Jean-Claude Repetto) [patch #31] 1.9.12 (2013-04-17) ! Mapsource OpenStreetMap Maps4u.eu updated ~ Reduced the number of decimal places of coordinates in GPX files created by MOBAC to 5 places (#242) + Custom multi-layer map sources: Each layer can now have an alpha transparency value, specified as space separated list in element ! Bufix of conversion between different coordinate formats (degree, deg/min, deg/min/sec) ~ localImageFile support using (patch by miocool) ~ More atlas format support retina (scale = 2) images, including Paper(PNG), Paper(pdf). (patch by miocool) ! More atlas format can display retina (scale = 2) images correctly (convert to scale = 1), such as iPhone v5 (patch by miocool) + Add map source support (patch by miocool) ! Bug fix of 512x512 map tile images in Multiple layer (patch by miocool) + Multiple language for Simplify-Chinese, Traditional Chinese and English (patch by miocool) + View 512x512 map tile images for retina display (patch by miocool) 1.9.11 (2013-02-19) ! Bugfix for servers that send case insensitive content-types ! Bugfix OruxMapsSQlite final commit was missing (patch #30) + New map sources: USGS National Map Base/Satellite/Satellite+/Vector/Topo ! Bugfix Garmin Custom Map: Removed possibility to set output format to PNG 1.9.10 (2012-12-04) ! Bugfix Local tile [zip] files in quadkey format causes a NullPointerException when creating an atlas (#229) + Custom multi-layer map source can now contain maps 1.9.9 (2012-10-09) ! Bugfix in PNGW calibration (patch by allib) ! RMAPS: Error "failed to retrieve max tile zoom info" fixed (#3561323) ! GEMF: Error "NullPointerException" fixed (#3564146) ~ OruxMaps: Patch #3300055 applied + Custom XML map: now works in simple XML map, too + Loading multiple GPX files at once into MOBAC (based on patch by heckie) ! Bugfix NullPointerException when aborting atlas download fixed (#3568849) + Automatically splitted maps because of the specified maximum map size can now overlap 1-5 tiles 1.9.8 (2012-07-05) ! Viewranger atlas format depends on Java Advanced Imaging without checking ! OurxMaps SQLite: Memory handling changed (should prevent OutOfMemoryError) ! Fixed progress bar in atlas progress window for large atlases + Possibility added to use SQLite Java Wrapper (ch-werner) instead of default sqlite library ~ Replaced the old SQLite library with recent version of Xerial. This fixes all problems creating databases larger than 2GB on Windows 64bit ! CacheWolf: Custom tile processing re-enabled + New atlas format: iPhone 3 Map Tiles v5 1.9.7 (2012-05-16) + Custom XML map source: New parameter {$q} for Quad-Tree encoded zoom, x & y + New atlas output format: Osmdroid GEMF + Increased default map size to 65536 1.9.6 (2012-04-02) + New settings.xml option: + New atlas format: TomTom raster - Map source removed: Openstreetmap Osmarenderer (project has been retired) ! Paper atlas: Disabling compass in settings was ineffective + New map source: OpenStreetMap 4uMaps.eu (Europe) + backgroundColor option for customMultiLayerMapSource ! Message "The JPEG image format is not supported by OpenJDK." was shown at start-up even is custom tiles processing was disabled + New atlas format: Viewranger ~ Magellan (RMP): Removed 18000 pixel check 1.9.5 (2012-03-09) ! Alpine Quest Map: Multiple bugs fixed (#3484328) ~ Improvements in atlas download progress dialog (patch by dvodvo) ~ Windows launcher "Mobile Atlas Creator.exe" increased max heap size to 1GB ~ Linux start.sh increased max heap size to 1GB + New selection mode: Circle (approximated by a 16 point polygon) + New map source: OSMapa-Topo with contours (PL) 1.9.4 (2012-01-29) + BeanShell map source: ignoreError=true feature added + Debug menu: Show/hide map tile borders 1.9.3 (2011-12-01) + Custom map source from local tiles XML schema changed: new values: DIR_ZOOM_X_Y, DIR_ZOOM_Y_X, QUADKEY removed flipXYDirs (use DIR_ZOOM_Y_X instead ! Custom map source from ZIPs: Handling for atlas types with two file extensions fixed ! Bugfix Osmdroid SQlite: PRIMARY KEY must be unique (#3438206) ~ Turaterkep map updated (renamed internally to Turaterkep256 because of map format change) + Support added for starting external tools from within MOBAC 1.9.2 (2011-10-12) + Custom map source from ZIP/files in file-system: added possibility to invert y coordinate via "invertYCoordinate" like it is used by MapTiler + New settings.xml option: (default 1). Allows to reduce or increase the maximum attempts MOBAC tries to download a tile in case of errors occur while download or HTTP response is not as expected. + Logging verboseness now configurable for the current session via GUI ! PaperAtlas: NullPointerException when WGS Grid=off has been fixed + CustomSQLite atlas as map source: OSMAND format added + New atlas output format: OSMAND SQLite 1.9.1 (2011-09-09) ! Opening settings dialog: ClassCastException on Linux/OpenJDK ! Custom SQlite atlas as map source fixed for atlas formats AndNav, BackCountry Navigator and Osmand + Background color for BeanShell map sources can be specified by adding backgroundColor = "#ffffff"; ! Custom SQLite atlas as map source had an undefined tileImageType; Added auto-detection and user defined 1.9 (2011-08-18) ! Calculation problem in MGMaps atlas format (fix by Pierre-Luc Paour) ! Custom mapsource from RMaps SQLite atlas shows wrong zoom levels - Removed map source: Open Cycle Map (request by Andy Allan) + New map source: OSMapa-Topo (Poland) + Map source tile store coverage: button for hiding colored layer added + OziExplorer/Trekbuddy: MM1B calculation improved (patch by MrPete #3026830) + Custom XML map source: {$serverpart} / implemented for balancing load among multiple servers with different DNS names + SQLite library included in MOBAC distribution 1.9 beta 6 (2011-06-21) + New atlas format: Geocaching Live offline maps + New atlas format: MBTiles (Experimental) + New atlas format: Paper Atlas (PDF) & Paper Atlas (PNG) [provided by Ľubomír Vasek] ! Bug #3316081 - "String index out of range: -1" upon map sources update ! Incorrect selection and tile count calculation + New map source: Moldova (point.md) 1.9 beta 5 (2011-05-17) + Added possibility change directory syntax for file and zip based map sources from zoom/x/y to zoom/y/x ("flipXYDir") + Added possibility to use and within a custom multi-layer map source ! CustomMultiLayerMapSource: "null" error when loading ! directories.ini: mobac.atlasprofilesdir not used for loading profiles list + directories.ini: System variables can be used in the form ${VARNAME} + Local map sources from SQLite atlases can now be used - supported formats are RMaps, MBTiles, BigPlanetTracks, Galileo, NaviComputer ! Fixed OpenStreetMap Cycle Map + Experimental: adding user-defined polygon maps ~ Changed polygon selection behavior - selection stays now after adding it 1.9 beta 4 (2011-05-02) ~ Problem loading tile image type for custom map sources (ends up for TrekBuddy atlas format in an NullPointerException like in bug #3290976 ~ Settings dialog now lists all tile stores - not only the stores of loaded map sources + Experimental: Polygonal map derived from GPX track segment ! Endless opening of exception dialog (endless recursion) 1.9 beta 3 (2011-04-21) + Map source UMP-pcPL reactivated + [Nokia] Sports Tracker file extension changed to jpg (feature request #3066161) + Reactivated atlas format "TwoNav (RMAP)" + New map source: FAA Sectional Charts (aeromaps.us) + Reactivated map sources Freemap.sk (Car atlas, Hiking map, Cycle map) + Map source New Zealand Topographic Maps (nztopomaps.com) reactivated ! OruxMapsSQLite: Last processed tiles missing in db file 1.9 beta 2 (2011-04-06) ! Custom atlas map source / locally generated tiles map source + New map source for using tiles from zip file(s) + Removed all map sources except the OSM related - for details see http://sourceforge.net/projects/mobac/forums/forum/861096/topic/4470412 1.9 beta 1 (2011-03-29) + New map source: OpenStreetMap MapQuest + New map source: OpenStreetMap Bing layer (Mapnik powered by Microsoft) ~ Maximum zoom level of OpenStreetMap Mapnik decreased to 16 (zoom levels 17+ are blocked on server side because of high server stress for generating such tiles) + New custom map source type: reading tiles offline from an OSMTracker/AndNav/ BackCountry Navigator/Maverick/OSMAND atlas (from file system) ~ Atlas format PNG+Worldfile: projection file for Arcgis added and calculation improved (patch by user mmartin2) ~ JPEG compression level selectable for Magellan (RMP) atlas format 1.9 preview 14 (2011-03-17) + Osmdroid SQLite: Tile image format conversion implemented - Osm Hiking maps removed (excluding the "Wanderreitkarte Abo" version) - Outdooractive.com maps removed as requested by map provider 1.9 preview 13 (2011-03-12) + Download to tile store without creating an atlas: new atlas format "Tile store download only" ! BeanShell map sources could not be used with certain atlas formats + New map source: Israel Topo (Amudanan) with and without trails 1.9 preview 12 (2011-03-05) ~ Cykloatlas: max zoom level extended to 16 + New map source: Canada Toporama + Convert an existing atlas profile to a different output format ! Loading of custom CloudMade maps fixed 1.9 preview 11 (2011-03-02) ! Error when using a BeanShell map source with certain atlas formats - Removed Map+ map sources because of license problem with swisstopo 1.9 preview 10 (2011-02-28) ! Fixed map source: Docelu.pl + Bookmarks can be added (saves map position and selected map source) ! Fixed map source: Cykloatlas and relief ! Fixed map source: Map+ (Switzerland) + New map source: Map+ Gelände (Switzerland) + New atlas format: nfComPass 1.9 preview 9 (2011-02-22) + New map source: Reit- und Wanderkarte (Abo) - (requires purchased ticket) ~ Updated New Zealand Topographic Maps url ! OpenStreetMap attribution + MOBAC user aget 1.9 preview 8 (2011-02-16) + NaviComputer: Possible to change tile image format (PNG, 4Bit-PNG, JPEG, ...) + OpenPisteMap: All three layers (base, contours and landshed are now supported) - Disabled TwoNav RMAP output format because of legal/license problems 1.9 preview 7 (2011-02-04) + OSM Hiking ticket system implemented (Wanderreitkarte.de) ! NoSuchMethodError: mobac.program.ProgramInfo.getUserAgent()Ljava/lang/String; 1.9 preview 6 (2011-02-04) ! Custom tile size was not available for TrekBuddy and Glopus GFM ~ Tile usage policy implemented for OSM Mapnik 1.9 preview 5 (2011-01-21) + New map source: ICAO Maps (Germany) + Manual map pack online update via settings dialog + Add selection via Ctrl+A key combination possible (see "Maps" menu) 1.9 preview 4 (2011-01-14) + New: Support for CustomWmsMapSource (experimental) + Download bandwidth limitation selectable for very fast network connections ! Highest zoom level missing in tile store coverage zoom selector + New atlas format: OsmdroidSQlite + New map sources: ArcGIS topo map/satellite/street map 1.9 preview 3 (2011-01-09) + New atlas format: PNG + Worldfile (PNG & PGW) ~ Atlas output format has to be chosen before adding maps ~ Disabling of unsupported tile processing options (regarding the current atlas format) ~ Enabled maps with ellipsoid projection for RMaps 1.9 preview 2 (2010-12-18) + New atlas format: BackCountry Navigator + New atlas format: TwoNav (RMAP) + Multi-layer maps with more than two layers are now possible + New map source: OSM Hiking with relief and base + New map source: Open Sea Map (sea layer joined with Mapnik) + New atlas format: MGMaps/MyTrails (MGM) + New map source: Topomapper.com ~ Map sources are now packed into "MapPacks" which can be updated without changing the main MOBAC program ~ Custom map sources are moved from settings.xml into separate xml files in the "mapsources" sub-directory ~ XML structure of multi-layer custom maps sources has changed + Multi-layer maps can now contain map sources that come with MOBAC This allows to combine existing map sources with new overlays. + BeanShell map sources can be used if placed in the "mapsources" sub-directory + All direcories used by MOBAC can be pre-configured via file directories.ini in the MOBAC program directory + CustomMap: new parameter: ignoreErrors and backGroundColor can have alpha transparency parameter + New map source: Cloudmade Map default style (1) + Tile image format conversion for RMaps/BigPlanet/Galileo 1.8 final: (2010-10-31) + New map source: New Zealand Topographic Maps 1.8 RC 1: (2010-10-23) + AlpineQuest handles tiles <> 256px and ellipsoid projections + New atlas format: Run.GPS Atlas ! Fixed map source: Emapi.pl 1.8 beta 4: (2010-10-09) ~ Implemented logging for ImageWriter warnings ~ Display selected areas: adding a new map selection does no longer resets the map selection and therefore the highlighted area does not change. 1.8 beta 3: (2010-10-02) ! Fixed: NullPointerException when renaming an GPX file entry ! MyTopo URL updated and fixed ~ Unnecessary restriction of RMaps / BigPlanet Tracks to zoom 17 removed + New map source: Microsoft Maps with hill shade ~ Custom tile settings now possible with SportsTracker + New atlas format: Osmdroid ZIP + New map source: SIGPAC Mercator (Spain only) - patch by susinho 1.8 beta 2: (2010-09-13) + AlpineQuestMap atlas creator updated (patch by Camille) + New map source: Navitel (Russian) ! GPS Sport Tracker: space removed in tile file name ! MyTopo URL updated 1.8 beta 1: (2010-08-24) ! Fixed PNG 256 color output + New atlas format: OruxMaps (Android) + New atlas format: Glopus Map File (AFTrack and others) ~ BigPlanet SQL commit rate changed ! #2963490 Using custom tile size with multi-layer maps creates black map tiles + GPX file editor improved ~ Austrian Map removed (does not work anymore - unable to fix) + Yandex Map & Sat added (works only with selected atlas creators because of a different projection category - Yandex uses an ellipsoid) ~ Map source change: Emapi.pl replaces Emapa.pl + New atlas format: PathAway ! Alpha transparency problem with multi-layer maps + New atlas format: AFTrack (OSZ) ~ CacheBox layer name uses now the map source name + New atlas format: AlpineQuestMap (AQM) + New atlas format: Ublox ! Fixed OSM Hiking relief + New map source: Cykloatlas with relief + Custom Map Sources extended to multi-layer map source (2 layers) + New map source: Statkart sea/nautical (AKA "sjo_hovedkart2") ~ TouretechQV: Corrected "projparams" (removed unset UTM zone) - see #2970353 + New atlas format: Google Earth Overlay (unrestricted Google Custom Map) ! Fixed: #3008934 (MM1B calculation problem in .map file) + New map source: MyTopo.com (USA only) + New map source: Yahoo Maps Japan + New atlas format: GPS Sports Tracker + New atlas format: Sports Tracker + New map source: OSM Hikebikemap.de + Background color for custom maps added ~ Freemap.sk maps updated and changed + New atlas format: Maplorer + New map source: Yahoo Taiwan + New map sources: Aero Charts VFR/IFR/IFR-H (USA only from runwayfinder.com) + New atlas format: OruxMaps Sqlite + New map source: Ordnance Survey Explorer Maps (UK) + Proxy authentication by user name/password added in GUI + New atlas format: OSMAND ~ SQLite back-end replaced - Zentus SqliteJDBC is now used (see README.HTM for details) ! OpenPisteMap tile url updated + New atlas format: NaviComputer 1.7: (2010-02-05) ~ Project has been renamed to "Mobile Atlas Creator" taking account that besides TrekBuddy a large number of atlas and map formats are supported and for ending the mix-up of "TrekBuddy" and "TrekBuddy Atlas Creator" ~ Tiles tore now uses database (BerkelyDB) instead of tile files in file system + Old tiles saved in the tile store are checked and updated when used (displayed in map view or used in an atlas). Updating is done via expiration settings - those provided by the server or otherwise user specified. + Atlas output directory can be specified via settings dialog + AndNav and OSMTracker: Tile format conversion (JPG <->PNG) implemented including color reduction ~ Docelu.pl can update it's base URL like the Google map sources do ~ Pause/resume button now works while map creation (not only while download) + New experimental map source: Turaterkep (Hungary hiking) Uses tiles of size 512x512 (not supported by all atlas formats) + Multi-layer map sources such as Google Hybrid or OSM Hiking with relief background can be used with all atlas creators + New map: NearMap Australia (high-resolution aerial images for Australia) ! GPX addWpt: Multiple way points added by one mouse click fixed ! Start.sh/Start.cmd Java max heap setting was ignored by Java because of the position at the end of the command line ! #2904937 and #2905182 1px map calibration bug + New map source: Humbermedia Bavaria + New atlas format: Mobile Trail Explorer Cache (writes single MTECache file per atlas) + New map sources: (Norway) Statkart Topo2, Toporaster2 (limited to 10.000 tiles per day and IP) + Drag & Drop for maps in "Atlas content" tree + New atlas format: Magellan RMP / VantagePoint + New atlas format: Touratech QV ! Fixed #2913874: ArrayIndexOutOfBoundsException in PNG 4-bit writer + New map source: Eniro.com map/aerial/nautical (Sweden, Norway, Finland) + Checkbox added in atlas progress dialog for ignoring all download errors + New atlas format: CacheWolf (as one large 24bit png + WFL or tiled with multiple WLF files using the configured image format and tile size) + New map source: Mapplus.ch (Switzerland) + Coordinate format changeable ("deg" / "deg,min" / "deg,min,sec") + New atlas format: CacheBox + New atlas format: Garmin Custom Map Image downscaling uses bilinear filter (improves image quality) + Each map source has now a background color (usually black) that is used in case of missing tiles + Content-type check after download (HTTP header and image data header) + New map source: Ovi/Nokia Maps + New map source: Bergfex (Austria) ! Grid paint juddering on high zoom levels fixed ~ OpenStreetMap Hiking updated 1.6.1: (2009-10-30) ! Loading and saving of GPX failed 1.6: (2009-10-27) + Loading & saving of GPX 1.1 files (way- track- and routepoints are displayed as overlay) + GPX 1.0 files are automatically transformed to GPX 1.1 file on load + Route and tracks are painted as connected line + Add new way points to a GPX file (properties: lat, lon, name) + Map scale bar added (metric/imperial selectable) + New atlas format: Mobile Trail Explorer (MTE) + New atlas format: RMaps / BigPlanet SQLite (Android applications, requires additional SQLite libraries) + New atlas format: OSMTracker + New map source: OpenStreetMap Public Transport (öpnvkarte.de) + New map source: AustrianMap (z14 & z15 of www.austrianmap.at) [provided by Guenther Hoelzl] + New map sources: Freemap Slovakia (normal, hiking & hiking plus hill shade) + New map sources: Google Maps Korea + New map sources: Open Piste Map (openpistemap.org) + New atlas format: Maverick (Android application) + New map sources: Emapa.pl (Poland) + New atlas format: Glopus (PNG & KAL) + New map sources: Outdooractive.com Austria and South Tyrol ~ Max zoom level of Google Maps increased from 17 to 19 ~ Behavior on adding new maps and layers changed: the number of layers has been reduced to a minimum making it easier switch between different zoom levels when using TrekBuddy ! Extreme performance break-in in grid-mode fixed ! Map selections do no longer unwanted enlarge itself in grid mode beyond the selected grid 1.5: (2009-08-01) + Flexible atlases containing different areas of multiple map sources are possible + New atlas output format: AndNav - Android Navigation System http://www.andnav.org + Atlas download can be paused/resumed interactively + Proxy settings rewritten - now system/Java wide or application settings can be used alternatively to the user defined proxy + New regional map sources (Poland): ump.waw.pl and docelu.pl + Map sources can now be disabled which hides them from the list + Merging different layers via drag & drop + Custom map sources can be defined via settings.xml (see README.HTM) + Map sources manual online update via settings dialog + New atlas format: OziExplorer / large PNG export ~ Java requirement has changed: Now at least Java 1.6 is required! ~ Profile saving updated to new atlas structure ~ Fullscreen mode is currently unavailable ~ Google Maps, Earth, Mapmaker, Maps China url updated ~ Settings.xml format has changed ~ Max zoom for Cycloatlas changed from 14 to 15 ~ Removed OpenArialMap map source ~ Panels on the left can be collapsed to save space ! Editing the atlas content while map creation in progress resulted in unusable/abnormal atlases (see bug #2819613) 1.1: (2009-05-13) + New output format: JPEG with different quality levels + added map source Microsoft Maps China (Ditu) ~ Fixed url and name of Cykloatlas (fixes also bug #2755108) ~ Updated url of Google Map Maker & Earth ~ Fixed tar creation which had problems with default charset on some systems ~ Changed the color depth selector to an output format selector ~ OSM Hiking map moved to new server - url adapted ! "Open atlas folder" does now work on Linux (Gnome and may be Kde) 1.0: (2009-04-10) + Reload current map view by pressing "F5" + First experimental implementation of color reducing implemented (requires additional library "Java Advanced Imaging": https://jai.dev.java.net/binary-builds.html Download the library and place the Jar[s] in the same directory as TrekBuddyAtlasCreator + Experimental: Color reduced (<16) png files are saved using an own implementation that writes real 4 bit PNG files (instead to the default Java one that only creates 8 bit or true color files) + added map source OSM hiking: http://opentiles.com/nop/ + added map source OpenArialMap ~ Maximum map size reduced to 32767 (1 pixel less) ~ Atlas output format can now be specified: Tared or untared atlas. The created atlas is always created in the folder "atlases" - the folder "atlasestared" is no longer used. ~ "ozi" / "tac_tmp" directory no longer used. Instead one temporary tar file per map layer is created (and later deleted) in the default system temp directory ~ fixed GoogleMapMaker map source ! Loading tile store information in settings dialog blocked GUI 0.9.7: (2009-03-05) + New map sources (full support): Microsoft Maps, Earth, Hybrid, Cycloatlas (Czech Republic only) + New map sources (partial support): Multimap.com + Window position, size and state (maximized or not) is saved + Preview map allows zoom move/zoom via keyboard controls (patch by Martin Loetzsch) + Fullscreen mode hides left panel and places control inside the preview map (patch by Martin Loetzsch) ~ Google Maps, Earth & MapsChina urls updated ~ Custom tile size selection controls combined ~ Fixed several Swing thread safety problems (patch by Martin Loetzsch) 0.9.6: (2009-01-08) + New map source: Google Terrain + Download error counter added to atlas progress dialog ! Updated OpenCycleMap url (fixes zoom level > 13) + New map source: Yahoo Maps + New map source: Google Maps China (Ditu) + New map source (Germany only): Outdooractive.com + Selected/entered tile size is now saved/restored in/from settings.xml + Tooltip of "tiles-to-download-counter-label" (located right to the label "Zoom levels (..)") now shows the breakdown of the number of tiles to the different zoom levels including the area calculation ~ Exceptions that occur while downloading/creating an atlas are now displayed in an dialog showing detailed information about the system and the exception ~ Updated Google Maps url & removed "Galileo" appendix ~ New experimental implementation for creating tile of custom size. Disdvantage: Much slower that the algorithm before Advantage: Only constant memory needed (approx. less than 10 MB) ~ Using custom tile size now does not concert the tiles to png format. Instead the format used by the maps source is used. 0.9.5: (2008-10-27) + Detailed log files can be created by providing a configuration file log4j.xml (see README.txt for details). + HTTP Proxy (host & port) can be specified via GUI + Added information about amount of tiles and total size for each tile source store in Settings window. + Multithreaded download of tiles implemented (number of parallel download threads changeable via settings dialog ~ Tile download system now reuses HTTP connections for HTTP 1.1 servers instead of opening a new TCP connection for each tile ! Selection of whole world resulted in a wrong max longitude (-180 instead of 180) ! Tile number and index calculations near to the border of the world corrected ! Saving profiles works now (including map source, zoom levels and tile size) ! Aborting of stalled downloads works now as expected 0.9.1: (2008-10-17) ! Fixed wrong calculation of number of tiles when the amount was large. 0.9 alpha: (2008-10-15) + Added resizeable GUI + Added possibility to select map area by selection an area with mouse + Added tmi files for the tared atlases which make the map loading faster ~ Changed preview viewer to JMapViewer. It has several advantages: different map sources preview loads in background automatically easy zooming (mouse wheel) and movement (right mouse button) ~ Tar generation rewritten, each tar is now only opened one time, not once for each tile to be added (increases tar creation in case of a virus scanner being active) 0.8: + Added xml based settings file via Java Properties + Added possibility to change tile size for the downloaded tiles. + Added possibility to set map size in atlas. Giving the possibility to create large atlases ! Fixed the non working setting tile store enabled. It was always enabled, despite of what was written in the settings file ! Fixed (hopefully) the generation of mixed up atlases at some Linux operating system(s). ! Fixed bugs related to defect profiles in profiles.xml file by adding some validation of the xml data at application start. 0.7: + Added possibility to abort an ongoing download of Atlas + Added label that shows how many tiles that will be downloaded with current lat, long & zoom settings + Added persistent tile store (cache of tiles in a store which is persistent between program sessions) ! Fixed wrong download link to ditu.google.com 0.61: + Added a possibility to select to download tiles from either ditu.google.com or maps.google.com ! Fixed hard coded look and feel, which resulted in an javax.swing.UnsupportedLookAndFeelException at other environments then Windows