gpxedit on the rails
|
@ -0,0 +1,4 @@
|
|||
# Authors
|
||||
|
||||
* Julien Veyssier <eneiluj@gmx.fr> (Developper)
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
# Change Log
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## [Unreleased]
|
|
@ -0,0 +1,661 @@
|
|||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
Version 3, 19 November 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
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 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
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If your software can interact with users remotely through a computer
|
||||
network, you should also make sure that it provides a way for users to
|
||||
get its source. For example, if your program is a web application, its
|
||||
interface could display a "Source" link that leads users to an archive
|
||||
of the code. There are many ways you could offer source, and different
|
||||
solutions will be better for different programs; see section 13 for the
|
||||
specific requirements.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
|
@ -0,0 +1,80 @@
|
|||
# GpxPod owncloud/nextcloud application
|
||||
|
||||
If you want to help to translate this app in your language, take the english=>french files in "l10n" directory as examples.
|
||||
|
||||
This app's purpose is to display gpx, kml and tcx files collections,
|
||||
view elevation profiles and tracks stats, filter tracks,
|
||||
color tracks by speed, slope, elevation and compare divergent parts of similar tracks.
|
||||
|
||||
It's compatible with SQLite, MySQL and PostgreSQL databases.
|
||||
|
||||
It works with gpx/kml/tcx files anywhere in your files, files shared with you, files in folders shared with you.
|
||||
kml and tcx files will be displayed only if GpsBabel is found on the server system.
|
||||
|
||||
Elevations can be corrected for entire folders or specific track if SRTM.py (gpxelevations) is found.
|
||||
|
||||
Personal map tile servers can be added.
|
||||
|
||||
It works with encrypted data folder (server side encryption).
|
||||
|
||||
A public link pointing to a specific track can be shared if the corresponding gpx file is already shared by public link.
|
||||
|
||||
!!! GpxPod now uses the owncloud database to store meta-information. If you want to get rid of the .geojson, .geojson.colored and .markers produced by previous versions, there are two buttons at the bottom of the "Settings" tab in user interface. !!!
|
||||
|
||||
GpxPod proudly uses Leaflet with lots of plugins to display the map.
|
||||
|
||||
This app is tested under Owncloud/Nextcloud 9.0/10 with Firefox and Chromium.
|
||||
This app is under development.
|
||||
|
||||
Link to Owncloud application website : https://apps.owncloud.com/content/show.php/GpxPod+again?content=174733
|
||||
|
||||
## Install
|
||||
|
||||
No special installation instruction except :
|
||||
!! Server needs python2.x or 3.x "gpxpy" and "geojson" module to work !!
|
||||
They may be installed with pip.
|
||||
|
||||
For example, on Debian-like systems :
|
||||
|
||||
```
|
||||
sudo apt-get install python-pip
|
||||
sudo pip install gpxpy geojson
|
||||
```
|
||||
or on Redhat-like systems :
|
||||
```
|
||||
sudo yum install python-pip
|
||||
sudo pip install gpxpy geojson
|
||||
```
|
||||
|
||||
Then put gpxpod directory in the Owncloud/Nextcloud apps to install.
|
||||
There are several ways to do that :
|
||||
|
||||
### Clone the git repository
|
||||
|
||||
```
|
||||
cd /path/to/owncloud/apps
|
||||
git clone https://gitlab.com/eneiluj/gpxpod-oc.git gpxpod
|
||||
```
|
||||
|
||||
### Download from apps.owncloud.org
|
||||
|
||||
Extract gpxpod archive you just downloaded from apps.owncloud.org :
|
||||
```
|
||||
cd /path/to/owncloud/apps
|
||||
tar xvf 174733-gpxpod-1.0.0.tar.gz
|
||||
```
|
||||
|
||||
### Post install precautions
|
||||
|
||||
Just in case, make python scripts executables :
|
||||
```
|
||||
cd /path/to/owncloud/apps
|
||||
chmod +x gpxpod/*.py
|
||||
```
|
||||
|
||||
## Known issues
|
||||
|
||||
* bad management of file names including simple or double quotes
|
||||
* _WARNING_, kml conversion will NOT work with recent kml files using the proprietary "gx:track" extension tag.
|
||||
|
||||
Any feedback will be appreciated.
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
/**
|
||||
* ownCloud - gpxEdit
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later. See the COPYING file.
|
||||
*
|
||||
* @author Julien Veyssier <eneiluj@gmx.fr>
|
||||
* @copyright Julien Veyssier 2015
|
||||
*/
|
||||
|
||||
namespace OCA\GpxEdit\AppInfo;
|
||||
|
||||
use OCP\AppFramework\App;
|
||||
|
||||
$app = new Application();
|
||||
$container = $app->getContainer();
|
||||
|
||||
$container->query('OCP\INavigationManager')->add(function () use ($container) {
|
||||
$urlGenerator = $container->query('OCP\IURLGenerator');
|
||||
$l10n = $container->query('OCP\IL10N');
|
||||
return [
|
||||
// the string under which your app will be referenced in owncloud
|
||||
'id' => 'gpxedit',
|
||||
|
||||
// sorting weight for the navigation. The higher the number, the higher
|
||||
// will it be listed in the navigation
|
||||
'order' => 10,
|
||||
|
||||
// the route that will be shown on startup
|
||||
'href' => $urlGenerator->linkToRoute('gpxedit.page.index'),
|
||||
|
||||
// the icon that will be shown in the navigation
|
||||
// this file needs to exist in img/
|
||||
'icon' => $urlGenerator->imagePath('gpxedit', 'app.svg'),
|
||||
|
||||
// the title of your application. This will be used in the
|
||||
// navigation or on the settings page of your app
|
||||
'name' => $l10n->t('GpxEdit'),
|
||||
];
|
||||
});
|
|
@ -0,0 +1,88 @@
|
|||
<?php
|
||||
/**
|
||||
* ownCloud - gpxedit
|
||||
*
|
||||
*
|
||||
* @author
|
||||
*
|
||||
* @copyright
|
||||
*/
|
||||
|
||||
namespace OCA\GpxEdit\AppInfo;
|
||||
|
||||
|
||||
|
||||
use OCP\IContainer;
|
||||
|
||||
use OCP\AppFramework\App;
|
||||
use OCP\AppFramework\IAppContainer;
|
||||
|
||||
use OCA\GpxEdit\Controller\PageController;
|
||||
use OCA\GpxEdit\Controller\ComparisonController;
|
||||
use OCA\GpxEdit\Controller\UtilsController;
|
||||
|
||||
/**
|
||||
* Class Application
|
||||
*
|
||||
* @package OCA\GpxEdit\AppInfo
|
||||
*/
|
||||
class Application extends App {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $urlParams
|
||||
*/
|
||||
public function __construct(array $urlParams = []) {
|
||||
parent::__construct('gpxedit', $urlParams);
|
||||
|
||||
$container = $this->getContainer();
|
||||
|
||||
/**
|
||||
* Controllers
|
||||
*/
|
||||
$container->registerService(
|
||||
'PageController', function (IAppContainer $c) {
|
||||
return new PageController(
|
||||
$c->query('AppName'),
|
||||
$c->query('Request'),
|
||||
$c->query('UserId'),
|
||||
$c->query('ServerContainer')->getUserFolder($c->query('UserId')),
|
||||
$c->query('ServerContainer')->getConfig(),
|
||||
$c->getServer()->getShareManager()
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
$container->registerService(
|
||||
'ComparisonController', function (IAppContainer $c) {
|
||||
return new ComparisonController(
|
||||
$c->query('AppName'),
|
||||
$c->query('Request'),
|
||||
$c->query('UserId'),
|
||||
//$c->getServer()->getUserFolder($c->query('UserId')),
|
||||
//$c->query('OCP\IConfig'),
|
||||
$c->query('ServerContainer')->getUserFolder($c->query('UserId')),
|
||||
$c->query('ServerContainer')->getConfig()
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
$container->registerService(
|
||||
'UtilsController', function (IAppContainer $c) {
|
||||
return new UtilsController(
|
||||
$c->query('AppName'),
|
||||
$c->query('Request'),
|
||||
$c->query('UserId'),
|
||||
//$c->getServer()->getUserFolder($c->query('UserId')),
|
||||
//$c->query('OCP\IConfig'),
|
||||
$c->query('ServerContainer')->getUserFolder($c->query('UserId')),
|
||||
$c->query('ServerContainer')->getConfig()
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0"?>
|
||||
<info>
|
||||
<id>gpxedit</id>
|
||||
<name>GpxEdit</name>
|
||||
<description>
|
||||
# GpxEdit owncloud/nextcloud application
|
||||
|
||||
Any feedback will be appreciated.
|
||||
|
||||
</description>
|
||||
<licence>AGPL</licence>
|
||||
<summary>Display, analyse, compare and share gpx tracks</summary>
|
||||
<author>Julien Veyssier</author>
|
||||
<author>Fritz Kleinschroth</author>
|
||||
<version>0.0.1</version>
|
||||
<namespace>GpxEdit</namespace>
|
||||
<documentation>
|
||||
<user>https://gitlab.com/eneiluj/gpxedit-oc/wikis/userdoc</user>
|
||||
<admin>https://gitlab.com/eneiluj/gpxedit-oc/wikis/admindoc</admin>
|
||||
<developer>https://gitlab.com/eneiluj/gpxedit-oc/wikis/devdoc</developer>
|
||||
</documentation>
|
||||
<category>tool</category>
|
||||
<category>multimedia</category>
|
||||
<website>https://gitlab.com/eneiluj/gpxedit-oc</website>
|
||||
<bugs>https://gitlab.com/eneiluj/gpxedit-oc/issues</bugs>
|
||||
<screenshot></screenshot>
|
||||
<dependencies>
|
||||
<php min-version="5.6"/>
|
||||
<owncloud min-version="9.0" max-version="10" />
|
||||
<nextcloud min-version="9.0"/>
|
||||
</dependencies>
|
||||
<ocsid></ocsid>
|
||||
</info>
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
/**
|
||||
* ownCloud - gpxedit
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later. See the COPYING file.
|
||||
*
|
||||
* @author Julien Veyssier <eneiluj@gmx.fr>
|
||||
* @copyright Julien Veyssier 2015
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create your routes in here. The name is the lowercase name of the controller
|
||||
* without the controller part, the stuff after the hash is the method.
|
||||
* e.g. page#index -> OCA\GpxEdit\Controller\PageController->index()
|
||||
*
|
||||
* The controller class has to be registered in the application.php file since
|
||||
* it's instantiated in there
|
||||
*/
|
||||
return [
|
||||
'routes' => [
|
||||
['name' => 'page#index', 'url' => '/', 'verb' => 'GET'],
|
||||
]
|
||||
];
|
|
@ -0,0 +1,183 @@
|
|||
<?php
|
||||
/**
|
||||
* ownCloud - gpxedit
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later. See the COPYING file.
|
||||
*
|
||||
* @author Julien Veyssier <eneiluj@gmx.fr>
|
||||
* @copyright Julien Veyssier 2015
|
||||
*/
|
||||
|
||||
namespace OCA\GpxEdit\Controller;
|
||||
|
||||
use \OC_App;
|
||||
|
||||
use OCP\IURLGenerator;
|
||||
use OCP\IConfig;
|
||||
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\RedirectResponse;
|
||||
|
||||
use OCP\AppFramework\Http\ContentSecurityPolicy;
|
||||
|
||||
use OCP\IRequest;
|
||||
use OCP\AppFramework\Http\TemplateResponse;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\AppFramework\Controller;
|
||||
|
||||
function delTree($dir) {
|
||||
$files = array_diff(scandir($dir), array('.','..'));
|
||||
foreach ($files as $file) {
|
||||
(is_dir("$dir/$file")) ? delTree("$dir/$file") : unlink("$dir/$file");
|
||||
}
|
||||
return rmdir($dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive find files from name pattern
|
||||
*/
|
||||
function globRecursive($path, $find, $recursive=True) {
|
||||
$result = Array();
|
||||
$dh = opendir($path);
|
||||
while (($file = readdir($dh)) !== false) {
|
||||
if (substr($file, 0, 1) === '.') continue;
|
||||
$rfile = "{$path}/{$file}";
|
||||
if (is_dir($rfile) and $recursive) {
|
||||
foreach (globRecursive($rfile, $find) as $ret) {
|
||||
array_push($result, $ret);
|
||||
}
|
||||
} else {
|
||||
if (fnmatch($find, $file)){
|
||||
array_push($result, $rfile);
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($dh);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/*
|
||||
* search into all directories in PATH environment variable
|
||||
* to find a program and return it if found
|
||||
*/
|
||||
function getProgramPath($progname){
|
||||
$path_ar = explode(':',getenv('path'));
|
||||
foreach ($path_ar as $path){
|
||||
$supposed_gpath = $path.'/'.$progname;
|
||||
if (file_exists($supposed_gpath) and
|
||||
is_executable($supposed_gpath)){
|
||||
return $supposed_gpath;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function endswith($string, $test) {
|
||||
$strlen = strlen($string);
|
||||
$testlen = strlen($test);
|
||||
if ($testlen > $strlen) return false;
|
||||
return substr_compare($string, $test, $strlen - $testlen, $testlen) === 0;
|
||||
}
|
||||
|
||||
class PageController extends Controller {
|
||||
|
||||
private $userId;
|
||||
private $userfolder;
|
||||
private $config;
|
||||
private $appVersion;
|
||||
private $userAbsoluteDataPath;
|
||||
private $shareManager;
|
||||
private $dbconnection;
|
||||
private $dbtype;
|
||||
private $dbdblquotes;
|
||||
private $appPath;
|
||||
|
||||
public function __construct($AppName, IRequest $request, $UserId,
|
||||
$userfolder, $config, $shareManager){
|
||||
parent::__construct($AppName, $request);
|
||||
$this->appVersion = $config->getAppValue('gpxedit', 'installed_version');
|
||||
$this->appPath = \OC_App::getAppPath('gpxedit');
|
||||
$this->userId = $UserId;
|
||||
$this->dbtype = $config->getSystemValue('dbtype');
|
||||
// IConfig object
|
||||
$this->config = $config;
|
||||
|
||||
if ($this->dbtype === 'pgsql'){
|
||||
$this->dbdblquotes = '"';
|
||||
}
|
||||
else{
|
||||
$this->dbdblquotes = '';
|
||||
}
|
||||
if ($UserId !== '' and $userfolder !== null){
|
||||
// path of user files folder relative to DATA folder
|
||||
$this->userfolder = $userfolder;
|
||||
// absolute path to user files folder
|
||||
$this->userAbsoluteDataPath =
|
||||
$this->config->getSystemValue('datadirectory').
|
||||
rtrim($this->userfolder->getFullPath(''), '/');
|
||||
|
||||
// make cache if it does not exist
|
||||
$cachedirpath = $this->userAbsoluteDataPath.'/../cache';
|
||||
if (! is_dir($cachedirpath)){
|
||||
mkdir($cachedirpath);
|
||||
}
|
||||
|
||||
$this->dbconnection = \OC::$server->getDatabaseConnection();
|
||||
}
|
||||
//$this->shareManager = \OC::$server->getShareManager();
|
||||
$this->shareManager = $shareManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Welcome page.
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
public function index() {
|
||||
$userFolder = \OC::$server->getUserFolder();
|
||||
$userfolder_path = $userFolder->getPath();
|
||||
|
||||
// DIRS array population
|
||||
$all = $userFolder->search(".gpx");
|
||||
$alldirs = Array();
|
||||
foreach($all as $file){
|
||||
if ($file->getType() === \OCP\Files\FileInfo::TYPE_FILE and
|
||||
(
|
||||
endswith($file->getName(), '.gpx') or
|
||||
endswith($file->getName(), '.GPX')
|
||||
)
|
||||
){
|
||||
$rel_dir = str_replace($userfolder_path, '', dirname($file->getPath()));
|
||||
$rel_dir = str_replace('//', '/', $rel_dir);
|
||||
if ($rel_dir === ''){
|
||||
$rel_dir = '/';
|
||||
}
|
||||
if (!in_array($rel_dir, $alldirs)){
|
||||
array_push($alldirs, $rel_dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PARAMS to view
|
||||
|
||||
sort($alldirs);
|
||||
$params = [
|
||||
'dirs'=>$alldirs,
|
||||
'username'=>$this->userId,
|
||||
'gpxedit_version'=>$this->appVersion
|
||||
];
|
||||
$response = new TemplateResponse('gpxedit', 'main', $params);
|
||||
$csp = new ContentSecurityPolicy();
|
||||
$csp->addAllowedImageDomain('*')
|
||||
->addAllowedMediaDomain('*')
|
||||
->addAllowedChildSrcDomain('*')
|
||||
->addAllowedObjectDomain('*')
|
||||
->addAllowedScriptDomain('*')
|
||||
//->allowEvalScript('*')
|
||||
->addAllowedConnectDomain('*');
|
||||
$response->setContentSecurityPolicy($csp);
|
||||
return $response;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
.leaflet-control-geocoder {
|
||||
background: white;
|
||||
box-shadow: 0 1px 7px rgba(0,0,0,0.65);
|
||||
-webkit-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
line-height: 26px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-control-geocoder {
|
||||
box-shadow: none;
|
||||
border: 2px solid rgba(0,0,0,0.2);
|
||||
background-clip: padding-box;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.leaflet-control-geocoder-form {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.leaflet-control-geocoder-expanded .leaflet-control-geocoder-form {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.leaflet-control-geocoder-form input, .leaflet-control-geocoder-form ul, .leaflet-control-geocoder-error {
|
||||
border: 0;
|
||||
color: transparent;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.leaflet-control-geocoder-form input {
|
||||
font-size: 16px;
|
||||
width: 0;
|
||||
transition: width 0.125s ease-in;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-control-geocoder-form input {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.leaflet-control-geocoder-icon {
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
background-image: url(./images/geocoder.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
float: right;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-control-geocoder-icon {
|
||||
margin-top: 2px;
|
||||
width: 30px;
|
||||
}
|
||||
|
||||
.leaflet-control-geocoder-throbber .leaflet-control-geocoder-icon {
|
||||
background-image: url(./images/throbber.gif);
|
||||
}
|
||||
|
||||
.leaflet-control-geocoder-expanded input, .leaflet-control-geocoder-error {
|
||||
width: 226px;
|
||||
margin: 0 0 0 4px;
|
||||
padding: 0 0 0 4px;
|
||||
vertical-align: middle;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.leaflet-control-geocoder-form input:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.leaflet-control-geocoder-form button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.leaflet-control-geocoder-form-no-error {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.leaflet-control-geocoder-error {
|
||||
margin-top: 8px;
|
||||
display: block;
|
||||
color: #444;
|
||||
}
|
||||
|
||||
ul.leaflet-control-geocoder-alternatives {
|
||||
width: 260px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
transition: height 0.125s ease-in;
|
||||
}
|
||||
|
||||
.leaflet-control-geocoder-alternatives-minimized {
|
||||
width: 0 !important;
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.leaflet-control-geocoder-alternatives li {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
border-bottom: 1px solid #eee;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
|
||||
.leaflet-control-geocoder-alternatives li:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.leaflet-control-geocoder-alternatives a {
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
padding: 6px 8px 16px 6px;
|
||||
font-size: 14px;
|
||||
line-height: 1;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-control-geocoder-alternatives a {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.leaflet-control-geocoder-alternatives a:hover, .leaflet-control-geocoder-selected {
|
||||
background-color: #ddd;
|
||||
}
|
||||
|
||||
.leaflet-control-geocoder-address-detail {
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.leaflet-control-geocoder-address-context {
|
||||
color: #666;
|
||||
font-size: 12px;
|
||||
font-weight: lighter;
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
.leaflet-control-minimap {
|
||||
border:solid rgba(255, 255, 255, 1.0) 4px;
|
||||
box-shadow: 0 1px 5px rgba(0,0,0,0.65);
|
||||
border-radius: 3px;
|
||||
background: #f8f8f9;
|
||||
transition: all .6s;
|
||||
}
|
||||
|
||||
.leaflet-control-minimap a {
|
||||
background-color: rgba(255, 255, 255, 1.0);
|
||||
background-repeat: no-repeat;
|
||||
z-index: 99999;
|
||||
transition: all .6s;
|
||||
}
|
||||
|
||||
.leaflet-control-minimap a.minimized-bottomright {
|
||||
-webkit-transform: rotate(180deg);
|
||||
transform: rotate(180deg);
|
||||
border-radius: 0px;
|
||||
}
|
||||
|
||||
.leaflet-control-minimap a.minimized-topleft {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
border-radius: 0px;
|
||||
}
|
||||
|
||||
.leaflet-control-minimap a.minimized-bottomleft {
|
||||
-webkit-transform: rotate(270deg);
|
||||
transform: rotate(270deg);
|
||||
border-radius: 0px;
|
||||
}
|
||||
|
||||
.leaflet-control-minimap a.minimized-topright {
|
||||
-webkit-transform: rotate(90deg);
|
||||
transform: rotate(90deg);
|
||||
border-radius: 0px;
|
||||
}
|
||||
|
||||
.leaflet-control-minimap-toggle-display{
|
||||
background-image: url("images/toggle.svg");
|
||||
background-size: cover;
|
||||
position: absolute;
|
||||
border-radius: 3px 0px 0px 0px;
|
||||
}
|
||||
|
||||
.leaflet-oldie .leaflet-control-minimap-toggle-display{
|
||||
background-image: url("images/toggle.png");
|
||||
}
|
||||
|
||||
.leaflet-control-minimap-toggle-display-bottomright {
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.leaflet-control-minimap-toggle-display-topleft{
|
||||
top: 0;
|
||||
left: 0;
|
||||
-webkit-transform: rotate(180deg);
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.leaflet-control-minimap-toggle-display-bottomleft{
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
-webkit-transform: rotate(90deg);
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.leaflet-control-minimap-toggle-display-topright{
|
||||
top: 0;
|
||||
right: 0;
|
||||
-webkit-transform: rotate(270deg);
|
||||
transform: rotate(270deg);
|
||||
}
|
||||
|
||||
/* Old IE */
|
||||
.leaflet-oldie .leaflet-control-minimap {
|
||||
border: 1px solid #999;
|
||||
}
|
||||
|
||||
.leaflet-oldie .leaflet-control-minimap a {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.leaflet-oldie .leaflet-control-minimap a.minimized {
|
||||
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
/*! Version: 0.42.0
|
||||
Date: 2015-04-29 */
|
||||
|
||||
.leaflet-touch .leaflet-bar-part-single{-webkit-border-radius:7px 7px 7px 7px;border-radius:7px 7px 7px 7px;border-bottom:none}.leaflet-touch .leaflet-control-locate{box-shadow:none;border:2px solid rgba(0,0,0,0.2);background-clip:padding-box}.leaflet-control-locate a{font-size:1.4em;margin-left:1px;color:#444}.leaflet-control-locate.active a{color:#2074B6}.leaflet-control-locate.active.following a{color:#FC8428}
|
||||
/*# sourceMappingURL=L.Control.Locate.min.css.map */
|
|
@ -0,0 +1,9 @@
|
|||
.leaflet-container .leaflet-control-mouseposition {
|
||||
background-color: rgba(255, 255, 255, 0.7);
|
||||
box-shadow: 0 0 5px #bbb;
|
||||
padding: 0 5px;
|
||||
margin:0;
|
||||
color: #333;
|
||||
font: 11px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
Colorbox Core Style:
|
||||
The following CSS is consistent between example themes and should not be altered.
|
||||
*/
|
||||
#colorbox, #cboxOverlay, #cboxWrapper{position:absolute; top:0; left:0; z-index:9999; overflow:hidden; -webkit-transform: translate3d(0,0,0);}
|
||||
#cboxWrapper {max-width:none;}
|
||||
#cboxOverlay{position:fixed; width:100%; height:100%;}
|
||||
#cboxMiddleLeft, #cboxBottomLeft{clear:left;}
|
||||
#cboxContent{position:relative;}
|
||||
#cboxLoadedContent{overflow:auto; -webkit-overflow-scrolling: touch;}
|
||||
#cboxTitle{margin:0;}
|
||||
#cboxLoadingOverlay, #cboxLoadingGraphic{position:absolute; top:0; left:0; width:100%; height:100%;}
|
||||
#cboxPrevious, #cboxNext, #cboxClose, #cboxSlideshow{cursor:pointer;}
|
||||
.cboxPhoto{float:left; margin:auto; border:0; display:block; max-width:none; -ms-interpolation-mode:bicubic;}
|
||||
.cboxIframe{width:100%; height:100%; display:block; border:0; padding:0; margin:0;}
|
||||
#colorbox, #cboxContent, #cboxLoadedContent{box-sizing:content-box; -moz-box-sizing:content-box; -webkit-box-sizing:content-box;}
|
||||
|
||||
/*
|
||||
User Style:
|
||||
Change the following styles to modify the appearance of Colorbox. They are
|
||||
ordered & tabbed in a way that represents the nesting of the generated HTML.
|
||||
*/
|
||||
#cboxOverlay{background:#000; opacity: 0.9; filter: alpha(opacity = 90);}
|
||||
#colorbox{outline:0;}
|
||||
#cboxContent{margin-top:20px;background:#000;}
|
||||
.cboxIframe{background:#fff;}
|
||||
#cboxError{padding:50px; border:1px solid #ccc;}
|
||||
#cboxLoadedContent{border:5px solid #000; background:#fff;}
|
||||
#cboxTitle{position:absolute; top:-20px; left:0; color:#ccc;}
|
||||
#cboxCurrent{position:absolute; top:-20px; right:0px; color:#ccc;}
|
||||
#cboxLoadingGraphic{background:url(images/loading.gif) no-repeat center center;}
|
||||
|
||||
/* these elements are buttons, and may need to have additional styles reset to avoid unwanted base styles */
|
||||
#cboxPrevious, #cboxNext, #cboxSlideshow, #cboxClose {border:0; padding:0; margin:0; overflow:visible; width:auto; background:none; }
|
||||
|
||||
/* avoid outlines on :active (mouseclick), but preserve outlines on :focus (tabbed navigating) */
|
||||
#cboxPrevious:active, #cboxNext:active, #cboxSlideshow:active, #cboxClose:active {outline:0;}
|
||||
|
||||
#cboxSlideshow{position:absolute; top:-20px; right:90px; color:#fff;}
|
||||
#cboxPrevious{position:absolute; top:50%; left:5px; margin-top:-32px; background:url(images/controls.png) no-repeat top left; width:28px; height:65px; text-indent:-9999px;}
|
||||
#cboxPrevious:hover{background-position:bottom left;}
|
||||
#cboxNext{position:absolute; top:50%; right:5px; margin-top:-32px; background:url(images/controls.png) no-repeat top right; width:28px; height:65px; text-indent:-9999px;}
|
||||
#cboxNext:hover{background-position:bottom right;}
|
||||
#cboxClose{position:absolute; top:5px; right:5px; display:block; background:url(images/controls.png) no-repeat top center; width:38px; height:19px; text-indent:-9999px;}
|
||||
#cboxClose:hover{background-position:bottom center;}
|
|
@ -0,0 +1,489 @@
|
|||
html {
|
||||
min-height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
div#map {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
width:100%;
|
||||
/*width: calc(100% - 300px);*/
|
||||
}
|
||||
|
||||
div.trackcol{
|
||||
width:100px;
|
||||
}
|
||||
|
||||
div.durationcol{
|
||||
max-width:50px;
|
||||
}
|
||||
|
||||
#gpxtable a.permalink , #gpxtable a.csrtm , #gpxtable a.csrtms{
|
||||
float: right;
|
||||
font-size: 11px;
|
||||
margin-left: 2px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
div#logo, div#logo img {
|
||||
height:80px;
|
||||
}
|
||||
div#logo div{
|
||||
position:absolute;
|
||||
bottom:0;
|
||||
width:100%;
|
||||
}
|
||||
div#logo div p{
|
||||
width:100%;
|
||||
text-align:center;
|
||||
float:right;
|
||||
font-size:10px;
|
||||
}
|
||||
div#logo{
|
||||
position:relative;
|
||||
}
|
||||
div#logo p{
|
||||
margin-top: 0px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
div#logo {
|
||||
background-image: url('images/gpxpod.png');
|
||||
width: 65px;
|
||||
background-size: 65px 65px;
|
||||
background-repeat: no-repeat;
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
|
||||
#folderrightdiv, #waypointstyle, #comparebutton, #optionbuttonsdiv, #folderdiv, #tzselect, #trackwaypointdisplay,
|
||||
#astlegend, #picturestylediv{
|
||||
float:right;
|
||||
display:block;
|
||||
}
|
||||
|
||||
#picturestyleselect{
|
||||
max-width: 90px;
|
||||
}
|
||||
|
||||
#folderrightdiv, #removeelevation, #comparebutton, #optionbuttonsdiv{
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
#optionbuttonsdiv{
|
||||
max-width: 60%;
|
||||
}
|
||||
#optioncheckdiv{
|
||||
max-width: 40%;
|
||||
font-size: 11px;
|
||||
}
|
||||
#folderdiv, #scantypediv{
|
||||
max-width: 80%;
|
||||
}
|
||||
|
||||
#tzselect{
|
||||
max-width:200px;
|
||||
}
|
||||
|
||||
#titlechoosedirform, #logo, #optioncheckdiv, #computecheckdiv{
|
||||
float:left;
|
||||
display:block;
|
||||
}
|
||||
#folderrightdiv {
|
||||
/*max-width:60%;
|
||||
margin-top: 12px;*/
|
||||
}
|
||||
#scantypediv{
|
||||
float:right;
|
||||
}
|
||||
#logo {
|
||||
max-width:40%;
|
||||
}
|
||||
|
||||
#optionbuttonsdiv{
|
||||
border-left:solid 1px;
|
||||
}
|
||||
|
||||
#titlechoosedirform{
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
h1.sectiontitle{
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
}
|
||||
h3.sectiontitle{
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
div#settings h1, div#help h1{
|
||||
/*margin-left:30px;*/
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
ul,hr {
|
||||
margin-top : 3px;
|
||||
margin-bottom : 3px;
|
||||
}
|
||||
h3 {
|
||||
margin-top : 5px;
|
||||
margin-bottom : 5px;
|
||||
}
|
||||
|
||||
.transparent {
|
||||
opacity : 0.6;
|
||||
}
|
||||
|
||||
.uibutton {
|
||||
font-size: 13px;
|
||||
height : 28px;
|
||||
}
|
||||
|
||||
#filterlist li input{
|
||||
margin-bottom: 10px;
|
||||
width:100px;
|
||||
}
|
||||
|
||||
#filterlist li b{
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
#filterlist li .ui-spinner {
|
||||
height:28px;
|
||||
margin-bottom: 5px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
#clearfilter{
|
||||
margin-left:10px;
|
||||
}
|
||||
.filterbutton{
|
||||
float:right;
|
||||
}
|
||||
|
||||
#filtertabtitle h1{
|
||||
float:left;
|
||||
margin-left:30px;
|
||||
}
|
||||
#filtertabtitle h3{
|
||||
float:left;
|
||||
}
|
||||
|
||||
#gpxtable{
|
||||
word-wrap: break-word;
|
||||
border-radius: 7px;
|
||||
}
|
||||
#gpxtable tr:first-child th:first-child
|
||||
{
|
||||
border-top-left-radius: 7px;
|
||||
}
|
||||
#gpxtable tr:first-child th:last-child
|
||||
{
|
||||
border-top-right-radius: 7px;
|
||||
}
|
||||
#gpxtable tr:last-child td:first-child
|
||||
{
|
||||
border-bottom-left-radius: 7px;
|
||||
}
|
||||
#gpxtable tr:last-child td:last-child
|
||||
{
|
||||
border-bottom-right-radius: 7px;
|
||||
}
|
||||
|
||||
#gpxtable th, #gpxtable td {
|
||||
border: 1px solid grey;
|
||||
}
|
||||
#gpxtable td {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.activeArea{
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 450px;
|
||||
right: 10px;
|
||||
bottom: 10px;
|
||||
}
|
||||
|
||||
#settings{
|
||||
color:black;
|
||||
}
|
||||
.disclist{
|
||||
margin-left:20px;
|
||||
list-style-type:disc;
|
||||
}
|
||||
.circlist{
|
||||
margin-left:20px;
|
||||
list-style-type:circle;
|
||||
}
|
||||
#loading, #loadingmarkers, #deleting {
|
||||
/*width: 330px;*/
|
||||
padding-left: 5px;
|
||||
/*height: 35px;*/
|
||||
text-align: right;
|
||||
font-weight: bold;
|
||||
font-size: 22px;
|
||||
color: white;
|
||||
background-color: #0074D9;
|
||||
background-size: 30px 30px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 3% 50%;
|
||||
border-radius: 7px;
|
||||
/*float: right;*/
|
||||
position:fixed;
|
||||
left:60px;
|
||||
top:60px;
|
||||
display:none;
|
||||
/*z-index: 1000;*/
|
||||
}
|
||||
#loading .fa, #loadingmarkers .fa, #deleting .fa {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
#loadingmarkers {
|
||||
background-color: green;
|
||||
}
|
||||
|
||||
#loading p, #loadingmarkers p, #deleting p{
|
||||
padding: 6px 6px 6px 6px;
|
||||
}
|
||||
.clear {
|
||||
clear:both;
|
||||
}
|
||||
#nofolder {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color:red;
|
||||
}
|
||||
#nofoldertext ,#nofolder {
|
||||
float:left;
|
||||
clear:both;
|
||||
}
|
||||
#nofoldertext{
|
||||
color:blue;
|
||||
}
|
||||
#subfolderselect, #processtypeselect, #tablecriteriasel {
|
||||
max-width:200px;
|
||||
text-overflow:ellipsis;
|
||||
}
|
||||
/*#ticv {
|
||||
display:none;
|
||||
}*/
|
||||
|
||||
.spinning {
|
||||
-moz-animation:spin 0.7s linear infinite;
|
||||
-webkit-animation:spin 0.7s linear infinite;
|
||||
animation:spin 0.7s linear infinite;
|
||||
}
|
||||
|
||||
@-moz-keyframes spin { 100% { -moz-transform: rotate(360deg); } }
|
||||
@-webkit-keyframes spin { 100% { -webkit-transform: rotate(360deg); } }
|
||||
@keyframes spin { 100% { -webkit-transform: rotate(360deg); transform:rotate(360deg); } }
|
||||
|
||||
/*#tablecriterialabel{
|
||||
float:left;
|
||||
}
|
||||
#tablecriteriasel{
|
||||
float:right;
|
||||
}
|
||||
*/
|
||||
#colorcriteriadiv{
|
||||
float:right;
|
||||
}
|
||||
|
||||
.toplink:link {
|
||||
color: blue;
|
||||
text-decoration: underline;
|
||||
}
|
||||
.toplink:visited {
|
||||
color: blue;
|
||||
text-decoration: underline;
|
||||
}
|
||||
.toplink:hover {
|
||||
color: hotpink;
|
||||
text-decoration: underline;
|
||||
}
|
||||
.toplink:active {
|
||||
color: green;
|
||||
text-decoration: underline;
|
||||
}
|
||||
#clean_results{
|
||||
word-wrap:break-word;
|
||||
}
|
||||
#clean_results ul{
|
||||
list-style-type:disc;
|
||||
}
|
||||
#tileserveradd, #tileserveradd input{
|
||||
width:100%;
|
||||
}
|
||||
|
||||
#gpxtable thead i.bigfa{
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
font-size:19px;
|
||||
}
|
||||
.permalink:link {
|
||||
color: black;
|
||||
text-decoration: underline;
|
||||
}
|
||||
.permalink:visited {
|
||||
color: black;
|
||||
text-decoration: underline;
|
||||
}
|
||||
.permalink:hover {
|
||||
color: hotpink;
|
||||
text-decoration: underline;
|
||||
}
|
||||
.permalink:active {
|
||||
color: green;
|
||||
text-decoration: underline;
|
||||
}
|
||||
#folderdiv .permalink{
|
||||
font-size:16px;
|
||||
}
|
||||
.popuptable{
|
||||
font-size: 10px;
|
||||
border-collapse: collapse;
|
||||
word-wrap: break-word;
|
||||
white-space: normal;
|
||||
width: 250px;
|
||||
margin: auto;
|
||||
}
|
||||
.popuptable td{
|
||||
border: 1px solid black;
|
||||
padding: 0px 5px 0px 5px;
|
||||
}
|
||||
.popuptable tr:nth-child(even){background-color: #f2f2f2;}
|
||||
.popuptable tr:hover {background-color: #ddd;}
|
||||
|
||||
#linkinput {
|
||||
width:98%;
|
||||
}
|
||||
#optiontitle{
|
||||
width:100%;
|
||||
float:left;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* adapt right leaflet controls when sidebar pushes them */
|
||||
@media screen and (max-width: 767px) {
|
||||
.leaflet-right { right:40px; }
|
||||
}
|
||||
|
||||
input[type=checkbox]
|
||||
{
|
||||
/* Double-sized Checkboxes */
|
||||
-ms-transform: scale(1.5); /* IE */
|
||||
-moz-transform: scale(1.5); /* FF */
|
||||
-webkit-transform: scale(1.5); /* Safari and Chrome */
|
||||
-o-transform: scale(1.5); /* Opera */
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.tooltipblue{
|
||||
background: rgba(0, 0, 255, 0.4);
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tooltipred{
|
||||
background: rgba(255, 0, 0, 0.4);
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tooltipcyan{
|
||||
background: rgba(0, 255, 255, 0.4);
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tooltippurple{
|
||||
background: rgba(128, 0, 128, 0.4);
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tooltipLime{
|
||||
background: rgba(0, 255, 0, 0.4);
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tooltipyellow{
|
||||
background: rgba(255, 255, 0, 0.4);
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tooltipblack{
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tooltiporange{
|
||||
background: rgba(255, 165, 0, 0.4);
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tooltipbrown{
|
||||
background: rgba(165, 42, 42, 0.4);
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tooltipChartreuse{
|
||||
background: rgba(127, 255, 0, 0.4);
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tooltipCrimson{
|
||||
background: rgba(220, 20, 60, 0.4);
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tooltipDeepPink{
|
||||
background: rgba(255, 20, 147, 0.4);
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
}
|
||||
.tooltipGold{
|
||||
background: rgba(255, 215, 0, 0.4);
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.leaflet-div-icon2
|
||||
{
|
||||
background-image: url('images/pinblue.png') !important;
|
||||
width: 21px !important;
|
||||
height: 30px !important;
|
||||
}
|
||||
|
||||
.leaflet-marker-red
|
||||
{
|
||||
background-image: url('images/marker-icon-red.png');
|
||||
width: 25px !important;
|
||||
height: 41px !important;
|
||||
}
|
||||
|
||||
.popupImage{
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
}
|
||||
|
||||
.leaflet-popup-content{
|
||||
margin: 4px 4px;
|
||||
}
|
||||
|
||||
.smallRedMarker{
|
||||
background: rgba(255,0,0,1);
|
||||
border: 1px solid black;
|
||||
}
|
||||
.trackNamesList{
|
||||
list-style-type:disc;
|
||||
text-align: center;
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
html {
|
||||
min-height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
div#map {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
div#parameters {
|
||||
font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
|
||||
color: black;
|
||||
font-size: 75%;
|
||||
background-color: white;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
right: 0px;
|
||||
width: 300px;
|
||||
height: 100%;
|
||||
padding: 10px;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
#gpxselect {
|
||||
width:100%;
|
||||
}
|
||||
|
||||
div#logo, div#logo img {
|
||||
height:100px;
|
||||
}
|
||||
div#logo {
|
||||
background-image: url('images/gpxvcomp.png');
|
||||
width: 125px;
|
||||
background-size: 125px 100px;
|
||||
background-repeat: no-repeat;
|
||||
margin: auto;
|
||||
}
|
||||
h1.sectiontitle{
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
}
|
||||
h3.sectiontitle{
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
ul,hr {
|
||||
margin-top : 3px;
|
||||
margin-bottom : 3px;
|
||||
}
|
||||
h3 {
|
||||
margin-top : 5px;
|
||||
margin-bottom : 5px;
|
||||
}
|
||||
|
||||
.uibutton {
|
||||
font-size: 13px;
|
||||
height : 28px;
|
||||
}
|
||||
#help ul, .trackpairlist{
|
||||
list-style-type:disc;
|
||||
}
|
||||
.activeArea{
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 450px;
|
||||
right: 10px;
|
||||
bottom: 10px;
|
||||
}
|
||||
|
||||
#stattable{
|
||||
word-wrap: break-word;
|
||||
white-space: normal;
|
||||
border-radius: 7px;
|
||||
}
|
||||
#stattable tr:first-child th:first-child
|
||||
{
|
||||
border-top-left-radius: 7px;
|
||||
}
|
||||
#stattable tr:first-child th:last-child
|
||||
{
|
||||
border-top-right-radius: 7px;
|
||||
}
|
||||
#stattable tr:last-child td:first-child
|
||||
{
|
||||
border-bottom-left-radius: 7px;
|
||||
}
|
||||
#stattable tr:last-child td:last-child
|
||||
{
|
||||
border-bottom-right-radius: 7px;
|
||||
}
|
||||
|
||||
#stattable th, #stattable td {
|
||||
border: 1px solid grey;
|
||||
max-width: 100px;
|
||||
}
|
||||
|
||||
div#statdiv{
|
||||
overflow:scroll;
|
||||
}
|
||||
#stattable td.normal{
|
||||
background-color: white;
|
||||
}
|
||||
td.selectedColumn{
|
||||
background-color: #FFE464;
|
||||
}
|
||||
#stattable td.statnamecol {
|
||||
background-color: #E6EEEE;
|
||||
}
|
||||
|
||||
/* adapt right leaflet controls when sidebar pushes them */
|
||||
@media screen and (max-width: 767px) {
|
||||
.leaflet-right { right:40px; }
|
||||
}
|
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 466 B |
After Width: | Height: | Size: 97 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 696 B |
After Width: | Height: | Size: 6.1 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 618 B |
After Width: | Height: | Size: 344 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 1.0 KiB |
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 540 60" height="60" width="540">
|
||||
<g id="enabled" fill="#464646">
|
||||
<g id="polyline">
|
||||
<path d="M18 36v6h6v-6h-6zm4 4h-2v-2h2v2z"/>
|
||||
<path d="M36 18v6h6v-6h-6zm4 4h-2v-2h2v2z"/>
|
||||
<path d="M23.142 39.145l-2.285-2.29 16-15.998 2.285 2.285z"/>
|
||||
</g>
|
||||
<path id="polygon" d="M100 24.565l-2.096 14.83L83.07 42 76 28.773 86.463 18z"/>
|
||||
<path id="rectangle" d="M140 20h20v20h-20z"/>
|
||||
<path id="circle" d="M221 30c0 6.078-4.926 11-11 11s-11-4.922-11-11c0-6.074 4.926-11 11-11s11 4.926 11 11z"/>
|
||||
<path id="marker" d="M270,19c-4.971,0-9,4.029-9,9c0,4.971,5.001,12,9,14c4.001-2,9-9.029,9-14C279,23.029,274.971,19,270,19z M270,31.5c-2.484,0-4.5-2.014-4.5-4.5c0-2.484,2.016-4.5,4.5-4.5c2.485,0,4.5,2.016,4.5,4.5C274.5,29.486,272.485,31.5,270,31.5z"/>
|
||||
<g id="edit">
|
||||
<path d="M337,30.156v0.407v5.604c0,1.658-1.344,3-3,3h-10c-1.655,0-3-1.342-3-3v-10c0-1.657,1.345-3,3-3h6.345 l3.19-3.17H324c-3.313,0-6,2.687-6,6v10c0,3.313,2.687,6,6,6h10c3.314,0,6-2.687,6-6v-8.809L337,30.156"/>
|
||||
<path d="M338.72 24.637l-8.892 8.892H327V30.7l8.89-8.89z"/>
|
||||
<path d="M338.697 17.826h4v4h-4z" transform="rotate(-134.99 340.703 19.817)"/>
|
||||
</g>
|
||||
<g id="remove">
|
||||
<path d="M381 42h18V24h-18v18zm14-16h2v14h-2V26zm-4 0h2v14h-2V26zm-4 0h2v14h-2V26zm-4 0h2v14h-2V26z"/>
|
||||
<path d="M395 20v-4h-10v4h-6v2h22v-2h-6zm-2 0h-6v-2h6v2z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="disabled" fill="#bbb" transform="translate(120)">
|
||||
<use xlink:href="#edit" id="edit-disabled"/>
|
||||
<use xlink:href="#remove" id="remove-disabled"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 4.7 KiB |
After Width: | Height: | Size: 219 B |
|
@ -0,0 +1,224 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
inkscape:version="0.48.2 r9819"
|
||||
version="1.1"
|
||||
id="svg2"
|
||||
height="18"
|
||||
width="18"
|
||||
sodipodi:docname="toggle.svg"
|
||||
inkscape:export-filename="C:\projects\Leaflet.MiniMap\src\images\toggle-2x.png"
|
||||
inkscape:export-xdpi="160"
|
||||
inkscape:export-ydpi="160">
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="44.2911"
|
||||
inkscape:cx="14.22384"
|
||||
inkscape:cy="9.2849211"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="svg2"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1138"
|
||||
inkscape:window-x="1192"
|
||||
inkscape:window-y="404"
|
||||
inkscape:window-maximized="1" />
|
||||
<defs
|
||||
id="defs4">
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="DiamondMend"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="DiamondMend">
|
||||
<path
|
||||
transform="matrix(0.4,0,0,0.4,-2.6,0)"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
|
||||
d="M 0,-7.0710768 -7.0710894,0 0,7.0710589 7.0710462,0 0,-7.0710768 z"
|
||||
id="path4062"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="Tail"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Tail">
|
||||
<g
|
||||
transform="scale(-1.2,-1.2)"
|
||||
id="g3997">
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;marker-start:none;marker-end:none"
|
||||
d="M -3.8048674,-3.9585227 0.54352094,0"
|
||||
id="path3999"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;marker-start:none;marker-end:none"
|
||||
d="M -1.2866832,-3.9585227 3.0617053,0"
|
||||
id="path4001"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;marker-start:none;marker-end:none"
|
||||
d="M 1.3053582,-3.9585227 5.6537466,0"
|
||||
id="path4003"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;marker-start:none;marker-end:none"
|
||||
d="M -3.8048674,4.1775838 0.54352094,0.21974226"
|
||||
id="path4005"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;marker-start:none;marker-end:none"
|
||||
d="M -1.2866832,4.1775838 3.0617053,0.21974226"
|
||||
id="path4007"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;marker-start:none;marker-end:none"
|
||||
d="M 1.3053582,4.1775838 5.6537466,0.21974226"
|
||||
id="path4009"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</marker>
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="DiamondLend"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="DiamondLend">
|
||||
<path
|
||||
transform="matrix(0.8,0,0,0.8,-5.6,0)"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
|
||||
d="M 0,-7.0710768 -7.0710894,0 0,7.0710589 7.0710462,0 0,-7.0710768 z"
|
||||
id="path4059"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="TriangleOutL"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="TriangleOutL">
|
||||
<path
|
||||
transform="scale(0.8,0.8)"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
|
||||
d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
|
||||
id="path4104"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="Arrow2Lend"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Lend">
|
||||
<path
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||
id="path3982"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="TriangleInL"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="TriangleInL">
|
||||
<path
|
||||
transform="scale(-0.8,-0.8)"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
|
||||
d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
|
||||
id="path4095"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="Arrow1Lstart"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Lstart">
|
||||
<path
|
||||
transform="matrix(0.8,0,0,0.8,10,0)"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||
id="path3961"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="Arrow2Lstart"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Lstart">
|
||||
<path
|
||||
transform="matrix(1.1,0,0,1.1,1.1,0)"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||
id="path3979"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<inkscape:path-effect
|
||||
fuse_tolerance="0"
|
||||
vertical_pattern="false"
|
||||
prop_units="false"
|
||||
tang_offset="0"
|
||||
normal_offset="0"
|
||||
spacing="0"
|
||||
scale_y_rel="false"
|
||||
prop_scale="1"
|
||||
copytype="single_stretched"
|
||||
pattern="M 0,5 10,10 10,0 z"
|
||||
is_visible="true"
|
||||
id="path-effect3006"
|
||||
effect="skeletal" />
|
||||
</defs>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:groupmode="layer"
|
||||
inkscape:label="Layer 1"
|
||||
transform="translate(0,-1034.3622)" />
|
||||
<path
|
||||
id="path11659"
|
||||
d="m 13.181013,13.146224 0,-5.8105616 -5.8105513,5.8105616 5.8105513,0 z"
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.64300000000000000;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
inkscape:label="Triangle"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:2.48154879000000020;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="M 12.761963,12.727174 6.2529128,6.2181329"
|
||||
id="path11689"
|
||||
inkscape:connector-curvature="0" />
|
||||
</svg>
|
After Width: | Height: | Size: 7.6 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 418 B |
After Width: | Height: | Size: 312 B |
After Width: | Height: | Size: 205 B |
After Width: | Height: | Size: 262 B |
After Width: | Height: | Size: 348 B |
After Width: | Height: | Size: 207 B |
After Width: | Height: | Size: 5.7 KiB |
After Width: | Height: | Size: 278 B |
After Width: | Height: | Size: 328 B |
After Width: | Height: | Size: 6.8 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 6.2 KiB |
|
@ -0,0 +1,623 @@
|
|||
/* required styles */
|
||||
|
||||
.leaflet-pane,
|
||||
.leaflet-tile,
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow,
|
||||
.leaflet-tile-container,
|
||||
.leaflet-map-pane svg,
|
||||
.leaflet-map-pane canvas,
|
||||
.leaflet-zoom-box,
|
||||
.leaflet-image-layer,
|
||||
.leaflet-layer {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
.leaflet-container {
|
||||
overflow: hidden;
|
||||
}
|
||||
.leaflet-tile,
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow {
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
-webkit-user-drag: none;
|
||||
}
|
||||
/* Safari renders non-retina tile on retina better with this, but Chrome is worse */
|
||||
.leaflet-safari .leaflet-tile {
|
||||
image-rendering: -webkit-optimize-contrast;
|
||||
}
|
||||
/* hack that prevents hw layers "stretching" when loading new tiles */
|
||||
.leaflet-safari .leaflet-tile-container {
|
||||
width: 1600px;
|
||||
height: 1600px;
|
||||
-webkit-transform-origin: 0 0;
|
||||
}
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow {
|
||||
display: block;
|
||||
}
|
||||
/* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */
|
||||
/* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */
|
||||
.leaflet-container .leaflet-overlay-pane svg,
|
||||
.leaflet-container .leaflet-marker-pane img,
|
||||
.leaflet-container .leaflet-tile-pane img,
|
||||
.leaflet-container img.leaflet-image-layer {
|
||||
max-width: none !important;
|
||||
}
|
||||
|
||||
.leaflet-container.leaflet-touch-zoom {
|
||||
-ms-touch-action: pan-x pan-y;
|
||||
touch-action: pan-x pan-y;
|
||||
}
|
||||
.leaflet-container.leaflet-touch-drag {
|
||||
-ms-touch-action: pinch-zoom;
|
||||
}
|
||||
.leaflet-container.leaflet-touch-drag.leaflet-touch-drag {
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
.leaflet-tile {
|
||||
filter: inherit;
|
||||
visibility: hidden;
|
||||
}
|
||||
.leaflet-tile-loaded {
|
||||
visibility: inherit;
|
||||
}
|
||||
.leaflet-zoom-box {
|
||||
width: 0;
|
||||
height: 0;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
z-index: 800;
|
||||
}
|
||||
/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */
|
||||
.leaflet-overlay-pane svg {
|
||||
-moz-user-select: none;
|
||||
}
|
||||
|
||||
.leaflet-pane { z-index: 400; }
|
||||
|
||||
.leaflet-tile-pane { z-index: 200; }
|
||||
.leaflet-overlay-pane { z-index: 400; }
|
||||
.leaflet-shadow-pane { z-index: 500; }
|
||||
.leaflet-marker-pane { z-index: 600; }
|
||||
.leaflet-tooltip-pane { z-index: 650; }
|
||||
.leaflet-popup-pane { z-index: 700; }
|
||||
|
||||
.leaflet-map-pane canvas { z-index: 100; }
|
||||
.leaflet-map-pane svg { z-index: 200; }
|
||||
|
||||
.leaflet-vml-shape {
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
}
|
||||
.lvml {
|
||||
behavior: url(#default#VML);
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
|
||||
/* control positioning */
|
||||
|
||||
.leaflet-control {
|
||||
position: relative;
|
||||
z-index: 800;
|
||||
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
|
||||
pointer-events: auto;
|
||||
}
|
||||
.leaflet-top,
|
||||
.leaflet-bottom {
|
||||
position: absolute;
|
||||
z-index: 1000;
|
||||
pointer-events: none;
|
||||
}
|
||||
.leaflet-top {
|
||||
top: 0;
|
||||
}
|
||||
.leaflet-right {
|
||||
right: 0;
|
||||
}
|
||||
.leaflet-bottom {
|
||||
bottom: 0;
|
||||
}
|
||||
.leaflet-left {
|
||||
left: 0;
|
||||
}
|
||||
.leaflet-control {
|
||||
float: left;
|
||||
clear: both;
|
||||
}
|
||||
.leaflet-right .leaflet-control {
|
||||
float: right;
|
||||
}
|
||||
.leaflet-top .leaflet-control {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.leaflet-bottom .leaflet-control {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.leaflet-left .leaflet-control {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.leaflet-right .leaflet-control {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
|
||||
/* zoom and fade animations */
|
||||
|
||||
.leaflet-fade-anim .leaflet-tile {
|
||||
will-change: opacity;
|
||||
}
|
||||
.leaflet-fade-anim .leaflet-popup {
|
||||
opacity: 0;
|
||||
-webkit-transition: opacity 0.2s linear;
|
||||
-moz-transition: opacity 0.2s linear;
|
||||
-o-transition: opacity 0.2s linear;
|
||||
transition: opacity 0.2s linear;
|
||||
}
|
||||
.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
|
||||
opacity: 1;
|
||||
}
|
||||
.leaflet-zoom-animated {
|
||||
-webkit-transform-origin: 0 0;
|
||||
-ms-transform-origin: 0 0;
|
||||
transform-origin: 0 0;
|
||||
}
|
||||
.leaflet-zoom-anim .leaflet-zoom-animated {
|
||||
will-change: transform;
|
||||
}
|
||||
.leaflet-zoom-anim .leaflet-zoom-animated {
|
||||
-webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
-moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
-o-transition: -o-transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
transition: transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
}
|
||||
.leaflet-zoom-anim .leaflet-tile,
|
||||
.leaflet-pan-anim .leaflet-tile {
|
||||
-webkit-transition: none;
|
||||
-moz-transition: none;
|
||||
-o-transition: none;
|
||||
transition: none;
|
||||
}
|
||||
|
||||
.leaflet-zoom-anim .leaflet-zoom-hide {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
|
||||
/* cursors */
|
||||
|
||||
.leaflet-interactive {
|
||||
cursor: pointer;
|
||||
}
|
||||
.leaflet-grab {
|
||||
cursor: -webkit-grab;
|
||||
cursor: -moz-grab;
|
||||
}
|
||||
.leaflet-crosshair,
|
||||
.leaflet-crosshair .leaflet-interactive {
|
||||
cursor: crosshair;
|
||||
}
|
||||
.leaflet-popup-pane,
|
||||
.leaflet-control {
|
||||
cursor: auto;
|
||||
}
|
||||
.leaflet-dragging .leaflet-grab,
|
||||
.leaflet-dragging .leaflet-grab .leaflet-interactive,
|
||||
.leaflet-dragging .leaflet-marker-draggable {
|
||||
cursor: move;
|
||||
cursor: -webkit-grabbing;
|
||||
cursor: -moz-grabbing;
|
||||
}
|
||||
|
||||
/* marker & overlays interactivity */
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow,
|
||||
.leaflet-image-layer,
|
||||
.leaflet-pane > svg path,
|
||||
.leaflet-tile-container {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.leaflet-marker-icon.leaflet-interactive,
|
||||
.leaflet-image-layer.leaflet-interactive,
|
||||
.leaflet-pane > svg path.leaflet-interactive {
|
||||
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
/* visual tweaks */
|
||||
|
||||
.leaflet-container {
|
||||
background: #ddd;
|
||||
outline: 0;
|
||||
}
|
||||
.leaflet-container a {
|
||||
color: #0078A8;
|
||||
}
|
||||
.leaflet-container a.leaflet-active {
|
||||
outline: 2px solid orange;
|
||||
}
|
||||
.leaflet-zoom-box {
|
||||
border: 2px dotted #38f;
|
||||
background: rgba(255,255,255,0.5);
|
||||
}
|
||||
|
||||
|
||||
/* general typography */
|
||||
.leaflet-container {
|
||||
font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
|
||||
/* general toolbar styles */
|
||||
|
||||
.leaflet-bar {
|
||||
box-shadow: 0 1px 5px rgba(0,0,0,0.65);
|
||||
border-radius: 4px;
|
||||
}
|
||||
.leaflet-bar a,
|
||||
.leaflet-bar a:hover {
|
||||
background-color: #fff;
|
||||
border-bottom: 1px solid #ccc;
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
display: block;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
}
|
||||
.leaflet-bar a,
|
||||
.leaflet-control-layers-toggle {
|
||||
background-position: 50% 50%;
|
||||
background-repeat: no-repeat;
|
||||
display: block;
|
||||
}
|
||||
.leaflet-bar a:hover {
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
.leaflet-bar a:first-child {
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
}
|
||||
.leaflet-bar a:last-child {
|
||||
border-bottom-left-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
border-bottom: none;
|
||||
}
|
||||
.leaflet-bar a.leaflet-disabled {
|
||||
cursor: default;
|
||||
background-color: #f4f4f4;
|
||||
color: #bbb;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-bar a {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
|
||||
/* zoom control */
|
||||
|
||||
.leaflet-control-zoom-in,
|
||||
.leaflet-control-zoom-out {
|
||||
font: bold 18px 'Lucida Console', Monaco, monospace;
|
||||
text-indent: 1px;
|
||||
}
|
||||
.leaflet-control-zoom-out {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-control-zoom-in {
|
||||
font-size: 22px;
|
||||
}
|
||||
.leaflet-touch .leaflet-control-zoom-out {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
|
||||
/* layers control */
|
||||
|
||||
.leaflet-control-layers {
|
||||
box-shadow: 0 1px 5px rgba(0,0,0,0.4);
|
||||
background: #fff;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.leaflet-control-layers-toggle {
|
||||
background-image: url(images/layers.png);
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
}
|
||||
.leaflet-retina .leaflet-control-layers-toggle {
|
||||
background-image: url(images/layers-2x.png);
|
||||
background-size: 26px 26px;
|
||||
}
|
||||
.leaflet-touch .leaflet-control-layers-toggle {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
}
|
||||
.leaflet-control-layers .leaflet-control-layers-list,
|
||||
.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
|
||||
display: none;
|
||||
}
|
||||
.leaflet-control-layers-expanded .leaflet-control-layers-list {
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
.leaflet-control-layers-expanded {
|
||||
padding: 6px 10px 6px 6px;
|
||||
color: #333;
|
||||
background: #fff;
|
||||
}
|
||||
.leaflet-control-layers-scrollbar {
|
||||
overflow-y: scroll;
|
||||
padding-right: 5px;
|
||||
}
|
||||
.leaflet-control-layers-selector {
|
||||
margin-top: 2px;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
.leaflet-control-layers label {
|
||||
display: block;
|
||||
}
|
||||
.leaflet-control-layers-separator {
|
||||
height: 0;
|
||||
border-top: 1px solid #ddd;
|
||||
margin: 5px -10px 5px -6px;
|
||||
}
|
||||
|
||||
/* Default icon URLs */
|
||||
.leaflet-default-icon-path {
|
||||
background-image: url(images/);
|
||||
}
|
||||
|
||||
|
||||
/* attribution and scale controls */
|
||||
|
||||
.leaflet-container .leaflet-control-attribution {
|
||||
background: #fff;
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
margin: 0;
|
||||
}
|
||||
.leaflet-control-attribution,
|
||||
.leaflet-control-scale-line {
|
||||
padding: 0 5px;
|
||||
color: #333;
|
||||
}
|
||||
.leaflet-control-attribution a {
|
||||
text-decoration: none;
|
||||
}
|
||||
.leaflet-control-attribution a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.leaflet-container .leaflet-control-attribution,
|
||||
.leaflet-container .leaflet-control-scale {
|
||||
font-size: 11px;
|
||||
}
|
||||
.leaflet-left .leaflet-control-scale {
|
||||
margin-left: 5px;
|
||||
}
|
||||
.leaflet-bottom .leaflet-control-scale {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.leaflet-control-scale-line {
|
||||
border: 2px solid #777;
|
||||
border-top: none;
|
||||
line-height: 1.1;
|
||||
padding: 2px 5px 1px;
|
||||
font-size: 11px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
|
||||
background: #fff;
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
.leaflet-control-scale-line:not(:first-child) {
|
||||
border-top: 2px solid #777;
|
||||
border-bottom: none;
|
||||
margin-top: -2px;
|
||||
}
|
||||
.leaflet-control-scale-line:not(:first-child):not(:last-child) {
|
||||
border-bottom: 2px solid #777;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-control-attribution,
|
||||
.leaflet-touch .leaflet-control-layers,
|
||||
.leaflet-touch .leaflet-bar {
|
||||
box-shadow: none;
|
||||
}
|
||||
.leaflet-touch .leaflet-control-layers,
|
||||
.leaflet-touch .leaflet-bar {
|
||||
border: 2px solid rgba(0,0,0,0.2);
|
||||
background-clip: padding-box;
|
||||
}
|
||||
|
||||
|
||||
/* popup */
|
||||
|
||||
.leaflet-popup {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.leaflet-popup-content-wrapper {
|
||||
padding: 1px;
|
||||
text-align: left;
|
||||
border-radius: 12px;
|
||||
}
|
||||
.leaflet-popup-content {
|
||||
margin: 13px 19px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.leaflet-popup-content p {
|
||||
margin: 18px 0;
|
||||
}
|
||||
.leaflet-popup-tip-container {
|
||||
width: 40px;
|
||||
height: 20px;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
margin-left: -20px;
|
||||
overflow: hidden;
|
||||
pointer-events: none;
|
||||
}
|
||||
.leaflet-popup-tip {
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
padding: 1px;
|
||||
|
||||
margin: -10px auto 0;
|
||||
|
||||
-webkit-transform: rotate(45deg);
|
||||
-moz-transform: rotate(45deg);
|
||||
-ms-transform: rotate(45deg);
|
||||
-o-transform: rotate(45deg);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
.leaflet-popup-content-wrapper,
|
||||
.leaflet-popup-tip {
|
||||
background: white;
|
||||
color: #333;
|
||||
box-shadow: 0 3px 14px rgba(0,0,0,0.4);
|
||||
}
|
||||
.leaflet-container a.leaflet-popup-close-button {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
padding: 4px 4px 0 0;
|
||||
border: none;
|
||||
text-align: center;
|
||||
width: 18px;
|
||||
height: 14px;
|
||||
font: 16px/14px Tahoma, Verdana, sans-serif;
|
||||
color: #c3c3c3;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
background: transparent;
|
||||
}
|
||||
.leaflet-container a.leaflet-popup-close-button:hover {
|
||||
color: #999;
|
||||
}
|
||||
.leaflet-popup-scrolled {
|
||||
overflow: auto;
|
||||
border-bottom: 1px solid #ddd;
|
||||
border-top: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.leaflet-oldie .leaflet-popup-content-wrapper {
|
||||
zoom: 1;
|
||||
}
|
||||
.leaflet-oldie .leaflet-popup-tip {
|
||||
width: 24px;
|
||||
margin: 0 auto;
|
||||
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
|
||||
filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
|
||||
}
|
||||
.leaflet-oldie .leaflet-popup-tip-container {
|
||||
margin-top: -1px;
|
||||
}
|
||||
|
||||
.leaflet-oldie .leaflet-control-zoom,
|
||||
.leaflet-oldie .leaflet-control-layers,
|
||||
.leaflet-oldie .leaflet-popup-content-wrapper,
|
||||
.leaflet-oldie .leaflet-popup-tip {
|
||||
border: 1px solid #999;
|
||||
}
|
||||
|
||||
|
||||
/* div icon */
|
||||
|
||||
.leaflet-div-icon {
|
||||
background: #fff;
|
||||
border: 1px solid #666;
|
||||
}
|
||||
|
||||
|
||||
/* Tooltip */
|
||||
/* Base styles for the element that has a tooltip */
|
||||
.leaflet-tooltip {
|
||||
position: absolute;
|
||||
padding: 6px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #fff;
|
||||
border-radius: 3px;
|
||||
color: #222;
|
||||
white-space: nowrap;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
pointer-events: none;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.4);
|
||||
}
|
||||
.leaflet-tooltip.leaflet-clickable {
|
||||
cursor: pointer;
|
||||
pointer-events: auto;
|
||||
}
|
||||
.leaflet-tooltip-top:before,
|
||||
.leaflet-tooltip-bottom:before,
|
||||
.leaflet-tooltip-left:before,
|
||||
.leaflet-tooltip-right:before {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
border: 6px solid transparent;
|
||||
background: transparent;
|
||||
content: "";
|
||||
}
|
||||
|
||||
/* Directions */
|
||||
|
||||
.leaflet-tooltip-bottom {
|
||||
margin-top: 6px;
|
||||
}
|
||||
.leaflet-tooltip-top {
|
||||
margin-top: -6px;
|
||||
}
|
||||
.leaflet-tooltip-bottom:before,
|
||||
.leaflet-tooltip-top:before {
|
||||
left: 50%;
|
||||
margin-left: -6px;
|
||||
}
|
||||
.leaflet-tooltip-top:before {
|
||||
bottom: 0;
|
||||
margin-bottom: -12px;
|
||||
border-top-color: #fff;
|
||||
}
|
||||
.leaflet-tooltip-bottom:before {
|
||||
top: 0;
|
||||
margin-top: -12px;
|
||||
margin-left: -6px;
|
||||
border-bottom-color: #fff;
|
||||
}
|
||||
.leaflet-tooltip-left {
|
||||
margin-left: -6px;
|
||||
}
|
||||
.leaflet-tooltip-right {
|
||||
margin-left: 6px;
|
||||
}
|
||||
.leaflet-tooltip-left:before,
|
||||
.leaflet-tooltip-right:before {
|
||||
top: 50%;
|
||||
margin-top: -6px;
|
||||
}
|
||||
.leaflet-tooltip-left:before {
|
||||
right: 0;
|
||||
margin-right: -12px;
|
||||
border-left-color: #fff;
|
||||
}
|
||||
.leaflet-tooltip-right:before {
|
||||
left: 0;
|
||||
margin-left: -12px;
|
||||
border-right-color: #fff;
|
||||
}
|
|
@ -0,0 +1,305 @@
|
|||
/* ================================================================== */
|
||||
/* Toolbars
|
||||
/* ================================================================== */
|
||||
|
||||
.leaflet-draw-section {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.leaflet-draw-toolbar {
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.leaflet-draw-toolbar-top {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.leaflet-draw-toolbar-notop a:first-child {
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
|
||||
.leaflet-draw-toolbar-nobottom a:last-child {
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
.leaflet-draw-toolbar a {
|
||||
background-image: url('images/spritesheet.png');
|
||||
background-image: linear-gradient(transparent, transparent), url('images/spritesheet.svg');
|
||||
background-repeat: no-repeat;
|
||||
background-size: 270px 30px;
|
||||
}
|
||||
|
||||
.leaflet-retina .leaflet-draw-toolbar a {
|
||||
background-image: url('images/spritesheet-2x.png');
|
||||
background-image: linear-gradient(transparent, transparent), url('images/spritesheet.svg');
|
||||
}
|
||||
|
||||
.leaflet-draw a {
|
||||
display: block;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
/* Toolbar actions menu
|
||||
/* ================================================================== */
|
||||
|
||||
.leaflet-draw-actions {
|
||||
display: none;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
left: 26px; /* leaflet-draw-toolbar.left + leaflet-draw-toolbar.width */
|
||||
top: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-draw-actions {
|
||||
left: 32px;
|
||||
}
|
||||
|
||||
.leaflet-right .leaflet-draw-actions {
|
||||
right:26px;
|
||||
left:auto;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-right .leaflet-draw-actions {
|
||||
right:32px;
|
||||
left:auto;
|
||||
}
|
||||
|
||||
.leaflet-draw-actions li {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.leaflet-draw-actions li:first-child a {
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
.leaflet-draw-actions li:last-child a {
|
||||
-webkit-border-radius: 0 4px 4px 0;
|
||||
border-radius: 0 4px 4px 0;
|
||||
}
|
||||
|
||||
.leaflet-right .leaflet-draw-actions li:last-child a {
|
||||
-webkit-border-radius: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.leaflet-right .leaflet-draw-actions li:first-child a {
|
||||
-webkit-border-radius: 4px 0 0 4px;
|
||||
border-radius: 4px 0 0 4px;
|
||||
}
|
||||
|
||||
.leaflet-draw-actions a {
|
||||
background-color: #919187;
|
||||
border-left: 1px solid #AAA;
|
||||
color: #FFF;
|
||||
font: 11px/19px "Helvetica Neue", Arial, Helvetica, sans-serif;
|
||||
line-height: 28px;
|
||||
text-decoration: none;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-draw-actions a {
|
||||
font-size: 12px;
|
||||
line-height: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.leaflet-draw-actions-bottom {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.leaflet-draw-actions-top {
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
||||
.leaflet-draw-actions-top a,
|
||||
.leaflet-draw-actions-bottom a {
|
||||
height: 27px;
|
||||
line-height: 27px;
|
||||
}
|
||||
|
||||
.leaflet-draw-actions a:hover {
|
||||
background-color: #A0A098;
|
||||
}
|
||||
|
||||
.leaflet-draw-actions-top.leaflet-draw-actions-bottom a {
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
/* Draw toolbar
|
||||
/* ================================================================== */
|
||||
|
||||
.leaflet-draw-toolbar .leaflet-draw-draw-polyline {
|
||||
background-position: -2px -2px;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-draw-polyline {
|
||||
background-position: 0 -1px;
|
||||
}
|
||||
|
||||
.leaflet-draw-toolbar .leaflet-draw-draw-polygon {
|
||||
background-position: -31px -2px;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-draw-polygon {
|
||||
background-position: -29px -1px;
|
||||
}
|
||||
|
||||
.leaflet-draw-toolbar .leaflet-draw-draw-rectangle {
|
||||
background-position: -62px -2px;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-draw-rectangle {
|
||||
background-position: -60px -1px;
|
||||
}
|
||||
|
||||
.leaflet-draw-toolbar .leaflet-draw-draw-circle {
|
||||
background-position: -92px -2px;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-draw-circle {
|
||||
background-position: -90px -1px;
|
||||
}
|
||||
|
||||
.leaflet-draw-toolbar .leaflet-draw-draw-marker {
|
||||
background-position: -122px -2px;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-draw-marker {
|
||||
background-position: -120px -1px;
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
/* Edit toolbar
|
||||
/* ================================================================== */
|
||||
|
||||
.leaflet-draw-toolbar .leaflet-draw-edit-edit {
|
||||
background-position: -152px -2px;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-edit-edit {
|
||||
background-position: -150px -1px;
|
||||
}
|
||||
|
||||
.leaflet-draw-toolbar .leaflet-draw-edit-remove {
|
||||
background-position: -182px -2px;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-edit-remove {
|
||||
background-position: -180px -1px;
|
||||
}
|
||||
|
||||
.leaflet-draw-toolbar .leaflet-draw-edit-edit.leaflet-disabled {
|
||||
background-position: -212px -2px;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-edit-edit.leaflet-disabled {
|
||||
background-position: -210px -1px;
|
||||
}
|
||||
|
||||
.leaflet-draw-toolbar .leaflet-draw-edit-remove.leaflet-disabled {
|
||||
background-position: -242px -2px;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-draw-toolbar .leaflet-draw-edit-remove.leaflet-disabled {
|
||||
background-position: -240px -2px;
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
/* Drawing styles
|
||||
/* ================================================================== */
|
||||
|
||||
.leaflet-mouse-marker {
|
||||
background-color: #fff;
|
||||
cursor: crosshair;
|
||||
}
|
||||
|
||||
.leaflet-draw-tooltip {
|
||||
background: rgb(54, 54, 54);
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
border: 1px solid transparent;
|
||||
-webkit-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
color: #fff;
|
||||
font: 12px/18px "Helvetica Neue", Arial, Helvetica, sans-serif;
|
||||
margin-left: 20px;
|
||||
margin-top: -21px;
|
||||
padding: 4px 8px;
|
||||
position: absolute;
|
||||
visibility: hidden;
|
||||
white-space: nowrap;
|
||||
z-index: 6;
|
||||
}
|
||||
|
||||
.leaflet-draw-tooltip:before {
|
||||
border-right: 6px solid black;
|
||||
border-right-color: rgba(0, 0, 0, 0.5);
|
||||
border-top: 6px solid transparent;
|
||||
border-bottom: 6px solid transparent;
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 7px;
|
||||
left: -7px;
|
||||
}
|
||||
|
||||
.leaflet-error-draw-tooltip {
|
||||
background-color: #F2DEDE;
|
||||
border: 1px solid #E6B6BD;
|
||||
color: #B94A48;
|
||||
}
|
||||
|
||||
.leaflet-error-draw-tooltip:before {
|
||||
border-right-color: #E6B6BD;
|
||||
}
|
||||
|
||||
.leaflet-draw-tooltip-single {
|
||||
margin-top: -12px
|
||||
}
|
||||
|
||||
.leaflet-draw-tooltip-subtext {
|
||||
color: #f8d5e4;
|
||||
}
|
||||
|
||||
.leaflet-draw-guide-dash {
|
||||
font-size: 1%;
|
||||
opacity: 0.6;
|
||||
position: absolute;
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
/* Edit styles
|
||||
/* ================================================================== */
|
||||
|
||||
.leaflet-edit-marker-selected {
|
||||
background: rgba(254, 87, 161, 0.1);
|
||||
border: 4px dashed rgba(254, 87, 161, 0.6);
|
||||
-webkit-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
.leaflet-edit-move {
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
.leaflet-edit-resize {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
/* Old IE styles
|
||||
/* ================================================================== */
|
||||
|
||||
.leaflet-oldie .leaflet-draw-toolbar {
|
||||
border: 1px solid #999;
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
.leaflet-vml-shape {
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
}
|
||||
.lvml {
|
||||
behavior: url(#default#VML);
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.leaflet-control {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.leaflet-popup-tip {
|
||||
width: 21px;
|
||||
_width: 27px;
|
||||
margin: 0 auto;
|
||||
_margin-top: -3px;
|
||||
|
||||
filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
|
||||
}
|
||||
.leaflet-popup-tip-container {
|
||||
margin-top: -1px;
|
||||
}
|
||||
.leaflet-popup-content-wrapper, .leaflet-popup-tip {
|
||||
border: 1px solid #999;
|
||||
}
|
||||
.leaflet-popup-content-wrapper {
|
||||
zoom: 1;
|
||||
}
|
||||
|
||||
.leaflet-control-zoom,
|
||||
.leaflet-control-layers {
|
||||
border: 3px solid #999;
|
||||
}
|
||||
.leaflet-control-layers-toggle {
|
||||
}
|
||||
.leaflet-control-attribution,
|
||||
.leaflet-control-layers,
|
||||
.leaflet-control-scale-line {
|
||||
background: white;
|
||||
}
|
||||
.leaflet-zoom-box {
|
||||
filter: alpha(opacity=50);
|
||||
}
|
||||
.leaflet-control-attribution {
|
||||
border-top: 1px solid #bbb;
|
||||
border-left: 1px solid #bbb;
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
.leaflet-label {
|
||||
background: rgb(235, 235, 235);
|
||||
background: rgba(235, 235, 235, 0.81);
|
||||
background-clip: padding-box;
|
||||
border-color: #777;
|
||||
border-color: rgba(0,0,0,0.25);
|
||||
border-radius: 4px;
|
||||
border-style: solid;
|
||||
border-width: 4px;
|
||||
color: #111;
|
||||
display: block;
|
||||
font: 12px/20px "Helvetica Neue", Arial, Helvetica, sans-serif;
|
||||
font-weight: bold;
|
||||
padding: 1px 6px;
|
||||
position: absolute;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
white-space: nowrap;
|
||||
z-index: 6;
|
||||
}
|
||||
|
||||
.leaflet-label.leaflet-clickable {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.leaflet-label:before {
|
||||
border-right: 6px solid black;
|
||||
border-right-color: inherit;
|
||||
border-top: 6px solid transparent;
|
||||
border-bottom: 6px solid transparent;
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
left: -10px;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
.leaflet-control-draw-measure {
|
||||
background-image: url(images/measure-control.png);
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
#hello {
|
||||
color: red;
|
||||
}
|
||||
#app-navigation *, #app-settings *{
|
||||
width:2px;
|
||||
z-index:-10;
|
||||
}
|
||||
#app-navigation, #app-settings{
|
||||
width:2px;
|
||||
}
|
||||
|
||||
#app *{
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#map *{
|
||||
box-sizing: content-box;
|
||||
}
|
||||
#gpxlist td{
|
||||
word-wrap: break-word;
|
||||
white-space: normal;
|
||||
}
|
||||
#gpxlist a{
|
||||
color: blue;
|
||||
text-decoration: underline;
|
||||
}
|
||||
/* jquery dialog */
|
||||
.ui-dialog{
|
||||
z-index: 2001 !important ;
|
||||
}
|
After Width: | Height: | Size: 54 B |
After Width: | Height: | Size: 64 B |
After Width: | Height: | Size: 54 B |
|
@ -0,0 +1,39 @@
|
|||
/* tables */
|
||||
table.tablesorter {
|
||||
font-family:arial;
|
||||
background-color: #CDCDCD;
|
||||
margin:10px 0pt 15px;
|
||||
font-size: 8pt;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
}
|
||||
table.tablesorter thead tr th, table.tablesorter tfoot tr th {
|
||||
background-color: #e6EEEE;
|
||||
border: 1px solid #FFF;
|
||||
font-size: 8pt;
|
||||
padding: 4px;
|
||||
}
|
||||
table.tablesorter thead tr .header {
|
||||
background-image: url(bg.gif);
|
||||
background-repeat: no-repeat;
|
||||
/*background-position: center right;*/
|
||||
cursor: pointer;
|
||||
}
|
||||
table.tablesorter tbody td {
|
||||
color: #3D3D3D;
|
||||
padding: 4px;
|
||||
/*background-color: #FFF;*/
|
||||
vertical-align: top;
|
||||
}
|
||||
table.tablesorter tbody tr.odd td {
|
||||
background-color:#F0F0F6;
|
||||
}
|
||||
table.tablesorter thead tr .headerSortUp {
|
||||
background-image: url(asc.gif);
|
||||
}
|
||||
table.tablesorter thead tr .headerSortDown {
|
||||
background-image: url(desc.gif);
|
||||
}
|
||||
table.tablesorter thead tr .headerSortDown, table.tablesorter thead tr .headerSortUp {
|
||||
background-color: #8dbdd8;
|
||||
}
|
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 2.6 KiB |
|
@ -0,0 +1,39 @@
|
|||
table.tablesorter {
|
||||
font-size: 12px;
|
||||
background-color: #4D4D4D;
|
||||
width: 1024px;
|
||||
border: 1px solid #000;
|
||||
}
|
||||
table.tablesorter th {
|
||||
text-align: left;
|
||||
padding: 5px;
|
||||
background-color: #6E6E6E;
|
||||
}
|
||||
table.tablesorter td {
|
||||
color: #FFF;
|
||||
padding: 5px;
|
||||
}
|
||||
table.tablesorter .even {
|
||||
background-color: #3D3D3D;
|
||||
}
|
||||
table.tablesorter .odd {
|
||||
background-color: #6E6E6E;
|
||||
}
|
||||
table.tablesorter .header {
|
||||
background-image: url(bg.png);
|
||||
background-repeat: no-repeat;
|
||||
border-left: 1px solid #FFF;
|
||||
border-right: 1px solid #000;
|
||||
border-top: 1px solid #FFF;
|
||||
padding-left: 30px;
|
||||
padding-top: 8px;
|
||||
height: auto;
|
||||
}
|
||||
table.tablesorter .headerSortUp {
|
||||
background-image: url(asc.png);
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
table.tablesorter .headerSortDown {
|
||||
background-image: url(desc.png);
|
||||
background-repeat: no-repeat;
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Layer_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
width="512px"
|
||||
height="512px"
|
||||
viewBox="0 0 512 512"
|
||||
enable-background="new 0 0 512 512"
|
||||
xml:space="preserve"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="marker.svg"><metadata
|
||||
id="metadata9"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs7" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1627"
|
||||
inkscape:window-height="951"
|
||||
id="namedview5"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.3037281"
|
||||
inkscape:cx="218.74462"
|
||||
inkscape:cy="239.15819"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="Layer_1" /><path
|
||||
d="M256,0C149.969,0,64,85.969,64,192s160,320,192,320s192-213.969,192-320S362.031,0,256,0z M256,320 c-70.594,0-128-57.438-128-128S185.406,64,256,64s128,57.438,128,128S326.594,320,256,320z"
|
||||
id="path3"
|
||||
style="fill:#b3b3b3" /><path
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#ff0000;stroke-width:0.87785804;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:1.75571607, 0.87785804;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="M 248.91673,509.24858 C 230.56801,500.07962 190.87269,454.55414 154.79361,401.30133 109.09773,333.85411 77.634458,268.76261 67.562633,220.8371 64.476451,206.15189 63.704442,185.37191 65.653374,169.44602 70.933923,126.29547 89.916923,87.289393 120.53926,56.667063 142.55287,34.653457 168.02941,18.997898 197.14663,9.5911583 c 20.07226,-6.4846296 36.32789,-8.96099834 58.799,-8.9573893 15.82056,0.002539 25.20235,0.8786925 38.58779,3.6036552 29.27974,5.9606698 57.25814,19.1024518 81.56571,38.3123618 7.16255,5.660455 23.62029,22.091106 29.14775,29.099766 27.68995,35.110068 42.05754,75.520398 42.11426,118.450638 0.0195,14.72113 -1.17042,24.05266 -5.0755,39.80466 -11.10768,44.80527 -40.59037,104.78432 -81.74458,166.29964 -43.60715,65.18186 -89.02708,115.3374 -104.44742,115.3374 -1.42318,0 -4.65279,-1.03199 -7.17691,-2.29331 z m 17.32829,-189.48636 c 45.4822,-4.02553 84.13475,-30.21804 104.50975,-70.81996 14.09646,-28.09048 17.18704,-60.24088 8.76327,-91.16176 -12.35905,-45.36594 -50.51518,-81.408176 -96.45838,-91.114479 -22.97888,-4.854691 -45.10067,-3.602599 -67.45932,3.818196 -67.1219,22.277628 -103.60883,95.090683 -81.20728,162.056633 14.25716,42.61957 49.88481,74.72409 93.7963,84.52101 14.09633,3.14498 24.60623,3.89074 38.05566,2.70036 z"
|
||||
id="path3333"
|
||||
inkscape:connector-curvature="0" /></svg>
|
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 1.7 KiB |
|
@ -0,0 +1,137 @@
|
|||
/**
|
||||
* Created: vogdb Date: 5/4/13 Time: 1:54 PM
|
||||
* Version: 0.3.0
|
||||
*/
|
||||
|
||||
L.Control.ActiveLayers = L.Control.Layers.extend({
|
||||
|
||||
/**
|
||||
* Get currently active base layer on the map
|
||||
* @return {Object} l where l.name - layer name on the control,
|
||||
* l.layer is L.TileLayer, l.overlay is overlay layer.
|
||||
*/
|
||||
getActiveBaseLayer: function () {
|
||||
return this._activeBaseLayer
|
||||
},
|
||||
|
||||
/**
|
||||
* Get currently active overlay layers on the map
|
||||
* @return {{layerId: l}} where layerId is <code>L.stamp(l.layer)</code>
|
||||
* and l @see #getActiveBaseLayer jsdoc.
|
||||
*/
|
||||
getActiveOverlayLayers: function () {
|
||||
return this._activeOverlayLayers
|
||||
},
|
||||
|
||||
onAdd: function (map) {
|
||||
var container = L.Control.Layers.prototype.onAdd.call(this, map)
|
||||
|
||||
if (Array.isArray(this._layers)) {
|
||||
this._activeBaseLayer = this._findActiveBaseLayer()
|
||||
this._activeOverlayLayers = this._findActiveOverlayLayers()
|
||||
} else { // 0.7.x
|
||||
this._activeBaseLayer = this._findActiveBaseLayerLegacy()
|
||||
this._activeOverlayLayers = this._findActiveOverlayLayersLegacy()
|
||||
}
|
||||
return container
|
||||
},
|
||||
|
||||
_findActiveBaseLayer: function () {
|
||||
var layers = this._layers
|
||||
for (var i = 0; i < layers.length; i++) {
|
||||
var layer = layers[i]
|
||||
if (!layer.overlay && this._map.hasLayer(layer.layer)) {
|
||||
return layer
|
||||
}
|
||||
}
|
||||
throw new Error('Control doesn\'t have any active base layer!')
|
||||
},
|
||||
|
||||
_findActiveOverlayLayers: function () {
|
||||
var result = {}
|
||||
var layers = this._layers
|
||||
for (var i = 0; i < layers.length; i++) {
|
||||
var layer = layers[i]
|
||||
if (layer.overlay && this._map.hasLayer(layer.layer)) {
|
||||
result[layer.layer._leaflet_id] = layer
|
||||
}
|
||||
}
|
||||
return result
|
||||
},
|
||||
|
||||
/**
|
||||
* Legacy 0.7.x support methods
|
||||
*/
|
||||
_findActiveBaseLayerLegacy: function () {
|
||||
var layers = this._layers
|
||||
for (var layerId in layers) {
|
||||
if (this._layers.hasOwnProperty(layerId)) {
|
||||
var layer = layers[layerId]
|
||||
if (!layer.overlay && this._map.hasLayer(layer.layer)) {
|
||||
return layer
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new Error('Control doesn\'t have any active base layer!')
|
||||
},
|
||||
|
||||
_findActiveOverlayLayersLegacy: function () {
|
||||
var result = {}
|
||||
var layers = this._layers
|
||||
for (var layerId in layers) {
|
||||
if (this._layers.hasOwnProperty(layerId)) {
|
||||
var layer = layers[layerId]
|
||||
if (layer.overlay && this._map.hasLayer(layer.layer)) {
|
||||
result[layerId] = layer
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
},
|
||||
|
||||
_onLayerChange: function () {
|
||||
L.Control.Layers.prototype._onLayerChange.apply(this, arguments)
|
||||
this._recountLayers()
|
||||
},
|
||||
|
||||
_onInputClick: function () {
|
||||
this._handlingClick = true
|
||||
|
||||
this._recountLayers()
|
||||
L.Control.Layers.prototype._onInputClick.call(this)
|
||||
|
||||
this._handlingClick = false
|
||||
},
|
||||
|
||||
_recountLayers: function () {
|
||||
var i, input, obj,
|
||||
inputs = this._form.getElementsByTagName('input'),
|
||||
inputsLen = inputs.length;
|
||||
|
||||
for (i = 0; i < inputsLen; i++) {
|
||||
input = inputs[i]
|
||||
if (Array.isArray(this._layers)) {
|
||||
obj = this._layers[i]
|
||||
} else {
|
||||
obj = this._layers[input.layerId] // 0.7.x
|
||||
}
|
||||
|
||||
if (input.checked && !this._map.hasLayer(obj.layer)) {
|
||||
if (obj.overlay) {
|
||||
this._activeOverlayLayers[input.layerId] = obj
|
||||
} else {
|
||||
this._activeBaseLayer = obj
|
||||
}
|
||||
} else if (!input.checked && this._map.hasLayer(obj.layer)) {
|
||||
if (obj.overlay) {
|
||||
delete this._activeOverlayLayers[input.layerId]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
L.control.activeLayers = function (baseLayers, overlays, options) {
|
||||
return new L.Control.ActiveLayers(baseLayers, overlays, options)
|
||||
}
|
|
@ -0,0 +1,739 @@
|
|||
(function (factory) {
|
||||
// Packaging/modules magic dance
|
||||
var L;
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// AMD
|
||||
define(['leaflet'], factory);
|
||||
} else if (typeof module !== 'undefined') {
|
||||
// Node/CommonJS
|
||||
L = require('leaflet');
|
||||
module.exports = factory(L);
|
||||
} else {
|
||||
// Browser globals
|
||||
if (typeof window.L === 'undefined')
|
||||
throw 'Leaflet must be loaded first';
|
||||
factory(window.L);
|
||||
}
|
||||
}(function (L) {
|
||||
'use strict';
|
||||
L.Control.Geocoder = L.Control.extend({
|
||||
options: {
|
||||
showResultIcons: false,
|
||||
collapsed: true,
|
||||
expand: 'click',
|
||||
position: 'topright',
|
||||
placeholder: 'Search...',
|
||||
errorMessage: 'Nothing found.'
|
||||
},
|
||||
|
||||
_callbackId: 0,
|
||||
|
||||
initialize: function (options) {
|
||||
L.Util.setOptions(this, options);
|
||||
if (!this.options.geocoder) {
|
||||
this.options.geocoder = new L.Control.Geocoder.Nominatim();
|
||||
}
|
||||
},
|
||||
|
||||
onAdd: function (map) {
|
||||
var className = 'leaflet-control-geocoder',
|
||||
container = L.DomUtil.create('div', className),
|
||||
icon = L.DomUtil.create('div', 'leaflet-control-geocoder-icon', container),
|
||||
form = this._form = L.DomUtil.create('form', className + '-form', container),
|
||||
input;
|
||||
|
||||
this._map = map;
|
||||
this._container = container;
|
||||
input = this._input = L.DomUtil.create('input');
|
||||
input.type = 'text';
|
||||
input.placeholder = this.options.placeholder;
|
||||
|
||||
L.DomEvent.addListener(input, 'keydown', this._keydown, this);
|
||||
//L.DomEvent.addListener(input, 'onpaste', this._clearResults, this);
|
||||
//L.DomEvent.addListener(input, 'oninput', this._clearResults, this);
|
||||
|
||||
this._errorElement = document.createElement('div');
|
||||
this._errorElement.className = className + '-form-no-error';
|
||||
this._errorElement.innerHTML = this.options.errorMessage;
|
||||
|
||||
this._alts = L.DomUtil.create('ul', className + '-alternatives leaflet-control-geocoder-alternatives-minimized');
|
||||
|
||||
form.appendChild(input);
|
||||
form.appendChild(this._errorElement);
|
||||
container.appendChild(this._alts);
|
||||
|
||||
L.DomEvent.addListener(form, 'submit', this._geocode, this);
|
||||
|
||||
if (this.options.collapsed) {
|
||||
if (this.options.expand === 'click') {
|
||||
L.DomEvent.addListener(icon, 'click', function(e) {
|
||||
// TODO: touch
|
||||
if (e.button === 0 && e.detail !== 2) {
|
||||
this._toggle();
|
||||
}
|
||||
}, this);
|
||||
} else {
|
||||
L.DomEvent.addListener(icon, 'mouseover', this._expand, this);
|
||||
L.DomEvent.addListener(icon, 'mouseout', this._collapse, this);
|
||||
this._map.on('movestart', this._collapse, this);
|
||||
}
|
||||
} else {
|
||||
this._expand();
|
||||
}
|
||||
|
||||
L.DomEvent.disableClickPropagation(container);
|
||||
|
||||
return container;
|
||||
},
|
||||
|
||||
_geocodeResult: function (results) {
|
||||
L.DomUtil.removeClass(this._container, 'leaflet-control-geocoder-throbber');
|
||||
if (results.length === 1) {
|
||||
this._geocodeResultSelected(results[0]);
|
||||
} else if (results.length > 0) {
|
||||
this._alts.innerHTML = '';
|
||||
this._results = results;
|
||||
L.DomUtil.removeClass(this._alts, 'leaflet-control-geocoder-alternatives-minimized');
|
||||
for (var i = 0; i < results.length; i++) {
|
||||
this._alts.appendChild(this._createAlt(results[i], i));
|
||||
}
|
||||
} else {
|
||||
L.DomUtil.addClass(this._errorElement, 'leaflet-control-geocoder-error');
|
||||
}
|
||||
},
|
||||
|
||||
markGeocode: function(result) {
|
||||
this._map.fitBounds(result.bbox);
|
||||
|
||||
if (this._geocodeMarker) {
|
||||
this._map.removeLayer(this._geocodeMarker);
|
||||
}
|
||||
|
||||
this._geocodeMarker = new L.Marker(result.center)
|
||||
.bindPopup(result.html || result.name)
|
||||
.addTo(this._map)
|
||||
.openPopup();
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
_geocode: function(event) {
|
||||
L.DomEvent.preventDefault(event);
|
||||
|
||||
L.DomUtil.addClass(this._container, 'leaflet-control-geocoder-throbber');
|
||||
this._clearResults();
|
||||
this.options.geocoder.geocode(this._input.value, this._geocodeResult, this);
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
_geocodeResultSelected: function(result) {
|
||||
if (this.options.collapsed) {
|
||||
this._collapse();
|
||||
} else {
|
||||
this._clearResults();
|
||||
}
|
||||
this.markGeocode(result);
|
||||
},
|
||||
|
||||
_toggle: function() {
|
||||
if (this._container.className.indexOf('leaflet-control-geocoder-expanded') >= 0) {
|
||||
this._collapse();
|
||||
} else {
|
||||
this._expand();
|
||||
}
|
||||
},
|
||||
|
||||
_expand: function () {
|
||||
L.DomUtil.addClass(this._container, 'leaflet-control-geocoder-expanded');
|
||||
this._input.select();
|
||||
},
|
||||
|
||||
_collapse: function () {
|
||||
this._container.className = this._container.className.replace(' leaflet-control-geocoder-expanded', '');
|
||||
L.DomUtil.addClass(this._alts, 'leaflet-control-geocoder-alternatives-minimized');
|
||||
L.DomUtil.removeClass(this._errorElement, 'leaflet-control-geocoder-error');
|
||||
},
|
||||
|
||||
_clearResults: function () {
|
||||
L.DomUtil.addClass(this._alts, 'leaflet-control-geocoder-alternatives-minimized');
|
||||
this._selection = null;
|
||||
L.DomUtil.removeClass(this._errorElement, 'leaflet-control-geocoder-error');
|
||||
},
|
||||
|
||||
_createAlt: function(result, index) {
|
||||
var li = document.createElement('li'),
|
||||
a = L.DomUtil.create('a', '', li),
|
||||
icon = this.options.showResultIcons && result.icon ? L.DomUtil.create('img', '', a) : null,
|
||||
text = result.html ? undefined : document.createTextNode(result.name);
|
||||
|
||||
if (icon) {
|
||||
icon.src = result.icon;
|
||||
}
|
||||
|
||||
a.href = '#';
|
||||
a.setAttribute('data-result-index', index);
|
||||
|
||||
if (result.html) {
|
||||
a.innerHTML = result.html;
|
||||
} else {
|
||||
a.appendChild(text);
|
||||
}
|
||||
|
||||
L.DomEvent.addListener(li, 'click', function clickHandler(e) {
|
||||
L.DomEvent.preventDefault(e);
|
||||
this._geocodeResultSelected(result);
|
||||
}, this);
|
||||
|
||||
return li;
|
||||
},
|
||||
|
||||
_keydown: function(e) {
|
||||
var _this = this,
|
||||
select = function select(dir) {
|
||||
if (_this._selection) {
|
||||
L.DomUtil.removeClass(_this._selection.firstChild, 'leaflet-control-geocoder-selected');
|
||||
_this._selection = _this._selection[dir > 0 ? 'nextSibling' : 'previousSibling'];
|
||||
}
|
||||
if (!_this._selection) {
|
||||
_this._selection = _this._alts[dir > 0 ? 'firstChild' : 'lastChild'];
|
||||
}
|
||||
|
||||
if (_this._selection) {
|
||||
L.DomUtil.addClass(_this._selection.firstChild, 'leaflet-control-geocoder-selected');
|
||||
}
|
||||
};
|
||||
|
||||
switch (e.keyCode) {
|
||||
// Escape
|
||||
case 27:
|
||||
if (this.options.collapsed) {
|
||||
this._collapse();
|
||||
}
|
||||
break;
|
||||
// Up
|
||||
case 38:
|
||||
select(-1);
|
||||
L.DomEvent.preventDefault(e);
|
||||
break;
|
||||
// Up
|
||||
case 40:
|
||||
select(1);
|
||||
L.DomEvent.preventDefault(e);
|
||||
break;
|
||||
// Enter
|
||||
case 13:
|
||||
if (this._selection) {
|
||||
var index = parseInt(this._selection.firstChild.getAttribute('data-result-index'), 10);
|
||||
this._geocodeResultSelected(this._results[index]);
|
||||
this._clearResults();
|
||||
L.DomEvent.preventDefault(e);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
L.Control.geocoder = function(id, options) {
|
||||
return new L.Control.Geocoder(id, options);
|
||||
};
|
||||
|
||||
L.Control.Geocoder.callbackId = 0;
|
||||
L.Control.Geocoder.jsonp = function(url, params, callback, context, jsonpParam) {
|
||||
var callbackId = '_l_geocoder_' + (L.Control.Geocoder.callbackId++);
|
||||
params[jsonpParam || 'callback'] = callbackId;
|
||||
window[callbackId] = L.Util.bind(callback, context);
|
||||
var script = document.createElement('script');
|
||||
script.type = 'text/javascript';
|
||||
script.src = url + L.Util.getParamString(params);
|
||||
script.id = callbackId;
|
||||
document.getElementsByTagName('head')[0].appendChild(script);
|
||||
};
|
||||
L.Control.Geocoder.getJSON = function(url, params, callback) {
|
||||
var xmlHttp = new XMLHttpRequest();
|
||||
xmlHttp.open( "GET", url + L.Util.getParamString(params), true);
|
||||
xmlHttp.send(null);
|
||||
xmlHttp.onreadystatechange = function () {
|
||||
if (xmlHttp.readyState != 4) return;
|
||||
if (xmlHttp.status != 200 && req.status != 304) return;
|
||||
callback(JSON.parse(xmlHttp.response));
|
||||
};
|
||||
};
|
||||
|
||||
L.Control.Geocoder.template = function (str, data, htmlEscape) {
|
||||
return str.replace(/\{ *([\w_]+) *\}/g, function (str, key) {
|
||||
var value = data[key];
|
||||
if (value === undefined) {
|
||||
value = '';
|
||||
} else if (typeof value === 'function') {
|
||||
value = value(data);
|
||||
}
|
||||
return L.Control.Geocoder.htmlEscape(value);
|
||||
});
|
||||
};
|
||||
|
||||
// Adapted from handlebars.js
|
||||
// https://github.com/wycats/handlebars.js/
|
||||
L.Control.Geocoder.htmlEscape = (function() {
|
||||
var badChars = /[&<>"'`]/g;
|
||||
var possible = /[&<>"'`]/;
|
||||
var escape = {
|
||||
'&': '&',
|
||||
'<': '<',
|
||||
'>': '>',
|
||||
'"': '"',
|
||||
'\'': ''',
|
||||
'`': '`'
|
||||
};
|
||||
|
||||
function escapeChar(chr) {
|
||||
return escape[chr];
|
||||
}
|
||||
|
||||
return function(string) {
|
||||
if (string == null) {
|
||||
return '';
|
||||
} else if (!string) {
|
||||
return string + '';
|
||||
}
|
||||
|
||||
// Force a string conversion as this will be done by the append regardless and
|
||||
// the regex test will do this transparently behind the scenes, causing issues if
|
||||
// an object's to string has escaped characters in it.
|
||||
string = '' + string;
|
||||
|
||||
if (!possible.test(string)) {
|
||||
return string;
|
||||
}
|
||||
return string.replace(badChars, escapeChar);
|
||||
};
|
||||
})();
|
||||
|
||||
L.Control.Geocoder.Nominatim = L.Class.extend({
|
||||
options: {
|
||||
serviceUrl: '//nominatim.openstreetmap.org/',
|
||||
geocodingQueryParams: {},
|
||||
reverseQueryParams: {},
|
||||
htmlTemplate: function(r) {
|
||||
var a = r.address,
|
||||
parts = [];
|
||||
if (a.road || a.building) {
|
||||
parts.push('{building} {road} {house_number}');
|
||||
}
|
||||
|
||||
if (a.city || a.town || a.village) {
|
||||
parts.push('<span class="' + (parts.length > 0 ? 'leaflet-control-geocoder-address-detail' : '') +
|
||||
'">{postcode} {city} {town} {village}</span>');
|
||||
}
|
||||
|
||||
if (a.state || a.country) {
|
||||
parts.push('<span class="' + (parts.length > 0 ? 'leaflet-control-geocoder-address-context' : '') +
|
||||
'">{state} {country}</span>');
|
||||
}
|
||||
|
||||
return L.Control.Geocoder.template(parts.join('<br/>'), a, true);
|
||||
}
|
||||
},
|
||||
|
||||
initialize: function(options) {
|
||||
L.Util.setOptions(this, options);
|
||||
},
|
||||
|
||||
geocode: function(query, cb, context) {
|
||||
L.Control.Geocoder.jsonp(this.options.serviceUrl + 'search/', L.extend({
|
||||
q: query,
|
||||
limit: 5,
|
||||
format: 'json',
|
||||
addressdetails: 1
|
||||
}, this.options.geocodingQueryParams),
|
||||
function(data) {
|
||||
var results = [];
|
||||
for (var i = data.length - 1; i >= 0; i--) {
|
||||
var bbox = data[i].boundingbox;
|
||||
for (var j = 0; j < 4; j++) bbox[j] = parseFloat(bbox[j]);
|
||||
results[i] = {
|
||||
icon: data[i].icon,
|
||||
name: data[i].display_name,
|
||||
html: this.options.htmlTemplate ?
|
||||
this.options.htmlTemplate(data[i])
|
||||
: undefined,
|
||||
bbox: L.latLngBounds([bbox[0], bbox[2]], [bbox[1], bbox[3]]),
|
||||
center: L.latLng(data[i].lat, data[i].lon),
|
||||
properties: data[i]
|
||||
};
|
||||
}
|
||||
cb.call(context, results);
|
||||
}, this, 'json_callback');
|
||||
},
|
||||
|
||||
reverse: function(location, scale, cb, context) {
|
||||
L.Control.Geocoder.jsonp(this.options.serviceUrl + 'reverse/', L.extend({
|
||||
lat: location.lat,
|
||||
lon: location.lng,
|
||||
zoom: Math.round(Math.log(scale / 256) / Math.log(2)),
|
||||
addressdetails: 1,
|
||||
format: 'json'
|
||||
}, this.options.reverseQueryParams), function(data) {
|
||||
var result = [],
|
||||
loc;
|
||||
|
||||
if (data && data.lat && data.lon) {
|
||||
loc = L.latLng(data.lat, data.lon);
|
||||
result.push({
|
||||
name: data.display_name,
|
||||
html: this.options.htmlTemplate ?
|
||||
this.options.htmlTemplate(data)
|
||||
: undefined,
|
||||
center: loc,
|
||||
bounds: L.latLngBounds(loc, loc),
|
||||
properties: data
|
||||
});
|
||||
}
|
||||
|
||||
cb.call(context, result);
|
||||
}, this, 'json_callback');
|
||||
}
|
||||
});
|
||||
|
||||
L.Control.Geocoder.nominatim = function(options) {
|
||||
return new L.Control.Geocoder.Nominatim(options);
|
||||
};
|
||||
|
||||
L.Control.Geocoder.Bing = L.Class.extend({
|
||||
initialize: function(key) {
|
||||
this.key = key;
|
||||
},
|
||||
|
||||
geocode : function (query, cb, context) {
|
||||
L.Control.Geocoder.jsonp('//dev.virtualearth.net/REST/v1/Locations', {
|
||||
query: query,
|
||||
key : this.key
|
||||
}, function(data) {
|
||||
var results = [];
|
||||
for (var i = data.resourceSets[0].resources.length - 1; i >= 0; i--) {
|
||||
var resource = data.resourceSets[0].resources[i],
|
||||
bbox = resource.bbox;
|
||||
results[i] = {
|
||||
name: resource.name,
|
||||
bbox: L.latLngBounds([bbox[0], bbox[1]], [bbox[2], bbox[3]]),
|
||||
center: L.latLng(resource.point.coordinates)
|
||||
};
|
||||
}
|
||||
cb.call(context, results);
|
||||
}, this, 'jsonp');
|
||||
},
|
||||
|
||||
reverse: function(location, scale, cb, context) {
|
||||
L.Control.Geocoder.jsonp('//dev.virtualearth.net/REST/v1/Locations/' + location.lat + ',' + location.lng, {
|
||||
key : this.key
|
||||
}, function(data) {
|
||||
var results = [];
|
||||
for (var i = data.resourceSets[0].resources.length - 1; i >= 0; i--) {
|
||||
var resource = data.resourceSets[0].resources[i],
|
||||
bbox = resource.bbox;
|
||||
results[i] = {
|
||||
name: resource.name,
|
||||
bbox: L.latLngBounds([bbox[0], bbox[1]], [bbox[2], bbox[3]]),
|
||||
center: L.latLng(resource.point.coordinates)
|
||||
};
|
||||
}
|
||||
cb.call(context, results);
|
||||
}, this, 'jsonp');
|
||||
}
|
||||
});
|
||||
|
||||
L.Control.Geocoder.bing = function(key) {
|
||||
return new L.Control.Geocoder.Bing(key);
|
||||
};
|
||||
|
||||
L.Control.Geocoder.RaveGeo = L.Class.extend({
|
||||
options: {
|
||||
querySuffix: '',
|
||||
deepSearch: true,
|
||||
wordBased: false
|
||||
},
|
||||
|
||||
jsonp: function(params, callback, context) {
|
||||
var callbackId = '_l_geocoder_' + (L.Control.Geocoder.callbackId++),
|
||||
paramParts = [];
|
||||
params.prepend = callbackId + '(';
|
||||
params.append = ')';
|
||||
for (var p in params) {
|
||||
paramParts.push(p + '=' + escape(params[p]));
|
||||
}
|
||||
|
||||
window[callbackId] = L.Util.bind(callback, context);
|
||||
var script = document.createElement('script');
|
||||
script.type = 'text/javascript';
|
||||
script.src = this._serviceUrl + '?' + paramParts.join('&');
|
||||
script.id = callbackId;
|
||||
document.getElementsByTagName('head')[0].appendChild(script);
|
||||
},
|
||||
|
||||
initialize: function(serviceUrl, scheme, options) {
|
||||
L.Util.setOptions(this, options);
|
||||
|
||||
this._serviceUrl = serviceUrl;
|
||||
this._scheme = scheme;
|
||||
},
|
||||
|
||||
geocode: function(query, cb, context) {
|
||||
L.Control.Geocoder.jsonp(this._serviceUrl, {
|
||||
address: query + this.options.querySuffix,
|
||||
scheme: this._scheme,
|
||||
outputFormat: 'jsonp',
|
||||
deepSearch: this.options.deepSearch,
|
||||
wordBased: this.options.wordBased
|
||||
}, function(data) {
|
||||
var results = [];
|
||||
for (var i = data.length - 1; i >= 0; i--) {
|
||||
var r = data[i],
|
||||
c = L.latLng(r.y, r.x);
|
||||
results[i] = {
|
||||
name: r.address,
|
||||
bbox: L.latLngBounds([c]),
|
||||
center: c
|
||||
};
|
||||
}
|
||||
cb.call(context, results);
|
||||
}, this);
|
||||
}
|
||||
});
|
||||
|
||||
L.Control.Geocoder.raveGeo = function(serviceUrl, scheme, options) {
|
||||
return new L.Control.Geocoder.RaveGeo(serviceUrl, scheme, options);
|
||||
};
|
||||
|
||||
L.Control.Geocoder.MapQuest = L.Class.extend({
|
||||
initialize: function(key) {
|
||||
// MapQuest seems to provide URI encoded API keys,
|
||||
// so to avoid encoding them twice, we decode them here
|
||||
this._key = decodeURIComponent(key);
|
||||
},
|
||||
|
||||
_formatName: function() {
|
||||
var r = [],
|
||||
i;
|
||||
for (i = 0; i < arguments.length; i++) {
|
||||
if (arguments[i]) {
|
||||
r.push(arguments[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return r.join(', ');
|
||||
},
|
||||
|
||||
geocode: function(query, cb, context) {
|
||||
L.Control.Geocoder.jsonp('//www.mapquestapi.com/geocoding/v1/address', {
|
||||
key: this._key,
|
||||
location: query,
|
||||
limit: 5,
|
||||
outFormat: 'json'
|
||||
}, function(data) {
|
||||
var results = [],
|
||||
loc,
|
||||
latLng;
|
||||
if (data.results && data.results[0].locations) {
|
||||
for (var i = data.results[0].locations.length - 1; i >= 0; i--) {
|
||||
loc = data.results[0].locations[i];
|
||||
latLng = L.latLng(loc.latLng);
|
||||
results[i] = {
|
||||
name: this._formatName(loc.street, loc.adminArea4, loc.adminArea3, loc.adminArea1),
|
||||
bbox: L.latLngBounds(latLng, latLng),
|
||||
center: latLng
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
cb.call(context, results);
|
||||
}, this);
|
||||
},
|
||||
|
||||
reverse: function(location, scale, cb, context) {
|
||||
L.Control.Geocoder.jsonp('//www.mapquestapi.com/geocoding/v1/reverse', {
|
||||
key: this._key,
|
||||
location: location.lat + ',' + location.lng,
|
||||
outputFormat: 'json'
|
||||
}, function(data) {
|
||||
var results = [],
|
||||
loc,
|
||||
latLng;
|
||||
if (data.results && data.results[0].locations) {
|
||||
for (var i = data.results[0].locations.length - 1; i >= 0; i--) {
|
||||
loc = data.results[0].locations[i];
|
||||
latLng = L.latLng(loc.latLng);
|
||||
results[i] = {
|
||||
name: this._formatName(loc.street, loc.adminArea4, loc.adminArea3, loc.adminArea1),
|
||||
bbox: L.latLngBounds(latLng, latLng),
|
||||
center: latLng
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
cb.call(context, results);
|
||||
}, this);
|
||||
}
|
||||
});
|
||||
|
||||
L.Control.Geocoder.mapQuest = function(key) {
|
||||
return new L.Control.Geocoder.MapQuest(key);
|
||||
};
|
||||
|
||||
L.Control.Geocoder.Mapbox = L.Class.extend({
|
||||
options: {
|
||||
service_url: 'https://api.tiles.mapbox.com/v4/geocode/mapbox.places-v1/'
|
||||
},
|
||||
|
||||
initialize: function(access_token) {
|
||||
this._access_token = access_token;
|
||||
},
|
||||
|
||||
geocode: function(query, cb, context) {
|
||||
L.Control.Geocoder.getJSON(this.options.service_url + encodeURIComponent(query) + '.json', {
|
||||
access_token: this._access_token,
|
||||
}, function(data) {
|
||||
var results = [],
|
||||
loc,
|
||||
latLng,
|
||||
latLngBounds;
|
||||
if (data.features && data.features.length) {
|
||||
for (var i = 0; i <= data.features.length - 1; i++) {
|
||||
loc = data.features[i];
|
||||
latLng = L.latLng(loc.center.reverse());
|
||||
if(loc.hasOwnProperty('bbox'))
|
||||
{
|
||||
latLngBounds = L.latLngBounds(L.latLng(loc.bbox.slice(0, 2).reverse()), L.latLng(loc.bbox.slice(2, 4).reverse()));
|
||||
}
|
||||
else
|
||||
{
|
||||
latLngBounds = L.latLngBounds(latLng, latLng);
|
||||
}
|
||||
results[i] = {
|
||||
name: loc.place_name,
|
||||
bbox: latLngBounds,
|
||||
center: latLng
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
cb.call(context, results);
|
||||
});
|
||||
},
|
||||
|
||||
suggest: function(query, cb, context) {
|
||||
return this.geocode(query, cb, context);
|
||||
},
|
||||
|
||||
reverse: function(location, scale, cb, context) {
|
||||
L.Control.Geocoder.getJSON(this.options.service_url + encodeURIComponent(location.lng) + ',' + encodeURIComponent(location.lat) + '.json', {
|
||||
access_token: this._access_token,
|
||||
}, function(data) {
|
||||
var results = [],
|
||||
loc,
|
||||
latLng,
|
||||
latLngBounds;
|
||||
if (data.features && data.features.length) {
|
||||
for (var i = 0; i <= data.features.length - 1; i++) {
|
||||
loc = data.features[i];
|
||||
latLng = L.latLng(loc.center.reverse());
|
||||
if(loc.hasOwnProperty('bbox'))
|
||||
{
|
||||
latLngBounds = L.latLngBounds(L.latLng(loc.bbox.slice(0, 2).reverse()), L.latLng(loc.bbox.slice(2, 4).reverse()));
|
||||
}
|
||||
else
|
||||
{
|
||||
latLngBounds = L.latLngBounds(latLng, latLng);
|
||||
}
|
||||
results[i] = {
|
||||
name: loc.place_name,
|
||||
bbox: latLngBounds,
|
||||
center: latLng
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
cb.call(context, results);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
L.Control.Geocoder.mapbox = function(access_token) {
|
||||
return new L.Control.Geocoder.Mapbox(access_token);
|
||||
};
|
||||
|
||||
L.Control.Geocoder.Google = L.Class.extend({
|
||||
options: {
|
||||
service_url: 'https://maps.googleapis.com/maps/api/geocode/json'
|
||||
},
|
||||
|
||||
initialize: function(key) {
|
||||
this._key = key;
|
||||
},
|
||||
|
||||
geocode: function(query, cb, context) {
|
||||
var params = {
|
||||
address: query,
|
||||
};
|
||||
if(this._key && this._key.length)
|
||||
{
|
||||
params['key'] = this._key
|
||||
}
|
||||
|
||||
L.Control.Geocoder.getJSON(this.options.service_url, params, function(data) {
|
||||
var results = [],
|
||||
loc,
|
||||
latLng,
|
||||
latLngBounds;
|
||||
if (data.results && data.results.length) {
|
||||
for (var i = 0; i <= data.results.length - 1; i++) {
|
||||
loc = data.results[i];
|
||||
latLng = L.latLng(loc.geometry.location);
|
||||
latLngBounds = L.latLngBounds(L.latLng(loc.geometry.viewport.northeast), L.latLng(loc.geometry.viewport.southwest));
|
||||
results[i] = {
|
||||
name: loc.formatted_address,
|
||||
bbox: latLngBounds,
|
||||
center: latLng
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
cb.call(context, results);
|
||||
});
|
||||
},
|
||||
|
||||
reverse: function(location, scale, cb, context) {
|
||||
var params = {
|
||||
latlng: encodeURIComponent(location.lat) + ',' + encodeURIComponent(location.lng)
|
||||
};
|
||||
if(this._key && this._key.length)
|
||||
{
|
||||
params['key'] = this._key
|
||||
}
|
||||
L.Control.Geocoder.getJSON(this.options.service_url, params, function(data) {
|
||||
var results = [],
|
||||
loc,
|
||||
latLng,
|
||||
latLngBounds;
|
||||
if (data.results && data.results.length) {
|
||||
for (var i = 0; i <= data.results.length - 1; i++) {
|
||||
loc = data.results[i];
|
||||
latLng = L.latLng(loc.geometry.location);
|
||||
latLngBounds = L.latLngBounds(L.latLng(loc.geometry.viewport.northeast), L.latLng(loc.geometry.viewport.southwest));
|
||||
results[i] = {
|
||||
name: loc.formatted_address,
|
||||
bbox: latLngBounds,
|
||||
center: latLng
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
cb.call(context, results);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
L.Control.Geocoder.google = function(key) {
|
||||
return new L.Control.Geocoder.Google(key);
|
||||
};
|
||||
return L.Control.Geocoder;
|
||||
}));
|
|
@ -0,0 +1,331 @@
|
|||
// Following https://github.com/Leaflet/Leaflet/blob/master/PLUGIN-GUIDE.md
|
||||
(function (factory, window) {
|
||||
|
||||
// define an AMD module that relies on 'leaflet'
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define(['leaflet'], factory);
|
||||
|
||||
// define a Common JS module that relies on 'leaflet'
|
||||
} else if (typeof exports === 'object') {
|
||||
module.exports = factory(require('leaflet'));
|
||||
}
|
||||
|
||||
// attach your plugin to the global 'L' variable
|
||||
if (typeof window !== 'undefined' && window.L) {
|
||||
window.L.Control.MiniMap = factory(L);
|
||||
window.L.control.minimap = function (layer, options) {
|
||||
return new window.L.Control.MiniMap(layer, options);
|
||||
};
|
||||
}
|
||||
}(function (L) {
|
||||
|
||||
var MiniMap = L.Control.extend({
|
||||
options: {
|
||||
position: 'bottomright',
|
||||
toggleDisplay: false,
|
||||
zoomLevelOffset: -5,
|
||||
zoomLevelFixed: false,
|
||||
centerFixed: false,
|
||||
zoomAnimation: false,
|
||||
autoToggleDisplay: false,
|
||||
minimized: false,
|
||||
width: 150,
|
||||
height: 150,
|
||||
collapsedWidth: 19,
|
||||
collapsedHeight: 19,
|
||||
aimingRectOptions: {color: '#ff7800', weight: 1, clickable: false},
|
||||
shadowRectOptions: {color: '#000000', weight: 1, clickable: false, opacity: 0, fillOpacity: 0},
|
||||
strings: {hideText: 'Hide MiniMap', showText: 'Show MiniMap'},
|
||||
mapOptions: {} // Allows definition / override of Leaflet map options.
|
||||
},
|
||||
|
||||
// layer is the map layer to be shown in the minimap
|
||||
initialize: function (layer, options) {
|
||||
L.Util.setOptions(this, options);
|
||||
// Make sure the aiming rects are non-clickable even if the user tries to set them clickable (most likely by forgetting to specify them false)
|
||||
this.options.aimingRectOptions.clickable = false;
|
||||
this.options.shadowRectOptions.clickable = false;
|
||||
this._layer = layer;
|
||||
},
|
||||
|
||||
onAdd: function (map) {
|
||||
|
||||
this._mainMap = map;
|
||||
|
||||
// Creating the container and stopping events from spilling through to the main map.
|
||||
this._container = L.DomUtil.create('div', 'leaflet-control-minimap');
|
||||
this._container.style.width = this.options.width + 'px';
|
||||
this._container.style.height = this.options.height + 'px';
|
||||
L.DomEvent.disableClickPropagation(this._container);
|
||||
L.DomEvent.on(this._container, 'mousewheel', L.DomEvent.stopPropagation);
|
||||
|
||||
var mapOptions = {
|
||||
attributionControl: false,
|
||||
dragging: !this.options.centerFixed,
|
||||
zoomControl: false,
|
||||
zoomAnimation: this.options.zoomAnimation,
|
||||
autoToggleDisplay: this.options.autoToggleDisplay,
|
||||
touchZoom: this.options.centerFixed ? 'center' : !this._isZoomLevelFixed(),
|
||||
scrollWheelZoom: this.options.centerFixed ? 'center' : !this._isZoomLevelFixed(),
|
||||
doubleClickZoom: this.options.centerFixed ? 'center' : !this._isZoomLevelFixed(),
|
||||
boxZoom: !this._isZoomLevelFixed(),
|
||||
crs: map.options.crs
|
||||
};
|
||||
mapOptions = L.Util.extend(this.options.mapOptions, mapOptions); // merge with priority of the local mapOptions object.
|
||||
|
||||
this._miniMap = new L.Map(this._container, mapOptions);
|
||||
|
||||
this._miniMap.addLayer(this._layer);
|
||||
|
||||
// These bools are used to prevent infinite loops of the two maps notifying each other that they've moved.
|
||||
this._mainMapMoving = false;
|
||||
this._miniMapMoving = false;
|
||||
|
||||
// Keep a record of this to prevent auto toggling when the user explicitly doesn't want it.
|
||||
this._userToggledDisplay = false;
|
||||
this._minimized = false;
|
||||
|
||||
if (this.options.toggleDisplay) {
|
||||
this._addToggleButton();
|
||||
}
|
||||
|
||||
this._miniMap.whenReady(L.Util.bind(function () {
|
||||
this._aimingRect = L.rectangle(this._mainMap.getBounds(), this.options.aimingRectOptions).addTo(this._miniMap);
|
||||
this._shadowRect = L.rectangle(this._mainMap.getBounds(), this.options.shadowRectOptions).addTo(this._miniMap);
|
||||
this._mainMap.on('moveend', this._onMainMapMoved, this);
|
||||
this._mainMap.on('move', this._onMainMapMoving, this);
|
||||
this._miniMap.on('movestart', this._onMiniMapMoveStarted, this);
|
||||
this._miniMap.on('move', this._onMiniMapMoving, this);
|
||||
this._miniMap.on('moveend', this._onMiniMapMoved, this);
|
||||
}, this));
|
||||
|
||||
return this._container;
|
||||
},
|
||||
|
||||
addTo: function (map) {
|
||||
L.Control.prototype.addTo.call(this, map);
|
||||
|
||||
var center = this.options.centerFixed || this._mainMap.getCenter();
|
||||
this._miniMap.setView(center, this._decideZoom(true));
|
||||
this._setDisplay(this.options.minimized);
|
||||
return this;
|
||||
},
|
||||
|
||||
onRemove: function (map) {
|
||||
this._mainMap.off('moveend', this._onMainMapMoved, this);
|
||||
this._mainMap.off('move', this._onMainMapMoving, this);
|
||||
this._miniMap.off('moveend', this._onMiniMapMoved, this);
|
||||
|
||||
this._miniMap.removeLayer(this._layer);
|
||||
},
|
||||
|
||||
changeLayer: function (layer) {
|
||||
this._miniMap.removeLayer(this._layer);
|
||||
this._layer = layer;
|
||||
this._miniMap.addLayer(this._layer);
|
||||
},
|
||||
|
||||
_addToggleButton: function () {
|
||||
this._toggleDisplayButton = this.options.toggleDisplay ? this._createButton(
|
||||
'', this._toggleButtonInitialTitleText(), ('leaflet-control-minimap-toggle-display leaflet-control-minimap-toggle-display-' +
|
||||
this.options.position), this._container, this._toggleDisplayButtonClicked, this) : undefined;
|
||||
|
||||
this._toggleDisplayButton.style.width = this.options.collapsedWidth + 'px';
|
||||
this._toggleDisplayButton.style.height = this.options.collapsedHeight + 'px';
|
||||
},
|
||||
|
||||
_toggleButtonInitialTitleText: function () {
|
||||
if (this.options.minimized) {
|
||||
return this.options.strings.showText;
|
||||
} else {
|
||||
return this.options.strings.hideText;
|
||||
}
|
||||
},
|
||||
|
||||
_createButton: function (html, title, className, container, fn, context) {
|
||||
var link = L.DomUtil.create('a', className, container);
|
||||
link.innerHTML = html;
|
||||
link.href = '#';
|
||||
link.title = title;
|
||||
|
||||
var stop = L.DomEvent.stopPropagation;
|
||||
|
||||
L.DomEvent
|
||||
.on(link, 'click', stop)
|
||||
.on(link, 'mousedown', stop)
|
||||
.on(link, 'dblclick', stop)
|
||||
.on(link, 'click', L.DomEvent.preventDefault)
|
||||
.on(link, 'click', fn, context);
|
||||
|
||||
return link;
|
||||
},
|
||||
|
||||
_toggleDisplayButtonClicked: function () {
|
||||
this._userToggledDisplay = true;
|
||||
if (!this._minimized) {
|
||||
this._minimize();
|
||||
} else {
|
||||
this._restore();
|
||||
}
|
||||
},
|
||||
|
||||
_setDisplay: function (minimize) {
|
||||
if (minimize !== this._minimized) {
|
||||
if (!this._minimized) {
|
||||
this._minimize();
|
||||
} else {
|
||||
this._restore();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_minimize: function () {
|
||||
// hide the minimap
|
||||
if (this.options.toggleDisplay) {
|
||||
this._container.style.width = this.options.collapsedWidth + 'px';
|
||||
this._container.style.height = this.options.collapsedHeight + 'px';
|
||||
this._toggleDisplayButton.className += (' minimized-' + this.options.position);
|
||||
this._toggleDisplayButton.title = this.options.strings.showText;
|
||||
} else {
|
||||
this._container.style.display = 'none';
|
||||
}
|
||||
this._minimized = true;
|
||||
},
|
||||
|
||||
_restore: function () {
|
||||
if (this.options.toggleDisplay) {
|
||||
this._container.style.width = this.options.width + 'px';
|
||||
this._container.style.height = this.options.height + 'px';
|
||||
this._toggleDisplayButton.className = this._toggleDisplayButton.className
|
||||
.replace('minimized-' + this.options.position, '');
|
||||
this._toggleDisplayButton.title = this.options.strings.hideText;
|
||||
} else {
|
||||
this._container.style.display = 'block';
|
||||
}
|
||||
this._minimized = false;
|
||||
},
|
||||
|
||||
_onMainMapMoved: function (e) {
|
||||
if (!this._miniMapMoving) {
|
||||
var center = this.options.centerFixed || this._mainMap.getCenter();
|
||||
|
||||
this._mainMapMoving = true;
|
||||
this._miniMap.setView(center, this._decideZoom(true));
|
||||
this._setDisplay(this._decideMinimized());
|
||||
} else {
|
||||
this._miniMapMoving = false;
|
||||
}
|
||||
this._aimingRect.setBounds(this._mainMap.getBounds());
|
||||
},
|
||||
|
||||
_onMainMapMoving: function (e) {
|
||||
this._aimingRect.setBounds(this._mainMap.getBounds());
|
||||
},
|
||||
|
||||
_onMiniMapMoveStarted: function (e) {
|
||||
if (!this.options.centerFixed) {
|
||||
var lastAimingRect = this._aimingRect.getBounds();
|
||||
var sw = this._miniMap.latLngToContainerPoint(lastAimingRect.getSouthWest());
|
||||
var ne = this._miniMap.latLngToContainerPoint(lastAimingRect.getNorthEast());
|
||||
this._lastAimingRectPosition = {sw: sw, ne: ne};
|
||||
}
|
||||
},
|
||||
|
||||
_onMiniMapMoving: function (e) {
|
||||
if (!this.options.centerFixed) {
|
||||
if (!this._mainMapMoving && this._lastAimingRectPosition) {
|
||||
this._shadowRect.setBounds(new L.LatLngBounds(this._miniMap.containerPointToLatLng(this._lastAimingRectPosition.sw), this._miniMap.containerPointToLatLng(this._lastAimingRectPosition.ne)));
|
||||
this._shadowRect.setStyle({opacity: 1, fillOpacity: 0.3});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_onMiniMapMoved: function (e) {
|
||||
if (!this._mainMapMoving) {
|
||||
this._miniMapMoving = true;
|
||||
this._mainMap.setView(this._miniMap.getCenter(), this._decideZoom(false));
|
||||
this._shadowRect.setStyle({opacity: 0, fillOpacity: 0});
|
||||
} else {
|
||||
this._mainMapMoving = false;
|
||||
}
|
||||
},
|
||||
|
||||
_isZoomLevelFixed: function () {
|
||||
var zoomLevelFixed = this.options.zoomLevelFixed;
|
||||
return this._isDefined(zoomLevelFixed) && this._isInteger(zoomLevelFixed);
|
||||
},
|
||||
|
||||
_decideZoom: function (fromMaintoMini) {
|
||||
if (!this._isZoomLevelFixed()) {
|
||||
if (fromMaintoMini) {
|
||||
return this._mainMap.getZoom() + this.options.zoomLevelOffset;
|
||||
} else {
|
||||
var currentDiff = this._miniMap.getZoom() - this._mainMap.getZoom();
|
||||
var proposedZoom = this._miniMap.getZoom() - this.options.zoomLevelOffset;
|
||||
var toRet;
|
||||
|
||||
if (currentDiff > this.options.zoomLevelOffset && this._mainMap.getZoom() < this._miniMap.getMinZoom() - this.options.zoomLevelOffset) {
|
||||
// This means the miniMap is zoomed out to the minimum zoom level and can't zoom any more.
|
||||
if (this._miniMap.getZoom() > this._lastMiniMapZoom) {
|
||||
// This means the user is trying to zoom in by using the minimap, zoom the main map.
|
||||
toRet = this._mainMap.getZoom() + 1;
|
||||
// Also we cheat and zoom the minimap out again to keep it visually consistent.
|
||||
this._miniMap.setZoom(this._miniMap.getZoom() - 1);
|
||||
} else {
|
||||
// Either the user is trying to zoom out past the mini map's min zoom or has just panned using it, we can't tell the difference.
|
||||
// Therefore, we ignore it!
|
||||
toRet = this._mainMap.getZoom();
|
||||
}
|
||||
} else {
|
||||
// This is what happens in the majority of cases, and always if you configure the min levels + offset in a sane fashion.
|
||||
toRet = proposedZoom;
|
||||
}
|
||||
this._lastMiniMapZoom = this._miniMap.getZoom();
|
||||
return toRet;
|
||||
}
|
||||
} else {
|
||||
if (fromMaintoMini) {
|
||||
return this.options.zoomLevelFixed;
|
||||
} else {
|
||||
return this._mainMap.getZoom();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_decideMinimized: function () {
|
||||
if (this._userToggledDisplay) {
|
||||
return this._minimized;
|
||||
}
|
||||
|
||||
if (this.options.autoToggleDisplay) {
|
||||
if (this._mainMap.getBounds().contains(this._miniMap.getBounds())) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return this._minimized;
|
||||
},
|
||||
|
||||
_isInteger: function (value) {
|
||||
return typeof value === 'number';
|
||||
},
|
||||
|
||||
_isDefined: function (value) {
|
||||
return typeof value !== 'undefined';
|
||||
}
|
||||
});
|
||||
|
||||
L.Map.mergeOptions({
|
||||
miniMapControl: false
|
||||
});
|
||||
|
||||
L.Map.addInitHook(function () {
|
||||
if (this.options.miniMapControl) {
|
||||
this.miniMapControl = (new MiniMap()).addTo(this);
|
||||
}
|
||||
});
|
||||
|
||||
return MiniMap;
|
||||
|
||||
}, window));
|
|
@ -0,0 +1,48 @@
|
|||
L.Control.MousePosition = L.Control.extend({
|
||||
options: {
|
||||
position: 'bottomleft',
|
||||
separator: ' : ',
|
||||
emptyString: 'Unavailable',
|
||||
lngFirst: false,
|
||||
numDigits: 5,
|
||||
lngFormatter: undefined,
|
||||
latFormatter: undefined,
|
||||
prefix: ""
|
||||
},
|
||||
|
||||
onAdd: function (map) {
|
||||
this._container = L.DomUtil.create('div', 'leaflet-control-mouseposition');
|
||||
L.DomEvent.disableClickPropagation(this._container);
|
||||
map.on('mousemove', this._onMouseMove, this);
|
||||
this._container.innerHTML=this.options.emptyString;
|
||||
return this._container;
|
||||
},
|
||||
|
||||
onRemove: function (map) {
|
||||
map.off('mousemove', this._onMouseMove)
|
||||
},
|
||||
|
||||
_onMouseMove: function (e) {
|
||||
var lng = this.options.lngFormatter ? this.options.lngFormatter(e.latlng.lng) : L.Util.formatNum(e.latlng.lng, this.options.numDigits);
|
||||
var lat = this.options.latFormatter ? this.options.latFormatter(e.latlng.lat) : L.Util.formatNum(e.latlng.lat, this.options.numDigits);
|
||||
var value = this.options.lngFirst ? lng + this.options.separator + lat : lat + this.options.separator + lng;
|
||||
var prefixAndValue = this.options.prefix + ' ' + value;
|
||||
this._container.innerHTML = prefixAndValue;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
L.Map.mergeOptions({
|
||||
positionControl: false
|
||||
});
|
||||
|
||||
L.Map.addInitHook(function () {
|
||||
if (this.options.positionControl) {
|
||||
this.positionControl = new L.Control.MousePosition();
|
||||
this.addControl(this.positionControl);
|
||||
}
|
||||
});
|
||||
|
||||
L.control.mousePosition = function (options) {
|
||||
return new L.Control.MousePosition(options);
|
||||
};
|
|
@ -0,0 +1,180 @@
|
|||
(function(previousMethods){
|
||||
if (typeof previousMethods === 'undefined') {
|
||||
// Defining previously that object allows you to use that plugin even if you have overridden L.map
|
||||
previousMethods = {
|
||||
getCenter: L.Map.prototype.getCenter,
|
||||
setView: L.Map.prototype.setView,
|
||||
setZoomAround: L.Map.prototype.setZoomAround,
|
||||
getBoundsZoom: L.Map.prototype.getBoundsZoom,
|
||||
scaleUpdate: L.Control.Scale.prototype._update
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
L.Map.include({
|
||||
getBounds: function() {
|
||||
if (this._viewport) {
|
||||
return this.getViewportLatLngBounds()
|
||||
} else {
|
||||
var bounds = this.getPixelBounds(),
|
||||
sw = this.unproject(bounds.getBottomLeft()),
|
||||
ne = this.unproject(bounds.getTopRight());
|
||||
|
||||
return new L.LatLngBounds(sw, ne);
|
||||
}
|
||||
},
|
||||
|
||||
getViewport: function() {
|
||||
return this._viewport;
|
||||
},
|
||||
|
||||
getViewportBounds: function() {
|
||||
var vp = this._viewport,
|
||||
topleft = L.point(vp.offsetLeft, vp.offsetTop),
|
||||
vpsize = L.point(vp.clientWidth, vp.clientHeight);
|
||||
|
||||
if (vpsize.x === 0 || vpsize.y === 0) {
|
||||
//Our own viewport has no good size - so we fallback to the container size:
|
||||
vp = this.getContainer();
|
||||
if(vp){
|
||||
topleft = L.point(0, 0);
|
||||
vpsize = L.point(vp.clientWidth, vp.clientHeight);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return L.bounds(topleft, topleft.add(vpsize));
|
||||
},
|
||||
|
||||
getViewportLatLngBounds: function() {
|
||||
var bounds = this.getViewportBounds();
|
||||
return L.latLngBounds(this.containerPointToLatLng(bounds.min), this.containerPointToLatLng(bounds.max));
|
||||
},
|
||||
|
||||
getOffset: function() {
|
||||
var mCenter = this.getSize().divideBy(2),
|
||||
vCenter = this.getViewportBounds().getCenter();
|
||||
|
||||
return mCenter.subtract(vCenter);
|
||||
},
|
||||
|
||||
getCenter: function () {
|
||||
var center = previousMethods.getCenter.call(this);
|
||||
|
||||
if (this.getViewport()) {
|
||||
var zoom = this.getZoom(),
|
||||
point = this.project(center, zoom);
|
||||
point = point.subtract(this.getOffset());
|
||||
|
||||
center = this.unproject(point, zoom);
|
||||
}
|
||||
|
||||
return center;
|
||||
},
|
||||
|
||||
setView: function (center, zoom, options) {
|
||||
center = L.latLng(center);
|
||||
zoom = zoom || this.getZoom();
|
||||
|
||||
if (this.getViewport()) {
|
||||
var point = this.project(center, this._limitZoom(zoom));
|
||||
point = point.add(this.getOffset());
|
||||
center = this.unproject(point, this._limitZoom(zoom));
|
||||
}
|
||||
|
||||
return previousMethods.setView.call(this, center, zoom, options);
|
||||
},
|
||||
|
||||
setZoomAround: function (latlng, zoom, options) {
|
||||
var vp = this.getViewport();
|
||||
|
||||
if (vp) {
|
||||
var scale = this.getZoomScale(zoom),
|
||||
viewHalf = this.getViewportBounds().getCenter(),
|
||||
containerPoint = latlng instanceof L.Point ? latlng : this.latLngToContainerPoint(latlng),
|
||||
|
||||
centerOffset = containerPoint.subtract(viewHalf).multiplyBy(1 - 1 / scale),
|
||||
newCenter = this.containerPointToLatLng(viewHalf.add(centerOffset));
|
||||
|
||||
return this.setView(newCenter, zoom, {zoom: options});
|
||||
} else {
|
||||
return previousMethods.setZoomAround.call(this, latlng, zoom, options);
|
||||
}
|
||||
},
|
||||
|
||||
getBoundsZoom: function (bounds, inside, padding) { // (LatLngBounds[, Boolean, Point]) -> Number
|
||||
bounds = L.latLngBounds(bounds);
|
||||
|
||||
var zoom = this.getMinZoom() - (inside ? 1 : 0),
|
||||
maxZoom = this.getMaxZoom(),
|
||||
vp = this.getViewport(),
|
||||
size = (vp) ? L.point(vp.clientWidth, vp.clientHeight) : this.getSize(),
|
||||
|
||||
nw = bounds.getNorthWest(),
|
||||
se = bounds.getSouthEast(),
|
||||
|
||||
zoomNotFound = true,
|
||||
boundsSize;
|
||||
|
||||
padding = L.point(padding || [0, 0]);
|
||||
|
||||
do {
|
||||
zoom++;
|
||||
boundsSize = this.project(se, zoom).subtract(this.project(nw, zoom)).add(padding);
|
||||
zoomNotFound = !inside ? size.contains(boundsSize) : boundsSize.x < size.x || boundsSize.y < size.y;
|
||||
|
||||
} while (zoomNotFound && zoom <= maxZoom);
|
||||
|
||||
if (zoomNotFound && inside) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return inside ? zoom : zoom - 1;
|
||||
}
|
||||
});
|
||||
|
||||
L.Control.Scale.include({
|
||||
_update: function () {
|
||||
if (!this._map._viewport) {
|
||||
previousMethods.scaleUpdate.call(this);
|
||||
} else {
|
||||
var bounds = this._map.getBounds(),
|
||||
centerLat = bounds.getCenter().lat,
|
||||
halfWorldMeters = 6378137 * Math.PI * Math.cos(centerLat * Math.PI / 180),
|
||||
dist = halfWorldMeters * (bounds.getNorthEast().lng - bounds.getSouthWest().lng) / 180,
|
||||
|
||||
size = this._map.getSize(),
|
||||
options = this.options,
|
||||
maxMeters = 0;
|
||||
|
||||
var size = new L.Point(
|
||||
this._map._viewport.clientWidth,
|
||||
this._map._viewport.clientHeight);
|
||||
|
||||
if (size.x > 0) {
|
||||
maxMeters = dist * (options.maxWidth / size.x);
|
||||
}
|
||||
|
||||
this._updateScales(options, maxMeters);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
L.Map.include({
|
||||
setActiveArea: function (css) {
|
||||
if( !this._viewport ){
|
||||
//Make viewport if not already made
|
||||
var container = this.getContainer();
|
||||
this._viewport = L.DomUtil.create('div', '');
|
||||
container.insertBefore(this._viewport, container.firstChild);
|
||||
}
|
||||
|
||||
if (typeof css === 'string') {
|
||||
this._viewport.className = css;
|
||||
} else {
|
||||
L.extend(this._viewport.style, css);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
});
|
||||
})(window.leafletActiveAreaPreviousMethods);
|
|
@ -0,0 +1,316 @@
|
|||
/*
|
||||
* Original script by Josh Fraser (http://www.onlineaspect.com)
|
||||
* Continued and maintained by Jon Nylander at https://bitbucket.org/pellepim/jstimezonedetect
|
||||
*
|
||||
* Provided under the Do Whatever You Want With This Code License.
|
||||
*/
|
||||
/**
|
||||
* Namespace to hold all the code for timezone detection.
|
||||
*/
|
||||
var jstz = {};
|
||||
jstz.HEMISPHERE_SOUTH = 'SOUTH';
|
||||
jstz.HEMISPHERE_NORTH = 'NORTH';
|
||||
jstz.HEMISPHERE_UNKNOWN = 'N/A';
|
||||
jstz.olson = {};
|
||||
|
||||
/**
|
||||
* A simple object containing information of utc_offset, which olson timezone key to use,
|
||||
* and if the timezone cares about daylight savings or not.
|
||||
*
|
||||
* @constructor
|
||||
* @param {string} offset - for example '-11:00'
|
||||
* @param {string} olson_tz - the olson Identifier, such as "America/Denver"
|
||||
* @param {boolean} uses_dst - flag for whether the time zone somehow cares about daylight savings.
|
||||
*/
|
||||
jstz.TimeZone = function (offset, olson_tz, uses_dst) {
|
||||
this.utc_offset = offset;
|
||||
this.olson_tz = olson_tz;
|
||||
this.uses_dst = uses_dst;
|
||||
};
|
||||
|
||||
/**
|
||||
* Prints out the result.
|
||||
* But before it does that, it calls this.ambiguity_check.
|
||||
*/
|
||||
jstz.TimeZone.prototype.display = function () {
|
||||
this.ambiguity_check();
|
||||
var response_text = '<b>UTC-offset</b>: ' + this.utc_offset + '<br/>';
|
||||
response_text += '<b>Zoneinfo key</b>: ' + this.olson_tz + '<br/>';
|
||||
response_text += '<b>Zone uses DST</b>: ' + (this.uses_dst ? 'yes' : 'no') + '<br/>';
|
||||
|
||||
return response_text;
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if a timezone has possible ambiguities. I.e timezones that are similar.
|
||||
*
|
||||
* If the preliminary scan determines that we're in America/Denver. We double check
|
||||
* here that we're really there and not in America/Mazatlan.
|
||||
*
|
||||
* This is done by checking known dates for when daylight savings start for different
|
||||
* timezones.
|
||||
*/
|
||||
jstz.TimeZone.prototype.ambiguity_check = function () {
|
||||
var ambiguity_list, length, i, tz;
|
||||
ambiguity_list = jstz.olson.ambiguity_list[this.olson_tz];
|
||||
|
||||
if (typeof (ambiguity_list) === 'undefined') {
|
||||
return;
|
||||
}
|
||||
|
||||
length = ambiguity_list.length;
|
||||
i = 0;
|
||||
|
||||
for (; i < length; i += 1) {
|
||||
tz = ambiguity_list[i];
|
||||
|
||||
if (jstz.date_is_dst(jstz.olson.dst_start_dates[tz])) {
|
||||
this.olson_tz = tz;
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks whether a given date is in daylight savings time.
|
||||
*
|
||||
* If the date supplied is after june, we assume that we're checking
|
||||
* for southern hemisphere DST.
|
||||
*
|
||||
* @param {Date} date
|
||||
* @returns {boolean}
|
||||
*/
|
||||
jstz.date_is_dst = function (date) {
|
||||
var date_offset, base_offset;
|
||||
base_offset = ((date.getMonth() > 5 ? jstz.get_june_offset()
|
||||
: jstz.get_january_offset()));
|
||||
|
||||
date_offset = jstz.get_date_offset(date);
|
||||
|
||||
return (base_offset - date_offset) !== 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the offset in minutes from UTC for a certain date.
|
||||
*
|
||||
* @param date
|
||||
* @returns {number}
|
||||
*/
|
||||
jstz.get_date_offset = function (date) {
|
||||
return -date.getTimezoneOffset();
|
||||
};
|
||||
|
||||
/**
|
||||
* This function does some basic calculations to create information about
|
||||
* the user's timezone.
|
||||
*
|
||||
* Returns a primitive object on the format
|
||||
* {'utc_offset' : -9, 'dst': 1, hemisphere' : 'north'}
|
||||
* where dst is 1 if the region uses daylight savings.
|
||||
*
|
||||
* @returns {Object}
|
||||
*/
|
||||
jstz.get_timezone_info = function () {
|
||||
var january_offset, june_offset, diff;
|
||||
january_offset = jstz.get_january_offset();
|
||||
june_offset = jstz.get_june_offset();
|
||||
diff = january_offset - june_offset;
|
||||
|
||||
if (diff < 0) {
|
||||
return {
|
||||
'utc_offset' : january_offset,
|
||||
'dst': 1,
|
||||
'hemisphere' : jstz.HEMISPHERE_NORTH
|
||||
};
|
||||
} else if (diff > 0) {
|
||||
return {
|
||||
'utc_offset' : june_offset,
|
||||
'dst' : 1,
|
||||
'hemisphere' : jstz.HEMISPHERE_SOUTH
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
'utc_offset' : january_offset,
|
||||
'dst': 0,
|
||||
'hemisphere' : jstz.HEMISPHERE_UNKNOWN
|
||||
};
|
||||
};
|
||||
|
||||
jstz.get_january_offset = function () {
|
||||
return jstz.get_date_offset(new Date(2011, 0, 1, 0, 0, 0, 0));
|
||||
};
|
||||
|
||||
jstz.get_june_offset = function () {
|
||||
return jstz.get_date_offset(new Date(2011, 5, 1, 0, 0, 0, 0));
|
||||
};
|
||||
|
||||
/**
|
||||
* Uses get_timezone_info() to formulate a key to use in the olson.timezones dictionary.
|
||||
*
|
||||
* Returns a primitive object on the format:
|
||||
* {'timezone': TimeZone, 'key' : 'the key used to find the TimeZone object'}
|
||||
*
|
||||
* @returns Object
|
||||
*/
|
||||
jstz.determine_timezone = function () {
|
||||
var timezone_key_info, hemisphere_suffix, tz_key;
|
||||
timezone_key_info = jstz.get_timezone_info();
|
||||
hemisphere_suffix = '';
|
||||
|
||||
if (timezone_key_info.hemisphere === jstz.HEMISPHERE_SOUTH) {
|
||||
hemisphere_suffix = ',s';
|
||||
}
|
||||
|
||||
tz_key = timezone_key_info.utc_offset + ',' + timezone_key_info.dst + hemisphere_suffix;
|
||||
|
||||
return {'timezone' : jstz.olson.timezones[tz_key], 'key' : tz_key};
|
||||
};
|
||||
|
||||
/**
|
||||
* The keys in this dictionary are comma separated as such:
|
||||
*
|
||||
* First the offset compared to UTC time in minutes.
|
||||
*
|
||||
* Then a flag which is 0 if the timezone does not take daylight savings into account and 1 if it does.
|
||||
*
|
||||
* Thirdly an optional 's' signifies that the timezone is in the southern hemisphere, only interesting for timezones with DST.
|
||||
*
|
||||
* The values of the dictionary are TimeZone objects.
|
||||
*/
|
||||
jstz.olson.timezones = {
|
||||
'-720,0' : new jstz.TimeZone('-12:00', 'Etc/GMT+12', false),
|
||||
'-660,0' : new jstz.TimeZone('-11:00', 'Pacific/Pago_Pago', false),
|
||||
'-600,1' : new jstz.TimeZone('-11:00', 'America/Adak', true),
|
||||
'-660,1,s' : new jstz.TimeZone('-11:00', 'Pacific/Apia', true),
|
||||
'-600,0' : new jstz.TimeZone('-10:00', 'Pacific/Honolulu', false),
|
||||
'-570,0' : new jstz.TimeZone('-10:30', 'Pacific/Marquesas', false),
|
||||
'-540,0' : new jstz.TimeZone('-09:00', 'Pacific/Gambier', false),
|
||||
'-540,1' : new jstz.TimeZone('-09:00', 'America/Anchorage', true),
|
||||
'-480,1' : new jstz.TimeZone('-08:00', 'America/Los_Angeles', true),
|
||||
'-480,0' : new jstz.TimeZone('-08:00', 'Pacific/Pitcairn', false),
|
||||
'-420,0' : new jstz.TimeZone('-07:00', 'America/Phoenix', false),
|
||||
'-420,1' : new jstz.TimeZone('-07:00', 'America/Denver', true),
|
||||
'-360,0' : new jstz.TimeZone('-06:00', 'America/Guatemala', false),
|
||||
'-360,1' : new jstz.TimeZone('-06:00', 'America/Chicago', true),
|
||||
'-360,1,s' : new jstz.TimeZone('-06:00', 'Pacific/Easter', true),
|
||||
'-300,0' : new jstz.TimeZone('-05:00', 'America/Bogota', false),
|
||||
'-300,1' : new jstz.TimeZone('-05:00', 'America/New_York', true),
|
||||
'-270,0' : new jstz.TimeZone('-04:30', 'America/Caracas', false),
|
||||
'-240,1' : new jstz.TimeZone('-04:00', 'America/Halifax', true),
|
||||
'-240,0' : new jstz.TimeZone('-04:00', 'America/Santo_Domingo', false),
|
||||
'-240,1,s' : new jstz.TimeZone('-04:00', 'America/Asuncion', true),
|
||||
'-210,1' : new jstz.TimeZone('-03:30', 'America/St_Johns', true),
|
||||
'-180,1' : new jstz.TimeZone('-03:00', 'America/Godthab', true),
|
||||
'-180,0' : new jstz.TimeZone('-03:00', 'America/Argentina/Buenos_Aires', false),
|
||||
'-180,1,s' : new jstz.TimeZone('-03:00', 'America/Montevideo', true),
|
||||
'-120,0' : new jstz.TimeZone('-02:00', 'America/Noronha', false),
|
||||
'-120,1' : new jstz.TimeZone('-02:00', 'Etc/GMT+2', true),
|
||||
'-60,1' : new jstz.TimeZone('-01:00', 'Atlantic/Azores', true),
|
||||
'-60,0' : new jstz.TimeZone('-01:00', 'Atlantic/Cape_Verde', false),
|
||||
'0,0' : new jstz.TimeZone('00:00', 'Etc/UTC', false),
|
||||
'0,1' : new jstz.TimeZone('00:00', 'Europe/London', true),
|
||||
'60,1' : new jstz.TimeZone('+01:00', 'Europe/Berlin', true),
|
||||
'60,0' : new jstz.TimeZone('+01:00', 'Africa/Lagos', false),
|
||||
'60,1,s' : new jstz.TimeZone('+01:00', 'Africa/Windhoek', true),
|
||||
'120,1' : new jstz.TimeZone('+02:00', 'Asia/Beirut', true),
|
||||
'120,0' : new jstz.TimeZone('+02:00', 'Africa/Johannesburg', false),
|
||||
'180,1' : new jstz.TimeZone('+03:00', 'Europe/Moscow', true),
|
||||
'180,0' : new jstz.TimeZone('+03:00', 'Asia/Baghdad', false),
|
||||
'210,1' : new jstz.TimeZone('+03:30', 'Asia/Tehran', true),
|
||||
'240,0' : new jstz.TimeZone('+04:00', 'Asia/Dubai', false),
|
||||
'240,1' : new jstz.TimeZone('+04:00', 'Asia/Yerevan', true),
|
||||
'270,0' : new jstz.TimeZone('+04:30', 'Asia/Kabul', false),
|
||||
'300,1' : new jstz.TimeZone('+05:00', 'Asia/Yekaterinburg', true),
|
||||
'300,0' : new jstz.TimeZone('+05:00', 'Asia/Karachi', false),
|
||||
'330,0' : new jstz.TimeZone('+05:30', 'Asia/Kolkata', false),
|
||||
'345,0' : new jstz.TimeZone('+05:45', 'Asia/Kathmandu', false),
|
||||
'360,0' : new jstz.TimeZone('+06:00', 'Asia/Dhaka', false),
|
||||
'360,1' : new jstz.TimeZone('+06:00', 'Asia/Omsk', true),
|
||||
'390,0' : new jstz.TimeZone('+06:30', 'Asia/Rangoon', false),
|
||||
'420,1' : new jstz.TimeZone('+07:00', 'Asia/Krasnoyarsk', true),
|
||||
'420,0' : new jstz.TimeZone('+07:00', 'Asia/Jakarta', false),
|
||||
'480,0' : new jstz.TimeZone('+08:00', 'Asia/Shanghai', false),
|
||||
'480,1' : new jstz.TimeZone('+08:00', 'Asia/Irkutsk', true),
|
||||
'525,0' : new jstz.TimeZone('+08:45', 'Australia/Eucla', true),
|
||||
'525,1,s' : new jstz.TimeZone('+08:45', 'Australia/Eucla', true),
|
||||
'540,1' : new jstz.TimeZone('+09:00', 'Asia/Yakutsk', true),
|
||||
'540,0' : new jstz.TimeZone('+09:00', 'Asia/Tokyo', false),
|
||||
'570,0' : new jstz.TimeZone('+09:30', 'Australia/Darwin', false),
|
||||
'570,1,s' : new jstz.TimeZone('+09:30', 'Australia/Adelaide', true),
|
||||
'600,0' : new jstz.TimeZone('+10:00', 'Australia/Brisbane', false),
|
||||
'600,1' : new jstz.TimeZone('+10:00', 'Asia/Vladivostok', true),
|
||||
'600,1,s' : new jstz.TimeZone('+10:00', 'Australia/Sydney', true),
|
||||
'630,1,s' : new jstz.TimeZone('+10:30', 'Australia/Lord_Howe', true),
|
||||
'660,1' : new jstz.TimeZone('+11:00', 'Asia/Kamchatka', true),
|
||||
'660,0' : new jstz.TimeZone('+11:00', 'Pacific/Noumea', false),
|
||||
'690,0' : new jstz.TimeZone('+11:30', 'Pacific/Norfolk', false),
|
||||
'720,1,s' : new jstz.TimeZone('+12:00', 'Pacific/Auckland', true),
|
||||
'720,0' : new jstz.TimeZone('+12:00', 'Pacific/Tarawa', false),
|
||||
'765,1,s' : new jstz.TimeZone('+12:45', 'Pacific/Chatham', true),
|
||||
'780,0' : new jstz.TimeZone('+13:00', 'Pacific/Tongatapu', false),
|
||||
'840,0' : new jstz.TimeZone('+14:00', 'Pacific/Kiritimati', false)
|
||||
};
|
||||
|
||||
/**
|
||||
* This object contains information on when daylight savings starts for
|
||||
* different timezones.
|
||||
*
|
||||
* The list is short for a reason. Often we do not have to be very specific
|
||||
* to single out the correct timezone. But when we do, this list comes in
|
||||
* handy.
|
||||
*
|
||||
* Each value is a date denoting when daylight savings starts for that timezone.
|
||||
*/
|
||||
jstz.olson.dst_start_dates = {
|
||||
'America/Denver' : new Date(2011, 2, 13, 3, 0, 0, 0),
|
||||
'America/Mazatlan' : new Date(2011, 3, 3, 3, 0, 0, 0),
|
||||
'America/Chicago' : new Date(2011, 2, 13, 3, 0, 0, 0),
|
||||
'America/Mexico_City' : new Date(2011, 3, 3, 3, 0, 0, 0),
|
||||
'Atlantic/Stanley' : new Date(2011, 8, 4, 7, 0, 0, 0),
|
||||
'America/Asuncion' : new Date(2011, 9, 2, 3, 0, 0, 0),
|
||||
'America/Santiago' : new Date(2011, 9, 9, 3, 0, 0, 0),
|
||||
'America/Campo_Grande' : new Date(2011, 9, 16, 5, 0, 0, 0),
|
||||
'America/Montevideo' : new Date(2011, 9, 2, 3, 0, 0, 0),
|
||||
'America/Sao_Paulo' : new Date(2011, 9, 16, 5, 0, 0, 0),
|
||||
'America/Los_Angeles' : new Date(2011, 2, 13, 8, 0, 0, 0),
|
||||
'America/Santa_Isabel' : new Date(2011, 3, 5, 8, 0, 0, 0),
|
||||
'America/Havana' : new Date(2011, 2, 13, 2, 0, 0, 0),
|
||||
'America/New_York' : new Date(2011, 2, 13, 7, 0, 0, 0),
|
||||
'Asia/Gaza' : new Date(2011, 2, 26, 23, 0, 0, 0),
|
||||
'Asia/Beirut' : new Date(2011, 2, 27, 1, 0, 0, 0),
|
||||
'Europe/Minsk' : new Date(2011, 2, 27, 3, 0, 0, 0),
|
||||
'Europe/Istanbul' : new Date(2011, 2, 27, 7, 0, 0, 0),
|
||||
'Asia/Damascus' : new Date(2011, 3, 1, 2, 0, 0, 0),
|
||||
'Asia/Jerusalem' : new Date(2011, 3, 1, 6, 0, 0, 0),
|
||||
'Africa/Cairo' : new Date(2011, 3, 29, 4, 0, 0, 0),
|
||||
'Asia/Yerevan' : new Date(2011, 2, 27, 4, 0, 0, 0),
|
||||
'Asia/Baku' : new Date(2011, 2, 27, 8, 0, 0, 0),
|
||||
'Pacific/Auckland' : new Date(2011, 8, 26, 7, 0, 0, 0),
|
||||
'Pacific/Fiji' : new Date(2010, 11, 29, 23, 0, 0, 0),
|
||||
'America/Halifax' : new Date(2011, 2, 13, 6, 0, 0, 0),
|
||||
'America/Goose_Bay' : new Date(2011, 2, 13, 2, 1, 0, 0),
|
||||
'America/Miquelon' : new Date(2011, 2, 13, 5, 0, 0, 0),
|
||||
'America/Godthab' : new Date(2011, 2, 27, 1, 0, 0, 0)
|
||||
};
|
||||
|
||||
/**
|
||||
* The keys in this object are timezones that we know may be ambiguous after
|
||||
* a preliminary scan through the olson_tz object.
|
||||
*
|
||||
* The array of timezones to compare must be in the order that daylight savings
|
||||
* starts for the regions.
|
||||
*/
|
||||
jstz.olson.ambiguity_list = {
|
||||
'America/Denver' : ['America/Denver', 'America/Mazatlan'],
|
||||
'America/Chicago' : ['America/Chicago', 'America/Mexico_City'],
|
||||
'America/Asuncion' : ['Atlantic/Stanley', 'America/Asuncion', 'America/Santiago', 'America/Campo_Grande'],
|
||||
'America/Montevideo' : ['America/Montevideo', 'America/Sao_Paulo'],
|
||||
'Asia/Beirut' : ['Asia/Gaza', 'Asia/Beirut', 'Europe/Minsk', 'Europe/Istanbul', 'Asia/Damascus', 'Asia/Jerusalem', 'Africa/Cairo'],
|
||||
'Asia/Yerevan' : ['Asia/Yerevan', 'Asia/Baku'],
|
||||
'Pacific/Auckland' : ['Pacific/Auckland', 'Pacific/Fiji'],
|
||||
'America/Los_Angeles' : ['America/Los_Angeles', 'America/Santa_Isabel'],
|
||||
'America/New_York' : ['America/Havana', 'America/New_York'],
|
||||
'America/Halifax' : ['America/Goose_Bay', 'America/Halifax'],
|
||||
'America/Godthab' : ['America/Miquelon', 'America/Godthab']
|
||||
};
|
|
@ -0,0 +1,310 @@
|
|||
(function ($, OC) {
|
||||
'use strict';
|
||||
|
||||
var gpxedit = {
|
||||
map: {},
|
||||
baseLayers: null,
|
||||
id: 0,
|
||||
// indexed by gpxedit_id
|
||||
layersData: {}
|
||||
};
|
||||
|
||||
function load_map() {
|
||||
var layer = getUrlParameter('layer');
|
||||
console.log('layer '+layer);
|
||||
var default_layer = 'OpenStreetMap';
|
||||
if (typeof layer !== 'undefined'){
|
||||
default_layer = decodeURI(layer);
|
||||
}
|
||||
|
||||
// get url from key and layer type
|
||||
function geopUrl (key, layer, format)
|
||||
{ return 'http://wxs.ign.fr/'+ key + '/wmts?LAYER=' + layer
|
||||
+'&EXCEPTIONS=text/xml&FORMAT='+(format?format:'image/jpeg')
|
||||
+'&SERVICE=WMTS&VERSION=1.0.0&REQUEST=GetTile&STYLE=normal'
|
||||
+'&TILEMATRIXSET=PM&TILEMATRIX={z}&TILECOL={x}&TILEROW={y}' ;
|
||||
}
|
||||
// change it if you deploy GPXPOD
|
||||
var API_KEY = 'ljthe66m795pr2v2g8p7faxt';
|
||||
var ign = new L.tileLayer ( geopUrl(API_KEY,'GEOGRAPHICALGRIDSYSTEMS.MAPS'),
|
||||
{ attribution:'© <a href="http://www.ign.fr/">IGN-France</a>',
|
||||
maxZoom:18
|
||||
});
|
||||
|
||||
var osmUrl = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
|
||||
var osmAttribution = 'Map data © 2013 <a href="http://openstreetmap'+
|
||||
'.org">OpenStreetMap</a> contributors';
|
||||
var osm = new L.TileLayer(osmUrl, {maxZoom: 18, attribution: osmAttribution});
|
||||
|
||||
var osmfrUrl = 'http://{s}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png';
|
||||
var osmfr = new L.TileLayer(osmfrUrl,
|
||||
{maxZoom: 20, attribution: osmAttribution});
|
||||
var osmfr2 = new L.TileLayer(osmfrUrl,
|
||||
{minZoom: 0, maxZoom: 13, attribution: osmAttribution});
|
||||
|
||||
var openmapsurferUrl = 'http://openmapsurfer.uni-hd.de/tiles/roads/'+
|
||||
'x={x}&y={y}&z={z}';
|
||||
var openmapsurferAttribution = 'Imagery from <a href="http://giscience.uni'+
|
||||
'-hd.de/">GIScience Research Group @ University of Heidelberg</a> — '+
|
||||
'Map data © <a href="http://www.openstreetmap.org/copyright">'+
|
||||
'OpenStreetMap</a>';
|
||||
var openmapsurfer = new L.TileLayer(openmapsurferUrl,
|
||||
{maxZoom: 18, attribution: openmapsurferAttribution});
|
||||
|
||||
var transportUrl = 'http://a.tile2.opencyclemap.org/transport/{z}/{x}/{y}.'+
|
||||
'png';
|
||||
var transport = new L.TileLayer(transportUrl,
|
||||
{maxZoom: 18, attribution: osmAttribution});
|
||||
|
||||
var pisteUrl = 'http://tiles.openpistemap.org/nocontours/{z}/{x}/{y}.png';
|
||||
var piste = new L.TileLayer(pisteUrl,
|
||||
{maxZoom: 18, attribution: osmAttribution});
|
||||
|
||||
var hikebikeUrl = 'http://toolserver.org/tiles/hikebike/{z}/{x}/{y}.png';
|
||||
var hikebike = new L.TileLayer(hikebikeUrl,
|
||||
{maxZoom: 18, attribution: osmAttribution});
|
||||
|
||||
var osmCycleUrl = 'http://{s}.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png';
|
||||
var osmCycleAttrib = '© <a href="http://www.opencyclemap.org">'+
|
||||
'OpenCycleMap</a>, © <a href="http://www.openstreetmap.org/copyright">'+
|
||||
'OpenStreetMap</a>';
|
||||
var osmCycle = new L.TileLayer(osmCycleUrl,
|
||||
{maxZoom: 18, attribution: osmCycleAttrib});
|
||||
|
||||
var darkUrl = 'http://a.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png';
|
||||
var darkAttrib = '© Map tiles by CartoDB, under CC BY 3.0. Data by'+
|
||||
' OpenStreetMap, under ODbL.';
|
||||
var dark = new L.TileLayer(darkUrl, {maxZoom: 18, attribution: darkAttrib});
|
||||
|
||||
var esriTopoUrl = 'https://server.arcgisonline.com/ArcGIS/rest/services/World'+
|
||||
'_Topo_Map/MapServer/tile/{z}/{y}/{x}';
|
||||
var esriTopoAttrib = 'Tiles © Esri — Esri, DeLorme, NAVTEQ, '+
|
||||
'TomTom, Intermap, iPC, USGS, FAO, NPS, NRCAN, GeoBase, Kadaster NL, Ord'+
|
||||
'nance Survey, Esri Japan, METI, Esri China (Hong Kong), and the GIS User'+
|
||||
' Community';
|
||||
var esriTopo = new L.TileLayer(esriTopoUrl,
|
||||
{maxZoom: 18, attribution: esriTopoAttrib});
|
||||
|
||||
var esriAerialUrl = 'https://server.arcgisonline.com/ArcGIS/rest/services'+
|
||||
'/World_Imagery/MapServer/tile/{z}/{y}/{x}';
|
||||
var esriAerialAttrib = 'Tiles © Esri — Source: Esri, i-cubed, '+
|
||||
'USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the'+
|
||||
' GIS User Community';
|
||||
var esriAerial = new L.TileLayer(esriAerialUrl,
|
||||
{maxZoom: 18, attribution: esriAerialAttrib});
|
||||
|
||||
var tonerUrl = 'http://{s}.tile.stamen.com/toner/{z}/{x}/{y}.jpg';
|
||||
var stamenAttribution = '<a href="http://leafletjs.com" title="A JS library'+
|
||||
' for interactive maps">Leaflet</a> | © Map tiles by <a href="http://stamen'+
|
||||
'.com">Stamen Design</a>, under <a href="http://creativecommons.org/license'+
|
||||
's/by/3.0">CC BY 3.0</a>, Data by <a href="http://openstreetmap.org">OpenSt'+
|
||||
'reetMap</a>, under <a href="http://creativecommons.org/licenses/by-sa/3.0"'+
|
||||
'>CC BY SA</a>.';
|
||||
var toner = new L.TileLayer(tonerUrl,
|
||||
{maxZoom: 18, attribution: stamenAttribution});
|
||||
|
||||
var watercolorUrl = 'http://{s}.tile.stamen.com/watercolor/{z}/{x}/{y}.jpg';
|
||||
var watercolor = new L.TileLayer(watercolorUrl,
|
||||
{maxZoom: 18, attribution: stamenAttribution});
|
||||
|
||||
var routeUrl = 'http://{s}.tile.openstreetmap.fr/route500/{z}/{x}/{y}.png';
|
||||
var routeAttrib = '©, Tiles © <a href="http://www.openstreetmap.fr">O'+
|
||||
'penStreetMap France</a>';
|
||||
var route = new L.TileLayer(routeUrl,
|
||||
{minZoom: 1, maxZoom: 20, attribution: routeAttrib});
|
||||
|
||||
var baseLayers = {
|
||||
'OpenStreetMap': osm,
|
||||
'OpenCycleMap': osmCycle,
|
||||
'IGN France': ign,
|
||||
'OpenMapSurfer Roads': openmapsurfer,
|
||||
'Hike & bike': hikebike,
|
||||
'OSM Transport': transport,
|
||||
'ESRI Aerial': esriAerial,
|
||||
'ESRI Topo with relief': esriTopo,
|
||||
'Dark' : dark,
|
||||
'Toner' : toner,
|
||||
'Watercolor' : watercolor,
|
||||
'OpenStreetMap France': osmfr
|
||||
};
|
||||
gpxedit.baseLayers = baseLayers;
|
||||
var baseOverlays = {
|
||||
'OsmFr Route500': route,
|
||||
'OpenPisteMap Relief':
|
||||
L.tileLayer('http://tiles2.openpistemap.org/landshaded/{z}/{x}/{y}.png',
|
||||
{
|
||||
attribution: '©, Tiles © <a href="http://www.o'+
|
||||
'penstreetmap.fr">OpenStreetMap France</a>',
|
||||
minZoom: 1,
|
||||
maxZoom: 15
|
||||
}
|
||||
),
|
||||
'OpenPisteMap pistes' : piste
|
||||
};
|
||||
|
||||
var layerlist = [];
|
||||
|
||||
gpxedit.map = new L.Map('map', {
|
||||
zoomControl: true,
|
||||
layers: layerlist,
|
||||
});
|
||||
|
||||
L.control.scale({metric: true, imperial: true, position:'topleft'})
|
||||
.addTo(gpxedit.map);
|
||||
|
||||
L.control.mousePosition().addTo(gpxedit.map);
|
||||
gpxedit.searchControl = L.Control.geocoder({position:'topleft'});
|
||||
gpxedit.searchControl.addTo(gpxedit.map);
|
||||
gpxedit.locateControl = L.control.locate({follow:true});
|
||||
gpxedit.locateControl.addTo(gpxedit.map);
|
||||
L.Control.measureControl().addTo(gpxedit.map);
|
||||
L.control.sidebar('sidebar').addTo(gpxedit.map);
|
||||
|
||||
gpxedit.map.setView(new L.LatLng(27, 5), 3);
|
||||
|
||||
if (! baseLayers.hasOwnProperty(default_layer)){
|
||||
default_layer = 'OpenStreetMap';
|
||||
}
|
||||
gpxedit.map.addLayer(baseLayers[default_layer]);
|
||||
|
||||
gpxedit.activeLayers = L.control.activeLayers(baseLayers, baseOverlays);
|
||||
gpxedit.activeLayers.addTo(gpxedit.map);
|
||||
|
||||
gpxedit.minimapControl = new L.Control.MiniMap(
|
||||
osmfr2,
|
||||
{ toggleDisplay: true, position:'bottomleft' }
|
||||
).addTo(gpxedit.map);
|
||||
gpxedit.minimapControl._toggleDisplayButtonClicked();
|
||||
|
||||
//gpxedit.map.on('moveend',updateTrackListFromBounds);
|
||||
//gpxedit.map.on('zoomend',updateTrackListFromBounds);
|
||||
//gpxedit.map.on('baselayerchange',updateTrackListFromBounds);
|
||||
|
||||
var editableLayers = new L.FeatureGroup();
|
||||
gpxedit.map.addLayer(editableLayers);
|
||||
|
||||
var MyCustomMarker = L.Icon.extend({
|
||||
options: {
|
||||
shadowUrl: null,
|
||||
//iconAnchor: new L.Point(12, 12),
|
||||
//iconSize: new L.Point(24, 24),
|
||||
//iconUrl: 'link/to/image.png'
|
||||
icon: L.divIcon({
|
||||
className: 'leaflet-div-icon2',
|
||||
iconAnchor: [5, 30]
|
||||
})
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
var options = {
|
||||
position: 'topright',
|
||||
draw: {
|
||||
polyline: {
|
||||
shapeOptions: {
|
||||
color: '#f357a1',
|
||||
weight: 7
|
||||
}
|
||||
},
|
||||
polygon:false,
|
||||
circle: false,
|
||||
rectangle:false,
|
||||
marker: {
|
||||
icon: L.divIcon({
|
||||
className: 'leaflet-div-icon2',
|
||||
iconAnchor: [5, 30]
|
||||
})
|
||||
}
|
||||
},
|
||||
edit: {
|
||||
featureGroup: editableLayers, //REQUIRED!!
|
||||
}
|
||||
};
|
||||
|
||||
var drawControl = new L.Control.Draw(options);
|
||||
gpxedit.map.addControl(drawControl);
|
||||
|
||||
gpxedit.map.on(L.Draw.Event.CREATED, function (e) {
|
||||
var type = e.layerType,
|
||||
layer = e.layer;
|
||||
var popupTitle = 'Line';
|
||||
if (type === 'marker') {
|
||||
popupTitle = 'Waypoint';
|
||||
}
|
||||
|
||||
layer.bindPopup('<h2>'+popupTitle+'</h2>Name : <input class="layerName"></input><br/>'+
|
||||
'Description : <textarea class="layerDesc"></textarea><br/>'+
|
||||
'Comment : <textarea class="layerCmt"></textarea><br/>'+
|
||||
'<button class="popupOkButton" layerid="'+gpxedit.id+'">OK</button>');
|
||||
|
||||
layer.gpxedit_id = gpxedit.id;
|
||||
layer.type = type;
|
||||
gpxedit.layersData[gpxedit.id] = {name:'', description:'', comment:'', layer: layer};
|
||||
editableLayers.addLayer(layer);
|
||||
gpxedit.id++;
|
||||
});
|
||||
gpxedit.map.on('draw:edited', function (e) {
|
||||
var layers = e.layers;
|
||||
layers.eachLayer(function (layer) {
|
||||
//do whatever you want; most likely save back to db
|
||||
//alert('edited : '+Object.keys(layer));
|
||||
});
|
||||
editableLayers.eachLayer(function (layer) {
|
||||
//alert('edited : '+Object.keys(layer));
|
||||
alert('edited : '+Object.keys(layer._leaflet_id));
|
||||
});
|
||||
});
|
||||
gpxedit.map.on('draw:deleted', function (e) {
|
||||
var layers = e.layers;
|
||||
layers.eachLayer(function (layer) {
|
||||
delete gpxedit.layersData[layer.gpxedit_id];
|
||||
});
|
||||
editableLayers.eachLayer(function (layer) {
|
||||
alert(layer.gpxedit_id);
|
||||
});
|
||||
});
|
||||
|
||||
gpxedit.map.on('popupopen', function(e){
|
||||
var id = parseInt(e.popup.getContent().match(/layerid="(\d+)"/)[1]);
|
||||
var buttonParent = $('button.popupOkButton[layerid='+id+']').parent();
|
||||
buttonParent.find('input.layerName').val(gpxedit.layersData[id].name);
|
||||
buttonParent.find('textarea.layerDesc').val(gpxedit.layersData[id].description);
|
||||
buttonParent.find('textarea.layerCmt').val(gpxedit.layersData[id].comment);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function getUrlParameter(sParam)
|
||||
{
|
||||
var sPageURL = window.location.search.substring(1);
|
||||
var sURLVariables = sPageURL.split('&');
|
||||
for (var i = 0; i < sURLVariables.length; i++)
|
||||
{
|
||||
var sParameterName = sURLVariables[i].split('=');
|
||||
if (sParameterName[0] === sParam)
|
||||
{
|
||||
return sParameterName[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
gpxedit.username = $('p#username').html();
|
||||
load_map();
|
||||
|
||||
$('body').on('click','button.popupOkButton', function(e) {
|
||||
var id = parseInt($(this).attr('layerid'));
|
||||
var name = $(this).parent().find('.layerName').val();
|
||||
var description = $(this).parent().find('.layerDesc').val();
|
||||
var comment = $(this).parent().find('.layerCmt').val();
|
||||
|
||||
gpxedit.layersData[id].name = name;
|
||||
gpxedit.layersData[id].description = description;
|
||||
gpxedit.layersData[id].comment = comment;
|
||||
gpxedit.layersData[id].layer.bindTooltip(name, {sticky:true});
|
||||
|
||||
gpxedit.map.closePopup();
|
||||
});
|
||||
});
|
||||
|
||||
})(jQuery, OC);
|
After Width: | Height: | Size: 3.9 KiB |
After Width: | Height: | Size: 3.9 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 797 B |
|
@ -0,0 +1,41 @@
|
|||
/**
|
||||
* jQuery Detect Timezone plugin
|
||||
*
|
||||
* Copyright (c) 2011 Scott Watermasysk (scottwater@gmail.com)
|
||||
* Provided under the Do Whatever You Want With This Code License. (same as detect_timezone).
|
||||
*
|
||||
*/
|
||||
|
||||
(function( $ ){
|
||||
|
||||
$.fn.set_timezone = function(options) {
|
||||
|
||||
this.val(this.get_timezone(options));
|
||||
return this;
|
||||
};
|
||||
|
||||
$.fn.get_timezone = function(options) {
|
||||
|
||||
var settings = {
|
||||
'debug' : false,
|
||||
'default' : 'America/New_York'
|
||||
};
|
||||
|
||||
if(options) {
|
||||
$.extend( settings, options );
|
||||
}
|
||||
|
||||
var tz_info = jstz.determine_timezone();
|
||||
var timezone = tz_info.timezone;
|
||||
if (timezone != 'undefined') {
|
||||
timezone.ambiguity_check();
|
||||
return timezone.olson_tz;
|
||||
} else {
|
||||
if(settings['debug']) {
|
||||
alert('no timezone to be found. using default.')
|
||||
}
|
||||
return settings['default']
|
||||
}
|
||||
};
|
||||
|
||||
})( jQuery );
|
|
@ -0,0 +1,221 @@
|
|||
/*! Copyright (c) 2013 Brandon Aaron (http://brandon.aaron.sh)
|
||||
* Licensed under the MIT License (LICENSE.txt).
|
||||
*
|
||||
* Version: 3.1.12
|
||||
*
|
||||
* Requires: jQuery 1.2.2+
|
||||
*/
|
||||
|
||||
(function (factory) {
|
||||
if ( typeof define === 'function' && define.amd ) {
|
||||
// AMD. Register as an anonymous module.
|
||||
define(['jquery'], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node/CommonJS style for Browserify
|
||||
module.exports = factory;
|
||||
} else {
|
||||
// Browser globals
|
||||
factory(jQuery);
|
||||
}
|
||||
}(function ($) {
|
||||
|
||||
var toFix = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'],
|
||||
toBind = ( 'onwheel' in document || document.documentMode >= 9 ) ?
|
||||
['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'],
|
||||
slice = Array.prototype.slice,
|
||||
nullLowestDeltaTimeout, lowestDelta;
|
||||
|
||||
if ( $.event.fixHooks ) {
|
||||
for ( var i = toFix.length; i; ) {
|
||||
$.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks;
|
||||
}
|
||||
}
|
||||
|
||||
var special = $.event.special.mousewheel = {
|
||||
version: '3.1.12',
|
||||
|
||||
setup: function() {
|
||||
if ( this.addEventListener ) {
|
||||
for ( var i = toBind.length; i; ) {
|
||||
this.addEventListener( toBind[--i], handler, false );
|
||||
}
|
||||
} else {
|
||||
this.onmousewheel = handler;
|
||||
}
|
||||
// Store the line height and page height for this particular element
|
||||
$.data(this, 'mousewheel-line-height', special.getLineHeight(this));
|
||||
$.data(this, 'mousewheel-page-height', special.getPageHeight(this));
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
if ( this.removeEventListener ) {
|
||||
for ( var i = toBind.length; i; ) {
|
||||
this.removeEventListener( toBind[--i], handler, false );
|
||||
}
|
||||
} else {
|
||||
this.onmousewheel = null;
|
||||
}
|
||||
// Clean up the data we added to the element
|
||||
$.removeData(this, 'mousewheel-line-height');
|
||||
$.removeData(this, 'mousewheel-page-height');
|
||||
},
|
||||
|
||||
getLineHeight: function(elem) {
|
||||
var $elem = $(elem),
|
||||
$parent = $elem['offsetParent' in $.fn ? 'offsetParent' : 'parent']();
|
||||
if (!$parent.length) {
|
||||
$parent = $('body');
|
||||
}
|
||||
return parseInt($parent.css('fontSize'), 10) || parseInt($elem.css('fontSize'), 10) || 16;
|
||||
},
|
||||
|
||||
getPageHeight: function(elem) {
|
||||
return $(elem).height();
|
||||
},
|
||||
|
||||
settings: {
|
||||
adjustOldDeltas: true, // see shouldAdjustOldDeltas() below
|
||||
normalizeOffset: true // calls getBoundingClientRect for each event
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.extend({
|
||||
mousewheel: function(fn) {
|
||||
return fn ? this.bind('mousewheel', fn) : this.trigger('mousewheel');
|
||||
},
|
||||
|
||||
unmousewheel: function(fn) {
|
||||
return this.unbind('mousewheel', fn);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
function handler(event) {
|
||||
var orgEvent = event || window.event,
|
||||
args = slice.call(arguments, 1),
|
||||
delta = 0,
|
||||
deltaX = 0,
|
||||
deltaY = 0,
|
||||
absDelta = 0,
|
||||
offsetX = 0,
|
||||
offsetY = 0;
|
||||
event = $.event.fix(orgEvent);
|
||||
event.type = 'mousewheel';
|
||||
|
||||
// Old school scrollwheel delta
|
||||
if ( 'detail' in orgEvent ) { deltaY = orgEvent.detail * -1; }
|
||||
if ( 'wheelDelta' in orgEvent ) { deltaY = orgEvent.wheelDelta; }
|
||||
if ( 'wheelDeltaY' in orgEvent ) { deltaY = orgEvent.wheelDeltaY; }
|
||||
if ( 'wheelDeltaX' in orgEvent ) { deltaX = orgEvent.wheelDeltaX * -1; }
|
||||
|
||||
// Firefox < 17 horizontal scrolling related to DOMMouseScroll event
|
||||
if ( 'axis' in orgEvent && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
|
||||
deltaX = deltaY * -1;
|
||||
deltaY = 0;
|
||||
}
|
||||
|
||||
// Set delta to be deltaY or deltaX if deltaY is 0 for backwards compatabilitiy
|
||||
delta = deltaY === 0 ? deltaX : deltaY;
|
||||
|
||||
// New school wheel delta (wheel event)
|
||||
if ( 'deltaY' in orgEvent ) {
|
||||
deltaY = orgEvent.deltaY * -1;
|
||||
delta = deltaY;
|
||||
}
|
||||
if ( 'deltaX' in orgEvent ) {
|
||||
deltaX = orgEvent.deltaX;
|
||||
if ( deltaY === 0 ) { delta = deltaX * -1; }
|
||||
}
|
||||
|
||||
// No change actually happened, no reason to go any further
|
||||
if ( deltaY === 0 && deltaX === 0 ) { return; }
|
||||
|
||||
// Need to convert lines and pages to pixels if we aren't already in pixels
|
||||
// There are three delta modes:
|
||||
// * deltaMode 0 is by pixels, nothing to do
|
||||
// * deltaMode 1 is by lines
|
||||
// * deltaMode 2 is by pages
|
||||
if ( orgEvent.deltaMode === 1 ) {
|
||||
var lineHeight = $.data(this, 'mousewheel-line-height');
|
||||
delta *= lineHeight;
|
||||
deltaY *= lineHeight;
|
||||
deltaX *= lineHeight;
|
||||
} else if ( orgEvent.deltaMode === 2 ) {
|
||||
var pageHeight = $.data(this, 'mousewheel-page-height');
|
||||
delta *= pageHeight;
|
||||
deltaY *= pageHeight;
|
||||
deltaX *= pageHeight;
|
||||
}
|
||||
|
||||
// Store lowest absolute delta to normalize the delta values
|
||||
absDelta = Math.max( Math.abs(deltaY), Math.abs(deltaX) );
|
||||
|
||||
if ( !lowestDelta || absDelta < lowestDelta ) {
|
||||
lowestDelta = absDelta;
|
||||
|
||||
// Adjust older deltas if necessary
|
||||
if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
|
||||
lowestDelta /= 40;
|
||||
}
|
||||
}
|
||||
|
||||
// Adjust older deltas if necessary
|
||||
if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
|
||||
// Divide all the things by 40!
|
||||
delta /= 40;
|
||||
deltaX /= 40;
|
||||
deltaY /= 40;
|
||||
}
|
||||
|
||||
// Get a whole, normalized value for the deltas
|
||||
delta = Math[ delta >= 1 ? 'floor' : 'ceil' ](delta / lowestDelta);
|
||||
deltaX = Math[ deltaX >= 1 ? 'floor' : 'ceil' ](deltaX / lowestDelta);
|
||||
deltaY = Math[ deltaY >= 1 ? 'floor' : 'ceil' ](deltaY / lowestDelta);
|
||||
|
||||
// Normalise offsetX and offsetY properties
|
||||
if ( special.settings.normalizeOffset && this.getBoundingClientRect ) {
|
||||
var boundingRect = this.getBoundingClientRect();
|
||||
offsetX = event.clientX - boundingRect.left;
|
||||
offsetY = event.clientY - boundingRect.top;
|
||||
}
|
||||
|
||||
// Add information to the event object
|
||||
event.deltaX = deltaX;
|
||||
event.deltaY = deltaY;
|
||||
event.deltaFactor = lowestDelta;
|
||||
event.offsetX = offsetX;
|
||||
event.offsetY = offsetY;
|
||||
// Go ahead and set deltaMode to 0 since we converted to pixels
|
||||
// Although this is a little odd since we overwrite the deltaX/Y
|
||||
// properties with normalized deltas.
|
||||
event.deltaMode = 0;
|
||||
|
||||
// Add event and delta to the front of the arguments
|
||||
args.unshift(event, delta, deltaX, deltaY);
|
||||
|
||||
// Clearout lowestDelta after sometime to better
|
||||
// handle multiple device types that give different
|
||||
// a different lowestDelta
|
||||
// Ex: trackpad = 3 and mouse wheel = 120
|
||||
if (nullLowestDeltaTimeout) { clearTimeout(nullLowestDeltaTimeout); }
|
||||
nullLowestDeltaTimeout = setTimeout(nullLowestDelta, 200);
|
||||
|
||||
return ($.event.dispatch || $.event.handle).apply(this, args);
|
||||
}
|
||||
|
||||
function nullLowestDelta() {
|
||||
lowestDelta = null;
|
||||
}
|
||||
|
||||
function shouldAdjustOldDeltas(orgEvent, absDelta) {
|
||||
// If this is an older event and the delta is divisable by 120,
|
||||
// then we are assuming that the browser is treating this as an
|
||||
// older mouse wheel event and that we should divide the deltas
|
||||
// by 40 to try and get a more usable deltaFactor.
|
||||
// Side note, this actually impacts the reported scroll distance
|
||||
// in older browsers and can cause scrolling to be slower than native.
|
||||
// Turn this off by setting $.event.special.mousewheel.settings.adjustOldDeltas to false.
|
||||
return special.settings.adjustOldDeltas && orgEvent.type === 'mousewheel' && absDelta % 120 === 0;
|
||||
}
|
||||
|
||||
}));
|
|
@ -0,0 +1 @@
|
|||
L.Control.Sidebar=L.Control.extend({includes:L.Mixin.Events,initialize:function(t,s){var i,a;for(L.setOptions(this,s),this._sidebar=L.DomUtil.get(t),L.Browser.touch&&L.DomUtil.addClass(this._sidebar,"leaflet-touch"),i=this._sidebar.children.length-1;i>=0;i--)a=this._sidebar.children[i],"UL"==a.tagName&&L.DomUtil.hasClass(a,"sidebar-tabs")?this._tabs=a:"DIV"==a.tagName&&L.DomUtil.hasClass(a,"sidebar-content")&&(this._container=a);for(this._tabitems=[],i=this._tabs.children.length-1;i>=0;i--)a=this._tabs.children[i],"LI"==a.tagName&&(this._tabitems.push(a),a._sidebar=this);for(this._panes=[],i=this._container.children.length-1;i>=0;i--)a=this._container.children[i],"DIV"==a.tagName&&L.DomUtil.hasClass(a,"sidebar-pane")&&this._panes.push(a);this._hasTouchStart=L.Browser.touch&&"ontouchstart"in document.documentElement},addTo:function(t){this._map=t;for(var s=this._hasTouchStart?"touchstart":"click",i=this._tabitems.length-1;i>=0;i--){var a=this._tabitems[i];L.DomEvent.on(a.firstChild,s,this._onClick,a)}return this},removeFrom:function(){this._map=null;for(var t=this._hasTouchStart?"touchstart":"click",s=this._tabitems.length-1;s>=0;s--){var i=this._tabitems[s];L.DomEvent.off(i.firstChild,t,this._onClick)}return this},open:function(t){var s,i;for(s=this._panes.length-1;s>=0;s--)i=this._panes[s],i.id==t?L.DomUtil.addClass(i,"active"):L.DomUtil.hasClass(i,"active")&&L.DomUtil.removeClass(i,"active");for(s=this._tabitems.length-1;s>=0;s--)i=this._tabitems[s],i.firstChild.hash=="#"+t?L.DomUtil.addClass(i,"active"):L.DomUtil.hasClass(i,"active")&&L.DomUtil.removeClass(i,"active");return this.fire("content",{id:t}),L.DomUtil.hasClass(this._sidebar,"collapsed")&&(this.fire("opening"),L.DomUtil.removeClass(this._sidebar,"collapsed")),this},close:function(){for(var t=this._tabitems.length-1;t>=0;t--){var s=this._tabitems[t];L.DomUtil.hasClass(s,"active")&&L.DomUtil.removeClass(s,"active")}return L.DomUtil.hasClass(this._sidebar,"collapsed")||(this.fire("closing"),L.DomUtil.addClass(this._sidebar,"collapsed")),this},_onClick:function(){L.DomUtil.hasClass(this,"active")?this._sidebar.close():this._sidebar.open(this.firstChild.hash.slice(1))}}),L.control.sidebar=function(t,s){return new L.Control.Sidebar(t,s)};
|
|
@ -0,0 +1,173 @@
|
|||
(function (factory, window) {
|
||||
// define an AMD module that relies on 'leaflet'
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define(['leaflet'], function (L) {
|
||||
factory(L, window.toGeoJSON);
|
||||
});
|
||||
|
||||
// define a Common JS module that relies on 'leaflet'
|
||||
} else if (typeof exports === 'object') {
|
||||
module.exports = function (L) {
|
||||
if (L === undefined) {
|
||||
if (typeof window !== 'undefined') {
|
||||
L = require('leaflet');
|
||||
}
|
||||
}
|
||||
factory(L);
|
||||
return L;
|
||||
};
|
||||
} else if (typeof window !== 'undefined' && window.L) {
|
||||
factory(window.L);
|
||||
}
|
||||
}(function (L) {
|
||||
L.Polyline.Measure = L.Draw.Polyline.extend({
|
||||
addHooks: function () {
|
||||
L.Draw.Polyline.prototype.addHooks.call(this);
|
||||
if (this._map) {
|
||||
this._markerGroup = new L.LayerGroup();
|
||||
this._map.addLayer(this._markerGroup);
|
||||
|
||||
this._markers = [];
|
||||
this._map.on('click', this._onClick, this);
|
||||
this._startShape();
|
||||
}
|
||||
},
|
||||
|
||||
removeHooks: function () {
|
||||
L.Draw.Polyline.prototype.removeHooks.call(this);
|
||||
|
||||
this._clearHideErrorTimeout();
|
||||
|
||||
// !\ Still useful when control is disabled before any drawing (refactor needed?)
|
||||
this._map
|
||||
.off('pointermove', this._onMouseMove, this)
|
||||
.off('mousemove', this._onMouseMove, this)
|
||||
.off('click', this._onClick, this);
|
||||
|
||||
this._clearGuides();
|
||||
this._container.style.cursor = '';
|
||||
|
||||
this._removeShape();
|
||||
},
|
||||
|
||||
_startShape: function () {
|
||||
this._drawing = true;
|
||||
this._poly = new L.Polyline([], this.options.shapeOptions);
|
||||
// this is added as a placeholder, if leaflet doesn't recieve
|
||||
// this when the tool is turned off all onclick events are removed
|
||||
this._poly._onClick = function () {};
|
||||
|
||||
this._container.style.cursor = 'crosshair';
|
||||
|
||||
this._updateTooltip();
|
||||
this._map
|
||||
.on('pointermove', this._onMouseMove, this)
|
||||
.on('mousemove', this._onMouseMove, this);
|
||||
},
|
||||
|
||||
_finishShape: function () {
|
||||
this._drawing = false;
|
||||
|
||||
this._cleanUpShape();
|
||||
this._clearGuides();
|
||||
|
||||
this._updateTooltip();
|
||||
|
||||
this._map
|
||||
.off('pointermove', this._onMouseMove, this)
|
||||
.off('mousemove', this._onMouseMove, this);
|
||||
|
||||
this._container.style.cursor = '';
|
||||
},
|
||||
|
||||
_removeShape: function () {
|
||||
if (!this._poly) return;
|
||||
this._map.removeLayer(this._poly);
|
||||
delete this._poly;
|
||||
this._markers.splice(0);
|
||||
this._markerGroup.clearLayers();
|
||||
},
|
||||
|
||||
_onClick: function () {
|
||||
if (!this._drawing) {
|
||||
this._removeShape();
|
||||
this._startShape();
|
||||
return;
|
||||
}
|
||||
},
|
||||
|
||||
_getTooltipText: function () {
|
||||
var labelText = L.Draw.Polyline.prototype._getTooltipText.call(this);
|
||||
if (!this._drawing) {
|
||||
labelText.text = '';
|
||||
}
|
||||
return labelText;
|
||||
}
|
||||
});
|
||||
|
||||
L.Control.MeasureControl = L.Control.extend({
|
||||
|
||||
statics: {
|
||||
TITLE: 'Measure distances'
|
||||
},
|
||||
options: {
|
||||
position: 'topleft',
|
||||
handler: {}
|
||||
},
|
||||
|
||||
toggle: function () {
|
||||
if (this.handler.enabled()) {
|
||||
this.handler.disable.call(this.handler);
|
||||
} else {
|
||||
this.handler.enable.call(this.handler);
|
||||
}
|
||||
},
|
||||
|
||||
onAdd: function (map) {
|
||||
var link = null;
|
||||
var className = 'leaflet-control-draw';
|
||||
|
||||
this._container = L.DomUtil.create('div', 'leaflet-bar');
|
||||
|
||||
this.handler = new L.Polyline.Measure(map, this.options.handler);
|
||||
|
||||
this.handler.on('enabled', function () {
|
||||
this.enabled = true;
|
||||
L.DomUtil.addClass(this._container, 'enabled');
|
||||
}, this);
|
||||
|
||||
this.handler.on('disabled', function () {
|
||||
delete this.enabled;
|
||||
L.DomUtil.removeClass(this._container, 'enabled');
|
||||
}, this);
|
||||
|
||||
link = L.DomUtil.create('a', className + '-measure', this._container);
|
||||
link.href = '#';
|
||||
link.title = L.Control.MeasureControl.TITLE;
|
||||
|
||||
L.DomEvent
|
||||
.addListener(link, 'click', L.DomEvent.stopPropagation)
|
||||
.addListener(link, 'click', L.DomEvent.preventDefault)
|
||||
.addListener(link, 'click', this.toggle, this);
|
||||
|
||||
return this._container;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
L.Map.mergeOptions({
|
||||
measureControl: false
|
||||
});
|
||||
|
||||
|
||||
L.Map.addInitHook(function () {
|
||||
if (this.options.measureControl) {
|
||||
this.measureControl = L.Control.measureControl().addTo(this);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
L.Control.measureControl = function (options) {
|
||||
return new L.Control.MeasureControl(options);
|
||||
};
|
||||
}, window));
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* Metadata - jQuery plugin for parsing metadata from elements
|
||||
*
|
||||
* Copyright (c) 2006 John Resig, Yehuda Katz, J<EFBFBD>örn Zaefferer, Paul McLanahan
|
||||
*
|
||||
* Dual licensed under the MIT and GPL licenses:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* Revision: $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sets the type of metadata to use. Metadata is encoded in JSON, and each property
|
||||
* in the JSON will become a property of the element itself.
|
||||
*
|
||||
* There are three supported types of metadata storage:
|
||||
*
|
||||
* attr: Inside an attribute. The name parameter indicates *which* attribute.
|
||||
*
|
||||
* class: Inside the class attribute, wrapped in curly braces: { }
|
||||
*
|
||||
* elem: Inside a child element (e.g. a script tag). The
|
||||
* name parameter indicates *which* element.
|
||||
*
|
||||
* The metadata for an element is loaded the first time the element is accessed via jQuery.
|
||||
*
|
||||
* As a result, you can define the metadata type, use $(expr) to load the metadata into the elements
|
||||
* matched by expr, then redefine the metadata type and run another $(expr) for other elements.
|
||||
*
|
||||
* @name $.metadata.setType
|
||||
*
|
||||
* @example <p id="one" class="some_class {item_id: 1, item_label: 'Label'}">This is a p</p>
|
||||
* @before $.metadata.setType("class")
|
||||
* @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label"
|
||||
* @desc Reads metadata from the class attribute
|
||||
*
|
||||
* @example <p id="one" class="some_class" data="{item_id: 1, item_label: 'Label'}">This is a p</p>
|
||||
* @before $.metadata.setType("attr", "data")
|
||||
* @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label"
|
||||
* @desc Reads metadata from a "data" attribute
|
||||
*
|
||||
* @example <p id="one" class="some_class"><script>{item_id: 1, item_label: 'Label'}</script>This is a p</p>
|
||||
* @before $.metadata.setType("elem", "script")
|
||||
* @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label"
|
||||
* @desc Reads metadata from a nested script element
|
||||
*
|
||||
* @param String type The encoding type
|
||||
* @param String name The name of the attribute to be used to get metadata (optional)
|
||||
* @cat Plugins/Metadata
|
||||
* @descr Sets the type of encoding to be used when loading metadata for the first time
|
||||
* @type undefined
|
||||
* @see metadata()
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
|
||||
$.extend({
|
||||
metadata : {
|
||||
defaults : {
|
||||
type: 'class',
|
||||
name: 'metadata',
|
||||
cre: /({.*})/,
|
||||
single: 'metadata'
|
||||
},
|
||||
setType: function( type, name ){
|
||||
this.defaults.type = type;
|
||||
this.defaults.name = name;
|
||||
},
|
||||
get: function( elem, opts ){
|
||||
var settings = $.extend({},this.defaults,opts);
|
||||
// check for empty string in single property
|
||||
if ( !settings.single.length ) settings.single = 'metadata';
|
||||
|
||||
var data = $.data(elem, settings.single);
|
||||
// returned cached data if it already exists
|
||||
if ( data ) return data;
|
||||
|
||||
data = "{}";
|
||||
|
||||
if ( settings.type == "class" ) {
|
||||
var m = settings.cre.exec( elem.className );
|
||||
if ( m )
|
||||
data = m[1];
|
||||
} else if ( settings.type == "elem" ) {
|
||||
if( !elem.getElementsByTagName )
|
||||
return undefined;
|
||||
var e = elem.getElementsByTagName(settings.name);
|
||||
if ( e.length )
|
||||
data = $.trim(e[0].innerHTML);
|
||||
} else if ( elem.getAttribute != undefined ) {
|
||||
var attr = elem.getAttribute( settings.name );
|
||||
if ( attr )
|
||||
data = attr;
|
||||
}
|
||||
|
||||
if ( data.indexOf( '{' ) <0 )
|
||||
data = "{" + data + "}";
|
||||
|
||||
data = eval("(" + data + ")");
|
||||
|
||||
$.data( elem, settings.single, data );
|
||||
return data;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Returns the metadata object for the first member of the jQuery object.
|
||||
*
|
||||
* @name metadata
|
||||
* @descr Returns element's metadata object
|
||||
* @param Object opts An object contianing settings to override the defaults
|
||||
* @type jQuery
|
||||
* @cat Plugins/Metadata
|
||||
*/
|
||||
$.fn.metadata = function( opts ){
|
||||
return $.metadata.get( this[0], opts );
|
||||
};
|
||||
|
||||
})(jQuery);
|