aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.pylintrc8
-rw-r--r--COPYING.AGPL661
-rw-r--r--administrative-codes/Makefile14
-rwxr-xr-xadministrative-codes/csv2json9
-rwxr-xr-xadministrative-codes/update21
-rw-r--r--common.py379
-rw-r--r--common_gdal.py383
-rw-r--r--config.yml4958
-rw-r--r--export_mvt.py619
-rw-r--r--export_raster.py251
-rwxr-xr-xgeodata-download (renamed from webmap-download)205
-rwxr-xr-xgeodata-import794
-rwxr-xr-xgeodata-import-topo350
-rw-r--r--import_source.py1153
-rw-r--r--layers/.gitignore3
-rw-r--r--layers/custom/gigafactories.geojson454
-rw-r--r--layers/custom/svk/transmissionsnatsprojekt.geojson1797
-rw-r--r--rename_exchange.py48
-rw-r--r--schema.sql9623
-rwxr-xr-xwebmap-cgi295
-rw-r--r--webmap-download-mrr.py669
-rwxr-xr-xwebmap-import1323
22 files changed, 20622 insertions, 3395 deletions
diff --git a/.pylintrc b/.pylintrc
new file mode 100644
index 0000000..6b3e91d
--- /dev/null
+++ b/.pylintrc
@@ -0,0 +1,8 @@
+[DESIGN]
+max-args = 20
+max-positional-arguments = 20
+max-locals = 50
+max-branches = 30
+max-statements = 100
+max-nested-blocks = 10
+max-module-lines = 1250
diff --git a/COPYING.AGPL b/COPYING.AGPL
new file mode 100644
index 0000000..be3f7b2
--- /dev/null
+++ b/COPYING.AGPL
@@ -0,0 +1,661 @@
+ GNU AFFERO GENERAL PUBLIC LICENSE
+ Version 3, 19 November 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://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 <https://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
+<https://www.gnu.org/licenses/>.
diff --git a/administrative-codes/Makefile b/administrative-codes/Makefile
index c0008bc..9e2464d 100644
--- a/administrative-codes/Makefile
+++ b/administrative-codes/Makefile
@@ -1,8 +1,13 @@
OUT = administrative-codes
CSV_SOURCES = counties.csv municipalities.csv
-GENERATED_FILES = $(addsuffix .json,$(OUT)) $(addsuffix .json.br,$(OUT))
+GENERATED_FILES = $(addsuffix .json,$(OUT)) \
+ $(addsuffix .json.br,$(OUT)) \
+ $(addsuffix .json.gz,$(OUT))
+
all: $(GENERATED_FILES)
+update: $(CSV_SOURCES)
+
$(CSV_SOURCES): %.csv:
./update
@@ -11,9 +16,12 @@ $(CSV_SOURCES): %.csv:
# XXX The brotli(1) executable doesn't support mode=MODE_TEXT
%.json.br: %.json
- brotli --best --keep --output=$@ -- $^
+ brotli --best --keep --no-copy-stat --verbose --stdout <$< >$@
+
+%.json.gz: %.json
+ gzip --best --keep --no-name --verbose --stdout <$< >$@
clean:
rm -f -- $(GENERATED_FILES)
-.PHONY: update clean
+.PHONY: all update clean
diff --git a/administrative-codes/csv2json b/administrative-codes/csv2json
index 7c22666..6dd6ad7 100755
--- a/administrative-codes/csv2json
+++ b/administrative-codes/csv2json
@@ -18,6 +18,8 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#----------------------------------------------------------------------
+# pylint: disable=missing-module-docstring
+
import sys
import csv
from pathlib import Path
@@ -25,13 +27,14 @@ import json
basedir = Path(sys.argv[0]).parent
data = {}
-def readCSV(path):
- with open(path, mode='r', newline='') as fp:
+def readCSV(pathname): # pylint: disable=invalid-name
+ """Read CSV"""
+ with open(pathname, mode='r', newline='', encoding='utf-8') as fp:
reader = csv.DictReader(fp, delimiter='\t', dialect='unix')
for row in reader:
code = row['Code']
if code in data:
- raise Exception(f'Duplicate code {code}')
+ raise RuntimeError(f'Duplicate code {code}')
data[code] = row['Name']
# The source (SCB) lists all codes in same file: they differ only in
diff --git a/administrative-codes/update b/administrative-codes/update
index 855f73b..fa6a6da 100755
--- a/administrative-codes/update
+++ b/administrative-codes/update
@@ -18,6 +18,8 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#----------------------------------------------------------------------
+# pylint: disable=missing-module-docstring
+
import re
import sys
import csv
@@ -30,13 +32,15 @@ import xlrd
#
# Unfortunately SCB doesn't provide a CSV, so we download their xls file and produce our own.
# https://www.scb.se/hitta-statistik/regional-statistik-och-kartor/regionala-indelningar/lan-och-kommuner/lan-och-kommuner-i-kodnummerordning/
-r = requests.get('https://www.scb.se/contentassets/7a89e48960f741e08918e489ea36354a/kommunlankod_2024.xls')
+r = requests.get('https://www.scb.se/contentassets/7a89e48960f741e08918e489ea36354a/'
+ 'kommunlankod_2024.xls',
+ timeout=30)
r.raise_for_status()
if 'content-type' not in r.headers:
- raise Exception('Missing Content-Type from response headers')
-if r.headers['content-type'] not in ['application/vnd.ms-excel', 'application/octet-stream']:
- raise Exception(f"Unsupported Content-Type: {r.headers['content-type']}")
+ raise RuntimeError('Missing Content-Type from response headers')
+if r.headers['content-type'] not in ('application/vnd.ms-excel', 'application/octet-stream'):
+ raise RuntimeError(f"Unsupported Content-Type: {r.headers['content-type']}")
xls = xlrd.open_workbook(file_contents=r.content)
sheets = xls.sheet_names()
@@ -71,15 +75,16 @@ for i in range(sheet.nrows):
counties.append(row)
basedir = Path(sys.argv[0]).parent
-def writeCSV(filename, data):
+def writeCSV(filename, data): # pylint: disable=invalid-name
+ """Write CSV file."""
fieldnames = ['Code', 'Name']
path = basedir.joinpath(filename).with_suffix('.csv')
- with path.open(mode='w', newline='') as fp:
+ with path.open(mode='w', newline='', encoding='utf-8') as fp:
writer = csv.DictWriter(fp, fieldnames=fieldnames, delimiter='\t',
quoting=csv.QUOTE_MINIMAL, dialect='unix')
writer.writeheader()
- for row in data:
- writer.writerow(row)
+ for row2 in data:
+ writer.writerow(row2)
print(f'Wrote {len(data)} rows in {path}', file=sys.stderr)
writeCSV('counties', counties)
diff --git a/common.py b/common.py
index 78fa4fd..cc4f2da 100644
--- a/common.py
+++ b/common.py
@@ -1,6 +1,6 @@
#----------------------------------------------------------------------
# Backend utilities for the Klimatanalys Norr project (common module)
-# Copyright © 2024 Guilhem Moulin <info@guilhem.se>
+# Copyright © 2024-2025 Guilhem Moulin <info@guilhem.se>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -16,146 +16,131 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#----------------------------------------------------------------------
-import os, sys
-from os import path
+# pylint: disable=missing-module-docstring
+
+import os
+from os import path as os_path, curdir as os_curdir, pardir as os_pardir, sep as os_sep
+import sys
from fnmatch import fnmatchcase
from pathlib import Path, PosixPath
-from urllib.parse import urlparse, urlunparse
from stat import S_ISDIR
-from math import modf
-from xdg.BaseDirectory import xdg_config_home
+import math
import logging
+from typing import Any, Iterator, Optional, Never, TextIO
+from hashlib import sha256
+
+from xdg.BaseDirectory import xdg_config_home
import yaml
-def init_logger(app=__file__, level=logging.WARNING):
+def init_logger(app : str =__file__, level : int = logging.WARNING) -> logging.Logger:
+ """Initialize the logger"""
+
log_fmt = logging.Formatter('%(levelname)s: %(message)s')
log = logging.getLogger()
log.setLevel(level)
- if os.getenv('SYSTEMD_EXEC_PID', None) is None or os.getenv('JOURNAL_STREAM', None) is None:
+ if (os.getenv('SYSTEMD_EXEC_PID', None) is None
+ or os.getenv('INVOCATION_ID', None) is None
+ or os.getenv('JOURNAL_STREAM', None) is None):
ch = logging.StreamHandler()
else:
# started in systemd, use journald for filtering incl. coloring
- from systemd.journal import JournalHandler
+ from systemd.journal import JournalHandler # pylint: disable=import-outside-toplevel
ch = JournalHandler(SYSLOG_IDENTIFIER=app)
ch.setFormatter(log_fmt)
log.addHandler(ch)
return log
-def load_config(path=None, groupnames=None):
- if path is None:
- for p in [Path(),
- Path(xdg_config_home).joinpath('webmap'),
- PosixPath('/etc').joinpath('webmap')]:
- p = str(p.joinpath('config.yml'))
- if os.path.exists(p):
- path = p
- break
- if path is None:
- raise Exception('Could not find configuration file')
- with open(path, 'r') as fp:
- config = yaml.safe_load(fp)
- layers = config.get('layers', {})
+class MissingConfiguration(Exception):
+ """Exception raised when no configuration file could be found"""
+ def __init__(self, name : str) -> Never:
+ super().__init__(f'Could not find configuration file {name}')
- # validate sources
- destinations = {}
+class BadConfiguration(Exception):
+ """Exception raised when there is a bad configuration"""
+ def __init__(self, message : str, config_path : Optional[Path] = None) -> Never:
+ if config_path is not None:
+ message = str(config_path) + ': ' + message
+ super().__init__(message)
+
+def open_config(filename : str = 'config.yml', appname : str = 'geodata') -> TextIO:
+ """Open the configuration file"""
+ dirs = [
+ Path(),
+ Path(xdg_config_home).joinpath(appname),
+ PosixPath('/etc').joinpath(appname)
+ ]
+ for d in dirs:
+ p = d.joinpath(filename)
+ try:
+ return p.open(mode='r', encoding='utf-8')
+ except (FileNotFoundError, PermissionError) as e:
+ logging.debug('Ignoring exception %s', str(e))
+ raise MissingConfiguration(filename)
+
+def load_config(path : Optional[Path] = None) -> dict[str, Any]:
+ """Load configuration file"""
+ fp = open_config() if path is None else path.open(mode='r', encoding='utf-8')
+ try:
+ return yaml.safe_load(fp)
+ finally:
+ fp.close()
+
+def layers_in_group(groupname : str, patterns : str|list[str],
+ layernames : set[str]) -> Iterator[str]:
+ """Get layer names matching the given patterns"""
+ if isinstance(patterns, str):
+ patterns = [patterns]
+ for pat in patterns:
+ has_match = False
+ for layername in layernames:
+ if fnmatchcase(layername, pat):
+ yield layername
+ has_match = True
+ if has_match:
+ continue
+ if pat in layernames:
+ # fallback to exact match
+ yield pat
+ else:
+ logging.warning('Pattern "%s" in group "%s" does not match anything', pat, groupname)
+
+def parse_config(path : Optional[Path] = None,
+ groupnames : Optional[list[str]] = None) -> dict[str, Any]:
+ """Parse configuration file"""
+ config = load_config(path)
+
+ layers = config.get('layers', {})
for name, layerdefs in layers.items():
if isinstance(layerdefs, dict) and 'sources' not in layerdefs:
layers[name] = { 'sources': [layerdefs] }
- for k in ['description', 'create']:
+ for k in ('description', 'create', 'publish', 'type', 'cluster-geometry'):
if k in layerdefs:
layers[name][k] = layerdefs.pop(k)
layerdefs = layers[name]
- if 'sources' not in layerdefs:
- raise Exception(f'Layer "{name}" does not have any source receipe')
-
- for sourcedef in layerdefs.get('sources', []):
- source = sourcedef.get('source', None)
- if source is None:
- continue
- download = source.get('download', None)
- if download is None:
- url = None
- dl_module = None
- elif isinstance(download, str):
- url = download
- dl_module = None
- source['download'] = download = { 'url': url }
- else:
- url = download.get('url', None)
- dl_module = download.get('module', None)
- if url is None:
- urlp = None
- else:
- urlp = urlparse(url)
- if urlp is None:
- raise Exception(f'urlparse({url}) failed')
-
- cache = source.get('cache', None)
- if cache is None or isinstance(cache, str):
- source['cache'] = { 'path': cache }
- else:
- cache = cache.get('path', None)
-
- if cache is None or cache in ['', os.curdir, os.pardir] or cache.endswith(os.sep):
- # infer filename from the source URL
- if urlp is None or urlp.path is None or urlp.path == '' or urlp.path.endswith('/'):
- raise Exception(f'Layer "{name}": Could not infer filename from URL {url}')
- p = PosixPath(urlp.path)
- if p is None or p.name is None or p.name == '':
- raise Exception(f'Invalid PosixPath({urlp.path})')
- if cache is None or cache == '':
- cache = Path()
- else:
- cache = Path(cache)
- cache = cache.joinpath(p.name)
- else:
- cache = Path(cache)
- source['cache']['path'] = cache
-
- v = { 'url': urlp, 'module': dl_module }
- if cache in destinations and destinations[cache] != v:
- # allow destination conflicts, but only when the source URL and module match
- raise Exception(f'Destination conflict for layer "{name}"')
- destinations[cache] = v
-
# filter layers that are not of interest
if groupnames is not None:
- layernames = []
+ layernames = set()
+ layernames_all = set(layers.keys())
layer_groups = config.get('layer-groups', {})
for groupname in groupnames:
- if groupname not in layer_groups:
- if groupname in layers:
- # fallback to layer names
- layernames.append(groupname)
+ if groupname in layer_groups:
+ for name in layers_in_group(groupname, layer_groups[groupname], layernames_all):
+ if name in layernames:
+ logging.debug('Layer "%s" was already added, skipping', name)
+ else:
+ layernames.add(name)
+ elif groupname in layers:
+ # fallback to layer names
+ if groupname in layernames:
+ logging.debug('Layer "%s" was already added, skipping', groupname)
else:
- logging.error('Unknown group/layer name "%s"', groupname)
- exit(1)
+ layernames.add(groupname)
else:
- patterns = layer_groups[groupname]
- if isinstance(patterns, str):
- patterns = [patterns]
- for pat in patterns:
- has_match = False
- for layername in layers:
- if fnmatchcase(layername, pat):
- if layername in layernames:
- logging.debug('Layer "%s" was already added, skipping', layername)
- else:
- layernames.append(layername)
- has_match = True
- if has_match:
- pass
- elif pat in layers:
- # fallback to exact match
- if pat in layernames:
- logging.debug('Layer "%s" was already added, skipping', pat)
- else:
- layernames.append(pat)
- else:
- logging.warning('Group name "%s" does not match anything', groupname)
+ logging.error('Unknown group/layer name "%s"', groupname)
+ sys.exit(1)
layers = { name: layers[name] for name in layernames }
@@ -166,40 +151,133 @@ def load_config(path=None, groupnames=None):
if isinstance(extent, list):
config['extent'] = tuple(extent)
if config.get('SRS', None) is None:
- raise Exception('Configured extent without SRS')
+ raise BadConfiguration('Configured extent without SRS')
+
+ return config
+
+def _check_key_type(k : str, v : str, known_keys : list[type, tuple[set[str]]]) -> bool:
+ for t, ks in known_keys:
+ if k in ks and isinstance(v, t):
+ return True
+ return False
+
+def parse_config_dl(downloads) -> dict[str, dict[str, str|int]]:
+ """Parse and validate the "downloads" section from the configuration dictionary"""
+
+ if not isinstance(downloads, list):
+ raise BadConfiguration(f'Invalid download recipe: {downloads}')
+
+ known_keys = [
+ (str, {'path', 'url'}),
+ (int, {'max-age', 'max-size'}),
+ ]
+
+ destinations = {}
+ known_keys_set = {k for _,ks in known_keys for k in ks}
+ for dl in downloads:
+ if 'url' in dl:
+ dls = [dl]
+ elif 'basedir' in dl and 'baseurl' in dl and 'files' in dl and 'path' not in dl:
+ dls = []
+ for filename in dl['files']:
+ dl2 = {
+ 'path' : os_path.join(dl['basedir'], filename),
+ 'url' : dl['baseurl'] + filename
+ }
+ for k, v in dl.items():
+ if k not in ('basedir', 'baseurl', 'files'):
+ dl2[k] = v
+ dls.append(dl2)
+ else:
+ raise BadConfiguration(f'Invalid download recipe: {dl}')
+
+ for dl in dls:
+ path = dl.get('path', None)
+ if path is None or path in ('', os_curdir, os_pardir) or path.endswith(os_sep):
+ raise BadConfiguration(f'Invalid destination path "{path}"')
+ if path in destinations:
+ raise BadConfiguration(f'Duplicate download recipe for "{path}"')
+ dl2 = {}
+ for k, v in dl.items():
+ if k == 'path':
+ continue
+ if k not in known_keys_set:
+ logging.warning('Ignoring unknown setting "%s" in download recipe for "%s"',
+ k, path)
+ elif not _check_key_type(k, v, known_keys):
+ logging.warning('Ignoring setting "%s" in download recipe for "%s"'
+ ' (invalid type)', k, path)
+ else:
+ dl2[k] = v
+ destinations[path] = dl2
- sys.modules[__name__].config = config
+ return destinations
-def format_bytes(n):
- if n < 768:
+# pylint: disable-next=invalid-name
+def getSourcePathLockFileName(path : str) -> str:
+ """Return the name of the lockfile associated with a source path."""
+ return sha256(path.encode('utf-8')).hexdigest() + '.lck'
+
+def format_bytes(n : int, threshold : int = 768, precision : int = 2) -> str:
+ """Format a number of bytes to a SI unit"""
+
+ if n < threshold:
return f'{n}\u202FB'
- elif n < 768*1024:
- return f'{n/1024:.2f}\u202FkiB'
- elif n < 768*1024*1024:
- return f'{n/1048576:.2f}\u202FMiB'
- else:
- return f'{n/1073741824:.2f}\u202FGiB'
+ if n < threshold * 1024:
+ return f'{n/1024:.{precision}f}\u202FkiB'
+ if n < threshold * 1048576:
+ return f'{n/1048576:.{precision}f}\u202FMiB'
+ return f'{n/1073741824:.{precision}f}\u202FGiB'
-def format_time(s):
- fs, s = modf(s)
- m, s = divmod(int(s), 60)
+def format_time(ts : float, precision : int = 3) -> str:
+ """Format a timestamp to HH:MM:SS.fff"""
+
+ w = 2 if precision == 0 else precision + 3
+ ts = round(ts, precision)
+ m = math.floor(ts/60.)
+ s = ts - 60. * m
h, m = divmod(m, 60)
- return f'{h:02d}:{m:02d}:{s + fs:06.3f}'
+ return f'{h:02d}:{m:02d}:{s:0{w}.{precision}f}'
+
+def escape_identifier(identifier : str) -> str:
+ """Escape the given identifier, cf.
+ swig/python/gdal-utils/osgeo_utils/samples/validate_gpkg.py:_esc_id()."""
+
+ if identifier is None or '\x00' in identifier:
+ raise RuntimeError(f'Invalid identifier "{identifier}"')
-# Return a boolean indicating whether the installer GDAL version is
-# greater than or equal to the provider (maj, min, rev) triplet.
-def gdal_version_min(maj=0, min=0, rev=0):
- if maj < 1 or (maj == 1 and min < 10):
- # GDAL_VERSION_NUM() macro was changed in 1.10. That version
- # was released in 2013 so we blindly assume the installer
- # version is more recent
- return True
+ # SQL:1999 delimited identifier
+ return '"' + identifier.replace('"', '""') + '"'
- from osgeo import gdal
- version_cur = int(gdal.VersionInfo());
- # cf. GDAL_COMPUTE_VERSION(maj,min,rev) in gcore/gdal_version.h.in
- version_min = maj*1000000 + min*10000 + rev*100
- return version_min <= version_cur
+def escape_literal_str(literal : str) -> str:
+ """Escape the given character string literal, cf.
+ swig/python/gdal-utils/osgeo_utils/samples/validate_gpkg.py:_esc_literal()."""
+
+ if literal is None or '\x00' in literal:
+ raise RuntimeError(f'Invalid literal "{literal}"')
+
+ # SQL:1999 character string literal
+ return '\'' + literal.replace('\'', '\'\'') + '\''
+
+# pylint: disable-next=invalid-name
+def getEscapedTableNamePG(layername : str, extract_schema_from_layer_name : bool = True) -> str:
+ """Return the layer name as an escaped identifier, suitable for injection into SQL queries.
+ The optional boolean (default: True) indicates whether the first dot character is used as
+ the separator between the schema and the table name, like the EXTRACT_SCHEMA_FROM_LAYER_NAME
+ layer creation option, see
+ https://gdal.org/en/stable/drivers/vector/pg.html#layer-creation-options"""
+ if extract_schema_from_layer_name:
+ (schema_name, table_name) = getQualifiedLayerName(layername)
+ if schema_name is not None:
+ return escape_identifier(schema_name) + '.' + escape_identifier(table_name)
+ return escape_identifier(layername)
+
+# pylint: disable-next=invalid-name
+def getQualifiedLayerName(layername : str) -> tuple[str|None,str]:
+ """Return the qualified pair (schema_name, table_name) of a PostGIS layer name."""
+ if '.' in layername:
+ return tuple(layername.split('.', 1))
+ return (None, layername)
######
@@ -207,43 +285,42 @@ def gdal_version_min(maj=0, min=0, rev=0):
# and augmented with dir_fd.
# An alternative would be to use str(Path(f'/proc/self/fd/{dir_fd}').joinpath(path)).
-# Is a path a directory?
-# (From genericpath.py.)
-def isdir(path, dir_fd=None, follow_symlinks=True):
+def isdir(path : str, dir_fd : Optional[int] = None, follow_symlinks : bool = True) -> bool:
+ """Is a path a directory? (From genericpath.py.)"""
try:
st = os.stat(path, dir_fd=dir_fd, follow_symlinks=follow_symlinks)
except (OSError, ValueError):
return False
return S_ISDIR(st.st_mode)
-# Does a path exist?
-# (From genericpath.py.)
-def exists(path, dir_fd=None, follow_symlinks=True):
+def exists(path : str, dir_fd : Optional[int] = None, follow_symlinks : bool = True) -> bool:
+ """Does a path exist? (From genericpath.py.)"""
try:
os.stat(path, dir_fd=dir_fd, follow_symlinks=follow_symlinks)
except (OSError, ValueError):
return False
return True
-# Create a leaf directory and all intermediate ones.
-# (From os.py.)
-def makedirs(name, mode=0o777, exist_ok=False, dir_fd=None, logging=None):
- head, tail = path.split(name)
+def makedirs(name : str, mode : int = 0o777,
+ exist_ok : bool = False,
+ dir_fd : Optional[int] = None) -> None:
+ """Create a leaf directory and all intermediate ones. (From os.py.)"""
+
+ head, tail = os_path.split(name)
if not tail:
- head, tail = path.split(head)
+ head, tail = os_path.split(head)
if head and tail and not exists(head, dir_fd=dir_fd):
try:
- makedirs(head, exist_ok=exist_ok, dir_fd=dir_fd, logging=logging)
+ makedirs(head, exist_ok=exist_ok, dir_fd=dir_fd)
except FileExistsError:
# Defeats race condition when another thread created the path
pass
- cdir = os.curdir
+ cdir = os_curdir
if isinstance(tail, bytes):
- cdir = bytes(os.curdir, 'ASCII')
+ cdir = bytes(os_curdir, 'ASCII')
if tail == cdir: # xxx/newdir/. exists if xxx/newdir exists
return
- if logging is not None:
- logging.debug('mkdir("%s", 0%o)', name, mode)
+ logging.debug('mkdir("%s", 0%o)', name, mode)
try:
os.mkdir(name, mode, dir_fd=dir_fd)
except OSError:
diff --git a/common_gdal.py b/common_gdal.py
new file mode 100644
index 0000000..b5570eb
--- /dev/null
+++ b/common_gdal.py
@@ -0,0 +1,383 @@
+#!/usr/bin/python3
+
+#----------------------------------------------------------------------
+# Backend utilities for the Klimatanalys Norr project (common GDAL functions)
+# Copyright © 2024-2025 Guilhem Moulin <info@guilhem.se>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+#----------------------------------------------------------------------
+
+# pylint: disable=invalid-name, missing-module-docstring
+
+import logging
+import math
+import re
+from typing import Any, Optional
+
+from osgeo import gdal, ogr, osr
+
+from common import BadConfiguration, escape_identifier, getEscapedTableNamePG
+
+# pylint: disable-next=redefined-builtin
+def gdalVersionMin(maj : int = 0, min : int = 0, rev : int = 0) -> bool:
+ """Return a boolean indicating whether the installer GDAL version is
+ greater than or equal to the provider (maj, min, rev) triplet."""
+
+ if maj < 1 or (maj == 1 and min < 10):
+ # GDAL_VERSION_NUM() macro was changed in 1.10. That version
+ # was released in 2013 so we blindly assume the installer
+ # version is more recent
+ return True
+
+ version_cur = int(gdal.VersionInfo())
+ # cf. GDAL_COMPUTE_VERSION(maj,min,rev) in gcore/gdal_version.h.in
+ version_min = maj*1000000 + min*10000 + rev*100
+ return version_min <= version_cur
+
+def gdalGetMetadataItem(obj : gdal.MajorObject, k : str) -> bool:
+ """Wrapper around gdal.MajorObject.GetMetadataItem(name)."""
+
+ v = obj.GetMetadataItem(k)
+ if v is not None and isinstance(v, str):
+ return v.upper() == 'YES'
+
+ return False
+
+# pylint: disable-next=dangerous-default-value
+def gdalSetOpenExArgs(option_dict : Optional[dict[str, Any]] = {},
+ flags : int = 0) -> tuple[dict[str, int|list[str]], gdal.Driver]:
+ """Return a pair kwargs and driver to use with gdal.OpenEx()."""
+
+ kwargs = { 'nOpenFlags': flags }
+
+ fmt = option_dict.get('format', None)
+ if fmt is None:
+ drv = None
+ else:
+ drv = gdal.GetDriverByName(fmt)
+ if drv is None:
+ raise RuntimeError(f'Unknown driver name "{fmt}"')
+ if flags & gdal.OF_VECTOR and not gdalGetMetadataItem(drv, gdal.DCAP_VECTOR):
+ raise RuntimeError(f'Driver "{drv.ShortName}" has no vector capabilities')
+ if flags & gdal.OF_RASTER and not gdalGetMetadataItem(drv, gdal.DCAP_RASTER):
+ raise RuntimeError(f'Driver "{drv.ShortName}" has no raster capabilities')
+ kwargs['allowed_drivers'] = [ drv.ShortName ]
+
+ oo = option_dict.get('open-options', None)
+ if oo is not None:
+ kwargs['open_options'] = [ k + '=' + str(v) for k, v in oo.items() ]
+ return kwargs, drv
+
+def getSRS(srs_str : Optional[str]) -> osr.SpatialReference:
+ """Return the decoded Spatial Reference System."""
+
+ if srs_str is None:
+ return None
+
+ srs = osr.SpatialReference()
+ if srs_str.startswith('EPSG:'):
+ code = int(srs_str.removeprefix('EPSG:'))
+ srs.ImportFromEPSG(code)
+ else:
+ raise RuntimeError(f'Unknown SRS {srs_str}')
+
+ logging.debug('Default SRS: "%s" (%s)', srs.ExportToProj4(), srs.GetName())
+ return srs
+
+def getExtent(extent : Optional[tuple[float, float, float, float]],
+ srs : Optional[osr.SpatialReference] = None) -> ogr.Geometry:
+ """Convert extent (minX, minY, maxX, maxY) into a polygon and assign the
+ given SRS."""
+ if extent is None:
+ return None
+
+ if not isinstance(extent, tuple) or len(extent) != 4:
+ raise RuntimeError(f'Invalid extent {extent}')
+ if srs is None:
+ raise RuntimeError('Configured extent but no SRS')
+
+ logging.debug('Configured extent in %s: %s', srs.GetName(),
+ ', '.join(map(str, extent)))
+
+ ring = ogr.Geometry(ogr.wkbLinearRing)
+ ring.AddPoint_2D(extent[0], extent[1])
+ ring.AddPoint_2D(extent[2], extent[1])
+ ring.AddPoint_2D(extent[2], extent[3])
+ ring.AddPoint_2D(extent[0], extent[3])
+ ring.AddPoint_2D(extent[0], extent[1])
+
+ polygon = ogr.Geometry(ogr.wkbPolygon)
+ polygon.AddGeometry(ring)
+
+ # we expressed extent as minX, minY, maxX, maxY (easting/northing
+ # ordered, i.e., in traditional GIS order)
+ srs2 = srs.Clone()
+ srs2.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER)
+ polygon.AssignSpatialReference(srs2)
+ if not srs2.IsSame(srs):
+ polygon.TransformTo(srs)
+
+ return polygon
+
+def getSpatialFilterFromGeometry(geom : ogr.Geometry, srs : osr.SpatialReference) -> ogr.Geometry:
+ """Make the geometry suitable for use as a spatial filter. It is
+ densified the SRS:s are not equivalent."""
+ cloned = False
+ geom_srs = geom.GetSpatialReference()
+ if not geom_srs.IsSame(srs, [ 'IGNORE_DATA_AXIS_TO_SRS_AXIS_MAPPING=YES',
+ 'CRITERION=EQUIVALENT']):
+ # densify the geometry (a rectangle) to avoid issues when reprojecting,
+ # cf. apps/ogr2ogr_lib.cpp:ApplySpatialFilter()
+ segment_distance_metre = 10 * 1000
+ if geom_srs.IsGeographic():
+ cloned = True
+ geom = geom.Clone()
+ dfMaxLength = segment_distance_metre / math.radians(geom_srs.GetSemiMajor())
+ geom.Segmentize(dfMaxLength)
+ elif geom_srs.IsProjected():
+ cloned = True
+ geom = geom.Clone()
+ dfMaxLength = segment_distance_metre / geom_srs.GetLinearUnits()
+ geom.Segmentize(dfMaxLength)
+
+ if geom_srs.IsSame(srs):
+ return geom
+
+ if not cloned:
+ geom = geom.Clone()
+ if geom.TransformTo(srs) != ogr.OGRERR_NONE:
+ raise RuntimeError(f'Could not transform {geom.ExportToWkt()} to {srs.GetName()}')
+ return geom
+
+def formatTZFlag(tzFlag : int) -> str:
+ """Pretty-print timezone flag, cf. ogr/ogrutils.cpp:OGRGetISO8601DateTime()"""
+ if tzFlag is None:
+ raise RuntimeError('printTimeZone(None)')
+ if tzFlag == ogr.TZFLAG_UNKNOWN:
+ return 'none'
+ if tzFlag == ogr.TZFLAG_LOCALTIME:
+ return 'local'
+ if tzFlag == ogr.TZFLAG_UTC:
+ return 'UTC'
+
+ tzOffset = abs(tzFlag - ogr.TZFLAG_UTC) * 15
+ tzHour = int(tzOffset / 60)
+ tzMinute = int(tzOffset % 60)
+ tzSign = '+' if tzFlag > ogr.TZFLAG_UTC else '-'
+ return f'{tzSign}{tzHour:02}{tzMinute:02}'
+
+def fromGeomTypeName(name : str) -> int:
+ """Parse a Geometry type name, cf. ogr/ogrgeometry.cpp:OGRFromOGCGeomType()"""
+ name = name.upper()
+
+ isMeasured = False
+ if name.endswith('M'):
+ isMeasured = True
+ name = name.removesuffix('M')
+
+ convertTo3D = False
+ if name.endswith('Z'):
+ convertTo3D = True
+ name = name.removesuffix('Z')
+
+ if name == 'POINT':
+ eGType = ogr.wkbPoint
+ elif name == 'LINESTRING':
+ eGType = ogr.wkbLineString
+ elif name == 'POLYGON':
+ eGType = ogr.wkbPolygon
+ elif name == 'MULTIPOINT':
+ eGType = ogr.wkbMultiPoint
+ elif name == 'MULTILINESTRING':
+ eGType = ogr.wkbMultiLineString
+ elif name == 'MULTIPOLYGON':
+ eGType = ogr.wkbMultiPolygon
+ elif name == 'GEOMETRYCOLLECTION':
+ eGType = ogr.wkbGeometryCollection
+ elif name == 'CIRCULARSTRING':
+ eGType = ogr.wkbCircularString
+ elif name == 'COMPOUNDCURVE':
+ eGType = ogr.wkbCompoundCurve
+ elif name == 'CURVEPOLYGON':
+ eGType = ogr.wkbCurvePolygon
+ elif name == 'MULTICURVE':
+ eGType = ogr.wkbMultiCurve
+ elif name == 'MULTISURFACE':
+ eGType = ogr.wkbMultiSurface
+ elif name == 'TRIANGLE':
+ eGType = ogr.wkbTriangle
+ elif name == 'POLYHEDRALSURFACE':
+ eGType = ogr.wkbPolyhedralSurface
+ elif name == 'TIN':
+ eGType = ogr.wkbTIN
+ elif name == 'CURVE':
+ eGType = ogr.wkbCurve
+ elif name == 'SURFACE':
+ eGType = ogr.wkbSurface
+ else:
+ eGType = ogr.wkbUnknown
+
+ if convertTo3D:
+ eGType = ogr.GT_SetZ(eGType)
+
+ if isMeasured:
+ eGType = ogr.GT_SetM(eGType)
+
+ return eGType
+
+def parseGeomType(name : str|None) -> int:
+ """Parse geometry type, cf. ogr2ogr_lib.cpp"""
+ if name is None:
+ return ogr.wkbUnknown
+ name2 = name.upper()
+
+ is3D = False
+ if name2.endswith('25D'):
+ name2 = name2[:-3] # alias
+ is3D = True
+ elif name2.endswith('Z'):
+ name2 = name2[:-1]
+ is3D = True
+
+ if name2 == 'NONE':
+ eGType = ogr.wkbNone
+ elif name2 == 'GEOMETRY':
+ eGType = ogr.wkbUnknown
+ else:
+ eGType = fromGeomTypeName(name2)
+ if eGType == ogr.wkbUnknown:
+ raise BadConfiguration(f'Unknown geometry type "{name}"')
+
+ if eGType != ogr.wkbNone and is3D:
+ eGType = ogr.GT_SetZ(eGType)
+
+ return eGType
+
+
+def parseFieldType(name : str) -> int:
+ """Parse field type, cf. ogr/ogr_core.h's enum OGRFieldType"""
+ # pylint: disable=too-many-return-statements
+ if name is None:
+ raise RuntimeError('parseFieldType(None)')
+
+ name2 = name.lower()
+ if name2 == 'integer':
+ # simple 32bit integer
+ return ogr.OFTInteger
+ if name2 == 'integerlist':
+ # List of 32bit integers
+ return ogr.OFTIntegerList
+ if name2 == 'real':
+ # Double Precision floating point
+ return ogr.OFTReal
+ if name2 == 'reallist':
+ # List of doubles
+ return ogr.OFTRealList
+ if name2 == 'string':
+ # String of ASCII chars
+ return ogr.OFTString
+ if name2 == 'stringlist':
+ # Array of strings
+ return ogr.OFTStringList
+ if name2 == 'binary':
+ # Raw Binary data
+ return ogr.OFTBinary
+ if name2 == 'date':
+ # Date
+ return ogr.OFTDate
+ if name2 == 'time':
+ # Time
+ return ogr.OFTTime
+ if name2 == 'datetime':
+ # Date and Time
+ return ogr.OFTDateTime
+ if name2 == 'integer64':
+ # Single 64bit integer
+ return ogr.OFTInteger64
+ if name2 == 'integer64list':
+ # List of 64bit integers
+ return ogr.OFTInteger64List
+ raise BadConfiguration(f'Unknown field type "{name}"')
+
+def parseSubFieldType(name : str) -> int:
+ """Parse subfield type, cf. ogr/ogr_core.h's enum OGRFieldSubType"""
+ if name is None:
+ raise RuntimeError('parseSubFieldType(None)')
+ name2 = name.lower()
+ if name2 == 'none':
+ # No subtype. This is the default value.
+ return ogr.OFSTNone
+ if name2 == 'bool':
+ # Boolean integer. Only valid for OFTInteger and OFTIntegerList.
+ return ogr.OFSTBoolean
+ if name2 == 'int16':
+ # Signed 16-bit integer. Only valid for OFTInteger and OFTIntegerList.
+ return ogr.OFSTInt16
+ if name2 == 'float32':
+ # Single precision (32 bit) floating point. Only valid for OFTReal and OFTRealList.
+ return ogr.OFSTFloat32
+ if name2 == 'json':
+ # JSON content. Only valid for OFTString.
+ return ogr.OFSTJSON
+ if name2 == 'uuid':
+ # UUID string representation. Only valid for OFTString.
+ return ogr.OFSTUUID
+ raise BadConfiguration(f'Unknown field subtype "{name}"')
+
+TZ_RE = re.compile(r'(?:UTC\b)?([\+\-]?)([0-9][0-9]):?([0-9][0-9])', flags=re.IGNORECASE)
+def parseTimeZone(tz : str) -> int:
+ """Parse timezone."""
+ if tz is None:
+ raise RuntimeError('parseTimeZone(None)')
+ tz2 = tz.lower()
+ if tz2 == 'none':
+ return ogr.TZFLAG_UNKNOWN
+ if tz2 == 'local':
+ return ogr.TZFLAG_LOCALTIME
+ if tz2 in ('utc', 'gmt'):
+ return ogr.TZFLAG_UTC
+
+ m = TZ_RE.fullmatch(tz)
+ if m is None:
+ raise BadConfiguration(f'Invalid timezone "{tz}"')
+ tzSign = m.group(1)
+ tzHour = int(m.group(2))
+ tzMinute = int(m.group(3))
+ if tzHour > 14 or tzMinute >= 60 or tzMinute % 15 != 0:
+ raise BadConfiguration(f'Invalid timezone "{tz}"')
+ tzFlag = tzHour*4 + int(tzMinute/15)
+ if tzSign == '-':
+ tzFlag = ogr.TZFLAG_UTC - tzFlag
+ else:
+ tzFlag += ogr.TZFLAG_UTC
+ return tzFlag
+
+def getEscapedTableName(lyr : ogr.Layer, extract_schema_from_layer_name : bool = True) -> str:
+ """Return the layer name as an escaped identifier, suitable for injection into SQL queries.
+ For the PostgreSQL driver, an optional boolean (default: True) indicates whether the first
+ dot character is used as the separator between the schema and the table name."""
+ layername = lyr.GetName()
+ if lyr.GetDataset().GetDriver().ShortName == 'PostgreSQL':
+ return getEscapedTableNamePG(layername, extract_schema_from_layer_name)
+ return escape_identifier(layername)
+
+def executeSQL(ds : gdal.Dataset, statement : str,
+ spatialFilter : Optional[ogr.Geometry] = None) -> ogr.Layer|None:
+ """Wrapper for gdal.Dataset.ExecuteSQL().
+ https://gdal.org/en/stable/api/python/raster_api.html#osgeo.gdal.Dataset.ExecuteSQL"""
+ msg = statement
+ if spatialFilter is not None:
+ msg += ', spatialFilter=' + spatialFilter.ExportToWkt()
+ logging.debug('ExecuteSQL(%s)', msg)
+ return ds.ExecuteSQL(statement, spatialFilter=spatialFilter)
diff --git a/config.yml b/config.yml
index d3de950..c5daabb 100644
--- a/config.yml
+++ b/config.yml
@@ -22,20 +22,66 @@ extent:
- 1159296
- 7975712
-# Take User-Agent value from Tor Browser 13.0.15 (based on Mozilla Firefox 115.11.0esr)
-User-Agent: 'Mozilla/5.0 (Windows NT 10.0; rv:109.0) Gecko/20100101 Firefox/115.0'
+# Export options for MVT publishing, see
+# https://gdal.org/en/latest/drivers/vector/mvt.html
+vector-tiles:
+ min-zoom: 0 # res. 1024m/px
+ max-zoom: 7 # res. 8m/px
+ max-size: 4194304
+ max-features: 262144
+ tiling-scheme:
+ # Custom tiling scheme, cf. https://gdal.org/en/latest/drivers/vector/mvt.html#dataset-creation-options
+ # Compared to Lantmäteriet's scheme we start 2 levels deeper (resolution 1024m per pixel)
+ # and with 1024×1024 tiles
+ - 'EPSG:3006'
+ # upper-left corner of the upper-left tile (0,0) in the CRS
+ - 110720
+ - 7975712
+ # dimension of the tile at zoom level 0 (tile size * resolution)
+ - 1048576
+ # simplification factor, cf.
+ # https://gis.stackexchange.com/questions/401867/gdal-mvt-writer-simplification-parameter
+ simplification: 4.
+ simplification-max-zoom: 2.
+
+
+# Take User-Agent value from Tor Browser 15.0 (based on Mozilla Firefox 140.4.0esr)
+User-Agent: 'Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0'
# Map group names to one or more pattern of layer name(s). This is a convenience feature
# for systemd template units.
layer-groups:
- administrativindelning:
- - lansyta
- - kommunyta
- nvr: 'nvr:*'
- sks: 'sks:*'
- st: 'st:*'
- vbk: 'vbk:*'
- mrr: 'mrr:*'
+ adm:
+ - 'lm_topo250.lansyta'
+ - 'lm_topo250.kommunyta'
+ skydd:
+ - 'nvr.*'
+ - 'nvk.naturvardsavtal'
+ - 'sks.naturvardsavtal'
+ - 'sks.atervatningsavtal'
+ avverk:
+ - 'sks.avverk_anmald'
+ - 'sks.avverk_utford'
+ ren:
+ - 'sametinget.*'
+ vbk: 'vbk.*'
+ mrr: 'mrr.*'
+ ri:
+ - 'nvk.riksintresse_*'
+ - 'lst.riksintresse_*'
+ svk: 'svk.*'
+ misc:
+ - 'misc.dammar'
+ - 'misc.gigafactories'
+ nv:
+ - 'sks.nyckelbiotop'
+ - 'sks.nyckelbiotop_storskogsbruk'
+ - 'sks.naturvarde'
+ - 'sks.sumpskog'
+ - 'nvk.skyddsvard_statlig_skog'
+ - 'lst.pagaende_naturreservatsbildning'
+ kskog:
+ - 'nvk.kskog'
# Global GDAL/OGR configuration options, cf. https://gdal.org/user/configoptions.html and
@@ -64,9 +110,10 @@ dataset:
# https://gdal.org/drivers/vector/pg.html#dataset-open-options or
# https://gdal.org/drivers/vector/gpkg.html#dataset-open-options
open-options:
- ACTIVE_SCHEMA: postgis
- USER: webmap_import
- DBNAME: webmap
+ USER: geodata
+ DBNAME: geodata
+
+ layercache: public.layercache
# Optional dictionary of default layer creation options, cf.
# https://gdal.org/drivers/vector/pg.html#layer-creation-options or
@@ -75,14 +122,501 @@ dataset:
create-layer-options:
FID64: 'YES'
LAUNDER: 'NO'
- EXTRACT_SCHEMA_FROM_LAYER_NAME: 'NO'
+ EXTRACT_SCHEMA_FROM_LAYER_NAME: 'YES'
+
+
+downloads:
+# # List of cached paths and download recipes.
+#
+# - # URL from where to download the source file. path/to/file.gpkg can be used as
+# # an alias when path/to/file.gpkg:url is its only subkey.
+# url: 'https://example.net/path/to/file.gpkg'
+#
+# # Where to download the file.
+# path: path/to/file.gpkg
+#
+# # The maximum size to download in bytes. An error is raised when the payload
+# # size exceeds this value.
+# # (Default: 67108864, in other words 64MiB)
+# max-size: 1073741824
+#
+# # Maximum age for caching, in number of seconds ago. If the downloaded path
+# # exists and its mtime and/or ctime is newer than this value then no HTTP
+# # query is made.
+# # (Default: 21600, in other words 6h)
+# max-age: 86400
+#
+# For convenience
+#
+# - path: path/to/file1.gpkg
+# url: https://example.net/file1.gpkg
+# - path: path/to/sub/file2.gpkg
+# url: https://example.net/sub/file2.gpkg
+#
+# can be shortened as follow
+#
+# - basedir: path/to/
+# baseurl: https://example.net/
+# files:
+# - file1.gpkg
+# - sub/file2.gpkg
+
+ - basedir: nvk/nvr/
+ baseurl: https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/
+ files:
+ - TILLTRADESFORBUD.zip
+ - NP.zip
+ - NR.zip
+ - NVO.zip
+ - DVO.zip
+ - KR.zip
+ - VSO.zip
+ - LBSO.zip
+ - OBO.zip
+ - NM.zip
+ - IF.zip
+ - SPA_Rikstackande.zip
+ - HELCOM.zip
+ - Ramsar_2018.zip
+ - OSPAR.zip
+ - Varldsarv.zip
+ - biosfarsomraden.zip
+ - NVA.zip
+
+ - path: nvk/nvr/SCI_Rikstackande.zip
+ url: https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/SCI_Rikstackande.zip
+ max-size: 134217728 # 128MiB
+
+ - path: nvk/Skyddsvarda_statliga_skogar.zip
+ url: https://geodata.naturvardsverket.se/nedladdning/skog/Skyddsvarda_statliga_skogar.zip
+
+ - path: nvk/Sannolikt_och_potentiell_kontinuitetsskog_BorealRegion_2024.zip
+ url: https://geodata.naturvardsverket.se/nedladdning/Kartering_av_kontinuitetsskog/Sannolikt_och_potentiell_kontinuitetsskog_BorealRegion_2024.zip
+ max-size: 268435456 # 256MiB
+
+ - basedir: nvk/
+ baseurl: https://geodata.naturvardsverket.se/nedladdning/riksintresse/
+ files:
+ - RI_Naturvard.zip
+ - RI_Friluftsliv.zip
+
+ - basedir: lst/
+ baseurl: https://ext-dokument.lansstyrelsen.se/gemensamt/geodata/ShapeExport/
+ files:
+ - lst.LST_RI_Rorligt_friluftsliv_MB4kap2.zip
+ - lst.LST_RI_Obruten_kust_MB4kap3.zip
+ - lst.Lst_RI_Obrutet_fjall_MB4kap5.zip
+ - lst.LST_RI_Skyddade_vattendrag_MB4kap6.zip
+ - lstext.Pagaende_reservatsbildning.zip
+
+ - basedir: sks/
+ baseurl: https://geodpags.skogsstyrelsen.se/geodataport/data/
+ files:
+ - sksBiotopskydd_gpkg.zip
+ - sksNaturvardsavtal_gpkg.zip
+ - sksNyckelbiotoper_gpkg.zip
+ - sksStorskogsbrNyckelb_gpkg.zip
+ - sksNaturvarden_gpkg.zip
+ - sksAtervatningYta_gpkg.zip
+
+ - path: sks/sksSumpskogar_gpkg.zip
+ url: https://geodpags.skogsstyrelsen.se/geodataport/data/sksSumpskogar_gpkg.zip
+ max-size: 268435456 # 256MiB
+
+ - path: sks/sksAvverkAnm_gpkg.zip
+ url: https://geodpags.skogsstyrelsen.se/geodataport/data/sksAvverkAnm_gpkg.zip
+ max-size: 134217728 # 128MiB
+
+ - path: sks/sksUtfordAvverk_gpkg.zip
+ url: https://geodpags.skogsstyrelsen.se/geodataport/data/sksUtfordAvverk_gpkg.zip
+ max-size: 4294967296 # 4GiB
+ #max-age: 216000 # 60h
+
+ - basedir: vbk/
+ baseurl: https://ext-dokument.lansstyrelsen.se/gemensamt/geodata/ShapeExport/
+ files:
+ - lst.vbk_vindkraftverk.zip
+ - lst.vbk_projekteringsomraden.zip
+ - lst.vbk_havsbaserad_vindkraft.zip
+
+ - basedir: sametinget/
+ baseurl: https://ext-dokument.lansstyrelsen.se/Gemensamt/Geodata/Datadistribution/SWEREF99TM/Sametinget/
+ files:
+ - Samebyarnas_betesomraden.zip
+ - Samebyarnas_markanvandningsredovisning.zip
+
+ - basedir: sametinget/
+ baseurl: https://ext-dokument.lansstyrelsen.se/gemensamt/geodata/ShapeExport/
+ files:
+ - ren.riks_ren.zip
+ - ren.omr_riks.zip
+
+ - path: mrr/mineralrattigheter.zip
+ url: https://resource.sgu.se/data/oppnadata/mineralrattigheter/mineralrattigheter.zip
+
+ - path: svk/SVK_STAMNAT.zip
+ url: https://gis-services.metria.se/svkfeed/filer/SVK_STAMNAT.zip
+
+license-info:
+ # Map source paths to their metada (description, copyright, license information and link).
+ administrativindelning_sverige.zip:
+ description: Topografi 250 Nedladdning, vektor
+ copyright: © Lantmäteriet
+ product_url: https://www.lantmateriet.se/sv/geodata/vara-produkter/produktlista/topografi-250-nedladdning-vektor/
+ license:
+ name: CC0 1.0 Universiell
+ url: https://creativecommons.org/publicdomain/zero/1.0/deed.sv
+ nvk/nvr/TILLTRADESFORBUD.zip:
+ description: "Skyddade områden: tillträdesförbud (föreskriftsområden)"
+ copyright: © Naturvårdsverket
+ product_url: https://geodatakatalogen.naturvardsverket.se/geonetwork/srv/swe/catalog.search#/metadata/F2554ED6-3A9B-4955-B4AC-D61B35026C88
+ license:
+ name: CC0 1.0 Universiell
+ url: https://creativecommons.org/publicdomain/zero/1.0/deed.sv
+ nvk/nvr/NP.zip:
+ description: "Skyddade områden: nationalparker"
+ copyright: © Naturvårdsverket
+ product_url: https://geodatakatalogen.naturvardsverket.se/geonetwork/srv/swe/catalog.search#/metadata/bfc33845-ffb9-4835-8355-76af3773d4e0
+ license:
+ name: CC0 1.0 Universiell
+ url: https://creativecommons.org/publicdomain/zero/1.0/deed.sv
+ nvk/nvr/NR.zip:
+ description: "Skyddade områden: naturreservat"
+ copyright: © Naturvårdsverket
+ product_url: https://geodatakatalogen.naturvardsverket.se/geonetwork/srv/swe/catalog.search#/metadata/2921b01a-0baf-4702-a89f-9c5626c97844
+ license:
+ name: CC0 1.0 Universiell
+ url: https://creativecommons.org/publicdomain/zero/1.0/deed.sv
+ nvk/nvr/NVO.zip:
+ description: "Skyddade områden: naturvårdsområden"
+ copyright: © Naturvårdsverket
+ product_url: https://geodatakatalogen.naturvardsverket.se/geonetwork/srv/swe/catalog.search#/metadata/dd8371a0-f692-44e3-bd0b-25de8dee8906
+ license:
+ name: CC0 1.0 Universiell
+ url: https://creativecommons.org/publicdomain/zero/1.0/deed.sv
+ nvk/nvr/DVO.zip:
+ description: "Skyddade områden: djur- och växtskyddsområden"
+ copyright: © Naturvårdsverket
+ product_url: https://geodatakatalogen.naturvardsverket.se/geonetwork/srv/swe/catalog.search#/metadata/b4bb8837-8980-4093-be7e-c09f650df996
+ license:
+ name: CC0 1.0 Universiell
+ url: https://creativecommons.org/publicdomain/zero/1.0/deed.sv
+ nvk/nvr/KR.zip:
+ description: "Skyddade områden: kulturreservat"
+ copyright: © Naturvårdsverket
+ product_url: https://geodatakatalogen.naturvardsverket.se/geonetwork/srv/swe/catalog.search#/metadata/55d17118-f977-46c9-8691-20baf657796e
+ license:
+ name: CC0 1.0 Universiell
+ url: https://creativecommons.org/publicdomain/zero/1.0/deed.sv
+ nvk/nvr/VSO.zip:
+ description: "Skyddade områden: vattenskyddsområden"
+ copyright: © Naturvårdsverket
+ product_url: https://geodatakatalogen.naturvardsverket.se/geonetwork/srv/swe/catalog.search#/metadata/ae8d79d2-a799-4e1b-b500-05747a428816
+ license:
+ name: CC0 1.0 Universiell
+ url: https://creativecommons.org/publicdomain/zero/1.0/deed.sv
+ nvk/nvr/LBSO.zip:
+ description: "Landskapsbildsskyddsområde"
+ copyright: © Naturvårdsverket
+ product_url: https://geodatakatalogen.naturvardsverket.se/geonetwork/srv/swe/catalog.search#/metadata/bf435698-15a4-4b0b-85ec-727605a0a6ba
+ license:
+ name: Inga begränsningar
+ url: https://inspire.ec.europa.eu/metadata-codelist/LimitationsOnPublicAccess/noLimitations
+ sks/sksBiotopskydd_gpkg.zip:
+ description: "Biotopskydd beslutade av Skogsstyrelsen"
+ copyright: © Skogsstyrelsen
+ product_url: https://www.geodata.se/geodataportalen/GetMetaDataById?ID=772d46b8-25a2-42f7-b3da-4b17f610bc53
+ license:
+ name: CC0 1.0 Universiell
+ url: https://creativecommons.org/publicdomain/zero/1.0/deed.sv
+ nvk/nvr/OBO.zip:
+ description: "Skyddade områden: biotopskyddsområden"
+ copyright: © Naturvårdsverket
+ product_url: https://geodatakatalogen.naturvardsverket.se/geonetwork/srv/swe/catalog.search#/metadata/c3dd73b1-1c82-4db5-aac3-c8c6f240fa25
+ license:
+ name: CC0 1.0 Universiell
+ url: https://creativecommons.org/publicdomain/zero/1.0/deed.sv
+ nvk/nvr/NM.zip:
+ description: "Skyddade områden: naturminnen"
+ copyright: © Naturvårdsverket
+ product_url: https://geodatakatalogen.naturvardsverket.se/geonetwork/srv/swe/catalog.search#/metadata/c6b02e88-8084-4b3f-8a7d-33e5d45349c4
+ license:
+ name: CC0 1.0 Universiell
+ url: https://creativecommons.org/publicdomain/zero/1.0/deed.sv
+ nvk/nvr/IF.zip:
+ description: "Skyddade områden: interimistiska förbud"
+ copyright: © Naturvårdsverket
+ product_url: https://geodatakatalogen.naturvardsverket.se/geonetwork/srv/swe/catalog.search#/metadata/03e6e0d2-9ff8-4234-8dba-1a1ef88cb1ad
+ license:
+ name: CC0 1.0 Universiell
+ url: https://creativecommons.org/publicdomain/zero/1.0/deed.sv
+ nvk/nvr/SPA_Rikstackande.zip:
+ description: "Skyddade områden: fågeldirektivet (Natura 2000, SPA)"
+ copyright: © Naturvårdsverket
+ product_url: https://geodatakatalogen.naturvardsverket.se/geonetwork/srv/swe/catalog.search#/metadata/a80bf3d7-e70c-42d1-9b8d-8148e53e011d
+ license:
+ name: CC0 1.0 Universiell
+ url: https://creativecommons.org/publicdomain/zero/1.0/deed.sv
+ nvk/nvr/SCI_Rikstackande.zip:
+ description: "Skyddade områden: Art- och habitatdirektivet (Natura2000, SCI, SAC)"
+ copyright: © Naturvårdsverket
+ product_url: https://geodatakatalogen.naturvardsverket.se/geonetwork/srv/swe/catalog.search#/metadata/945e918f-8426-4155-8fd6-3f780a85dd8f
+ license:
+ name: CC0 1.0 Universiell
+ url: https://creativecommons.org/publicdomain/zero/1.0/deed.sv
+ nvk/nvr/HELCOM.zip:
+ description: "Skyddade områden: marina områden i Sverige enligt Helcom (MPA)"
+ copyright: © Naturvårdsverket
+ product_url: https://geodatakatalogen.naturvardsverket.se/geonetwork/srv/swe/catalog.search#/metadata/834a442f-310f-4d2d-bd12-d8978d9683c5
+ license:
+ name: CC0 1.0 Universiell
+ url: https://creativecommons.org/publicdomain/zero/1.0/deed.sv
+ nvk/nvr/Ramsar_2018.zip:
+ description: "Skyddade områden: Ramsarområden"
+ copyright: © Naturvårdsverket
+ product_url: https://geodatakatalogen.naturvardsverket.se/geonetwork/srv/swe/catalog.search#/metadata/f2d8691f-8b75-4a62-8d94-7cb1982cceea
+ license:
+ name: CC0 1.0 Universiell
+ url: https://creativecommons.org/publicdomain/zero/1.0/deed.sv
+ nvk/nvr/OSPAR.zip:
+ description: "Skyddade områden: marina områden i Sverige enligt Ospar"
+ copyright: © Naturvårdsverket
+ product_url: https://geodatakatalogen.naturvardsverket.se/geonetwork/srv/swe/catalog.search#/metadata/39948786-a278-4cdb-8b95-2ce99f941f65
+ license:
+ name: CC0 1.0 Universiell
+ url: https://creativecommons.org/publicdomain/zero/1.0/deed.sv
+ nvk/nvr/Varldsarv.zip:
+ description: "Skyddade områden: världsarv med höga naturvärden"
+ copyright: © Naturvårdsverket
+ product_url: https://geodatakatalogen.naturvardsverket.se/geonetwork/srv/swe/catalog.search#/metadata/f57de73f-0ce0-4be0-a638-5778bec38cde
+ license:
+ name: CC0 1.0 Universiell
+ url: https://creativecommons.org/publicdomain/zero/1.0/deed.sv
+ nvk/nvr/biosfarsomraden.zip:
+ description: "Skyddade områden: biosfärsområden"
+ copyright: © Naturvårdsverket
+ product_url: https://geodatakatalogen.naturvardsverket.se/geonetwork/srv/swe/catalog.search#/metadata/bc2ce857-fa87-42f6-8870-fbdc3a9b113e
+ license:
+ name: CC0 1.0 Universiell
+ url: https://creativecommons.org/publicdomain/zero/1.0/deed.sv
+ nvk/nvr/NVA.zip:
+ description: "Områden som omfattas av naturvårdsavtal (Naturvårdsverket, Länsstyrelsen)"
+ copyright: © Naturvårdsverket
+ product_url: https://geodatakatalogen.naturvardsverket.se/geonetwork/srv/swe/catalog.search#/metadata/3a5790ff-8cd3-45ea-bbee-28cf2c1b6b06
+ license:
+ name: CC0 1.0 Universiell
+ url: https://creativecommons.org/publicdomain/zero/1.0/deed.sv
+ sks/sksNaturvardsavtal_gpkg.zip:
+ description: "Naturvårdsavtal upprättade av Skogsstyrelsen"
+ copyright: © Skogsstyrelsen
+ product_url: https://www.geodata.se/geodataportalen/GetMetaDataById?ID=f56d281c-8246-40aa-83cd-9db0d4389d5a
+ license:
+ name: CC0 1.0 Universiell
+ url: https://creativecommons.org/publicdomain/zero/1.0/deed.sv
+ nvk/Skyddsvarda_statliga_skogar.zip:
+ description: "Skyddsvärda statliga skogar"
+ copyright: © Naturvårdsverket
+ product_url: https://geodatakatalogen.naturvardsverket.se/geonetwork/srv/swe/catalog.search#/metadata/3919E66E-2E09-440D-9171-B5074DF0C0ED
+ license: Inga begränsningar
+ lst/lstext.Pagaende_reservatsbildning.zip:
+ description: "LstBD Pågående naturreservatsbildning"
+ copyright: © Länsstyrelsen i Norrbottens län
+ product_url: https://ext-geodatakatalog.lansstyrelsen.se/GeodataKatalogen/srv/api/records/GetMetaDataById?id=8c0b5c30-806d-49e9-8d8d-1f866c354386
+ license:
+ name: CC BY 4.0
+ url: https://creativecommons.org/licenses/by/4.0/deed.sv
+ sks/sksAvverkAnm_gpkg.zip:
+ description: "Avverkningsanmälningar"
+ copyright: © Skogsstyrelsen
+ product_url: https://www.skogsstyrelsen.se/e-tjanster-och-kartor/karttjanster/skogsstyrelsens-geodata/
+ license:
+ # https://www.skogsstyrelsen.se/e-tjanster-och-kartor/karttjanster/geodatatjanster/villkor/
+ name: CC0 1.0 Universiell
+ url: https://creativecommons.org/publicdomain/zero/1.0/deed.sv
+ sks/sksUtfordAvverk_gpkg.zip:
+ description: "Utförda avverkningar"
+ copyright: © Skogsstyrelsen
+ product_url: https://www.skogsstyrelsen.se/e-tjanster-och-kartor/karttjanster/skogsstyrelsens-geodata/
+ license:
+ # https://www.skogsstyrelsen.se/e-tjanster-och-kartor/karttjanster/geodatatjanster/villkor/
+ name: CC0 1.0 Universiell
+ url: https://creativecommons.org/publicdomain/zero/1.0/deed.sv
+ sks/sksNyckelbiotoper_gpkg.zip:
+ description: "Nyckelbiotoper - Skogsstyrelsen"
+ copyright: © Skogsstyrelsen
+ product_url: https://www.skogsstyrelsen.se/e-tjanster-och-kartor/karttjanster/skogsstyrelsens-geodata/
+ license:
+ # https://www.skogsstyrelsen.se/e-tjanster-och-kartor/karttjanster/geodatatjanster/villkor/
+ name: CC0 1.0 Universiell
+ url: https://creativecommons.org/publicdomain/zero/1.0/deed.sv
+ sks/sksStorskogsbrNyckelb_gpkg.zip:
+ description: "Nyckelbiotoper - storskogsbruket"
+ copyright: © Skogsstyrelsen
+ product_url: https://www.skogsstyrelsen.se/e-tjanster-och-kartor/karttjanster/skogsstyrelsens-geodata/
+ license:
+ # https://www.skogsstyrelsen.se/e-tjanster-och-kartor/karttjanster/geodatatjanster/villkor/
+ name: CC0 1.0 Universiell
+ url: https://creativecommons.org/publicdomain/zero/1.0/deed.sv
+ sks/sksNaturvarden_gpkg.zip:
+ description: "Objekt med naturvärden"
+ copyright: © Skogsstyrelsen
+ product_url: https://www.skogsstyrelsen.se/e-tjanster-och-kartor/karttjanster/skogsstyrelsens-geodata/
+ license:
+ # https://www.skogsstyrelsen.se/e-tjanster-och-kartor/karttjanster/geodatatjanster/villkor/
+ name: CC0 1.0 Universiell
+ url: https://creativecommons.org/publicdomain/zero/1.0/deed.sv
+ sks/sksSumpskogar_gpkg.zip:
+ description: "Sumpskogar"
+ copyright: © Skogsstyrelsen
+ product_url: https://www.skogsstyrelsen.se/e-tjanster-och-kartor/karttjanster/skogsstyrelsens-geodata/
+ license:
+ # https://www.skogsstyrelsen.se/e-tjanster-och-kartor/karttjanster/geodatatjanster/villkor/
+ name: CC0 1.0 Universiell
+ url: https://creativecommons.org/publicdomain/zero/1.0/deed.sv
+ sks/sksAtervatningYta_gpkg.zip:
+ description: "Återvätningsavtal"
+ copyright: © Skogsstyrelsen
+ product_url: https://www.skogsstyrelsen.se/e-tjanster-och-kartor/karttjanster/skogsstyrelsens-geodata/
+ license:
+ # https://www.skogsstyrelsen.se/e-tjanster-och-kartor/karttjanster/geodatatjanster/villkor/
+ name: CC0 1.0 Universiell
+ url: https://creativecommons.org/publicdomain/zero/1.0/deed.sv
+ nvk/Sannolikt_och_potentiell_kontinuitetsskog_BorealRegion_2024.zip:
+ description: "Sannolikt och potentiell kontinuitetsskog (preciserad 2024)"
+ product_url: https://geodatakatalogen.naturvardsverket.se/geonetwork/srv/swe/catalog.search#/metadata/2b9d4c76-3b0e-4a55-a16c-51513da84558
+ #product_url: https://geodata.naturvardsverket.se/nedladdning/Kartering_av_kontinuitetsskog/Leverans-PM_Sannolikt_och_potentiell_kontinuitetsskog_i_Boreal_Region_2024.pdf
+ copyright: © Naturvårdsverket
+ license: Inga begränsningar
+ mrr/mineralrattigheter.zip:
+ description: "Mineralrättigheter och prospektering"
+ copyright: © Sveriges geologiska undersökning (utdrag ur Bergsstatens mineralrättsregister)
+ product_url: https://www.sgu.se/produkter-och-tjanster/geologiska-data/malmer-och-mineral--geologiska-data/mineralrattigheter-och-prospektering/
+ license:
+ name: CC0 1.0 Universiell
+ url: https://creativecommons.org/publicdomain/zero/1.0/deed.sv
+ sametinget/ren.riks_ren.zip:
+ description: "Riksintresse Rennäringen"
+ copyright: © Sametinget
+ product_url: https://ext-geodatakatalog-forv.lansstyrelsen.se/PlaneringsKatalogen/GetMetaDataById?id=103cf137-9d56-452b-97d6-9b12cba6c864_C
+ license:
+ name: CC BY 4.0
+ url: https://creativecommons.org/licenses/by/4.0/deed.sv
+ sametinget/ren.omr_riks.zip:
+ description: "Riksintresse Rennäringen - Kärnområde"
+ copyright: © Sametinget
+ product_url: https://ext-geodatakatalog-forv.lansstyrelsen.se/PlaneringsKatalogen/GetMetaDataById?id=b665a528-cd25-4612-8ab3-fa3e692b46c3_C
+ license:
+ name: CC BY 4.0
+ url: https://creativecommons.org/licenses/by/4.0/deed.sv
+ sametinget/Samebyarnas_markanvandningsredovisning.zip:
+ description: "Samebyarnas markanvändningsområden"
+ copyright: © Sametinget (Rennäringens markanvändningsdatabas IRENMARK)
+ product_url: https://ext-geodatakatalog-forv.lansstyrelsen.se/PlaneringsKatalogen/GetMetaDataById?id=19b7addd-a790-4829-991f-f2266009e863_C
+ # Licens behövs, cf. 'Samebyarnas markanvändningsredovisning/avtal.pdf'
+ license: Se avtal.pdf i zip-filen
+ sametinget/Samebyarnas_betesomraden.zip:
+ description: "Samebyarnas betesområden"
+ copyright: © Sametinget (Rennäringens markanvändningsdatabas, IRENMARK)
+ product_url: https://ext-geodatakatalog-forv.lansstyrelsen.se/PlaneringsKatalogen/GetMetaDataById?id=a216dea8-bfcb-4984-a18b-3a421cde2d57_C
+ # Licens behövs, cf. 'Samebyarnas_betesomraden/Samebyarnas betesområden/avtal.pdf'
+ license: Se avtal.pdf i zip-filen
+ nvk/RI_Naturvard.zip:
+ description: "Riksintresse naturvård"
+ copyright: © Naturvårdsverket
+ product_url: https://geodatakatalogen.naturvardsverket.se/geonetwork/srv/swe/catalog.search#/metadata/fb9ff32f-b6f8-4d8e-ac5c-20ebb0986908
+ license:
+ name: CC0 1.0 Universiell
+ url: https://creativecommons.org/publicdomain/zero/1.0/deed.sv
+ nvk/RI_Friluftsliv.zip:
+ description: "Riksintresse friluftsliv"
+ copyright: © Naturvårdsverket
+ product_url: https://geodatakatalogen.naturvardsverket.se/geonetwork/srv/swe/catalog.search#/metadata/22afb5cb-cdb0-4f3a-8b0f-a34344285864
+ license:
+ name: CC0 1.0 Universiell
+ url: https://creativecommons.org/publicdomain/zero/1.0/deed.sv
+ lst/lst.LST_RI_Rorligt_friluftsliv_MB4kap2.zip:
+ description: "Riksintresse rörligt friluftsliv (MB 4 kap 1 och 2 §§)"
+ copyright: © Länsstyrelsen
+ product_url: https://ext-geodatakatalog.lansstyrelsen.se/GeodataKatalogen/srv/api/records/GetMetaDataById?id=072b6b36-2cf6-4717-a616-bbf3fddea83d
+ license:
+ name: CC BY 4.0
+ url: https://creativecommons.org/licenses/by/4.0/deed.sv
+ lst/lst.LST_RI_Obruten_kust_MB4kap3.zip:
+ description: "Riksintresse obruten kust (MB 4 kap 3 §)"
+ copyright: © Länsstyrelsen — Förvaltningsobjekt Samhällsplanerin
+ product_url: https://ext-geodatakatalog.lansstyrelsen.se/GeodataKatalogen/srv/api/records/GetMetaDataById?id=2b5b141f-a9a4-433a-8dc7-bf983acdb859
+ license:
+ name: CC0 1.0 Universiell
+ url: https://creativecommons.org/publicdomain/zero/1.0/deed.sv
+ lst/lst.Lst_RI_Obrutet_fjall_MB4kap5.zip:
+ description: "Riksintresse obrutet fjäll (MB 4 kap 5 §)"
+ copyright: © Länsstyrelsen
+ product_url: https://ext-geodatakatalog.lansstyrelsen.se/GeodataKatalogen/srv/api/records/GetMetaDataById?id=b1d59cb0-2e71-4c08-b99d-e4cc7507cb92
+ license: Inga begränsningar
+ lst/lst.LST_RI_Skyddade_vattendrag_MB4kap6.zip:
+ description: "Riksintresse skyddade vattendrag (MB 4 kap 6 §)"
+ copyright: © Länsstyrelsen
+ product_url: https://ext-geodatakatalog.lansstyrelsen.se/GeodataKatalogen/srv/api/records/GetMetaDataById?id=61e21a50-4320-4db4-8e44-56252dab777e
+ license:
+ name: CC BY 4.0
+ url: https://creativecommons.org/licenses/by/4.0/deed.sv
+ vbk/lst.vbk_vindkraftverk.zip:
+ description: "Vindbrukskollen landbaserade vindkraftverk"
+ copyright: © Länsstyrelsen
+ product_url: https://ext-geodatakatalog.lansstyrelsen.se/GeodataKatalogen/srv/api/records/GetMetaDataById?id=ed5814b2-08bf-493a-a164-7819e1b590d6
+ license:
+ name: CC0 1.0 Universiell
+ url: https://creativecommons.org/publicdomain/zero/1.0/deed.sv
+ vbk/lst.vbk_projekteringsomraden.zip:
+ description: "Vindbrukskollen landbaserade projekteringsområden och vägar"
+ copyright: © Länsstyrelsen
+ product_url: https://ext-geodatakatalog-forv.lansstyrelsen.se/PlaneringsKatalogen/GetMetaDataById?id=c816bd1e-bc6c-487f-a962-770f05f677b6_C
+ license:
+ name: CC0 1.0 Universiell
+ url: https://creativecommons.org/publicdomain/zero/1.0/deed.sv
+ vbk/lst.vbk_havsbaserad_vindkraft.zip:
+ description: "Vindbrukskollen havsbaserad vindkraft"
+ copyright: © Länsstyrelsen
+ product_url: https://ext-geodatakatalog.lansstyrelsen.se/GeodataKatalogen/srv/api/records/GetMetaDataById?id=c290bc31-1af8-497e-a9a5-87fcec55d0ce
+ license:
+ name: CC0 1.0 Universiell
+ url: https://creativecommons.org/publicdomain/zero/1.0/deed.sv
+ svk/SVK_STAMNAT.zip:
+ description: "Transmissionsnät för el i Sverige"
+ copyright: © Svenska kraftnät
+ product_url: https://ext-geodatakatalog-forv.lansstyrelsen.se/PlaneringsKatalogen/GetMetaDataById?id=08ec56a0-6b5c-4f83-b29e-375e6f1a34b9_C
+ license: Okänd
+ custom/svk/transmissionsnatsprojekt.geojson:
+ description: "Transmissionsnätsprojekt"
+ copyright: © Guilhem Moulin (egen ritning baserad på SvK:s tillståndsansökningar och handlingar)
+ product_url: https://www.svk.se/utveckling-av-kraftsystemet/transmissionsnatet/transmissionsnatsprojekt/
+ license:
+ name: CC0 1.0 Universiell
+ url: https://creativecommons.org/publicdomain/zero/1.0/deed.sv
+ custom/gigafactories.geojson:
+ description: "Stora industrisatsningar"
+ copyright: © Guilhem Moulin
+ license:
+ name: CC0 1.0 Universiell
+ url: https://creativecommons.org/publicdomain/zero/1.0/deed.sv
+ custom/HY_PhysicalWaters_ManMadeObject.zip:
+ description: "Dammregistret"
+ copyright: © Sveriges meteorologiska och hydrologiska institut (SMHI)
+ product_url: https://www.smhi.se/data/sok-oppna-data-i-utforskaren/se-hy-dammregistret
+ license:
+ name: CC BY 4.0
+ url: https://creativecommons.org/licenses/by/4.0/deed.sv
layers:
-# # Dictionary of layer names and source receipes in the output dataset. If a layer
+# # Dictionary of layer names and source recipes in the output dataset. If a layer
# # has a single source, then the sources singleton can be inlined.
# layer1_name:
# description: A string describing that layer
+#
+# # Whether to CLUSTER on the geometry index after importing
+# cluster-geometry: true
+#
# create:
# # Geometry Type for the output layer. Possible values are like ogr2ogr(1)'s -nlt
# # value, namely one of NONE, GEOMETRY, POINT, LINESTRING, POLYGON, MULTIPOINT,
@@ -167,37 +701,10 @@ layers:
#
# sources:
# - source:
-# download:
-# # URL from where to download the source file. source:download can be used as
-# # an alias when source:download:url is its only subkey.
-# url: 'https://example.net/path/to/layer.zip'
-#
-# # The maximum size to download in bytes. An error is raised when the payload
-# # size exceeds this value.
-# # (Default: 67108864, in other words 64MiB)
-# max-size: 1073741824
+# # Local source path (relative to --cachedir).
+# path: path/to/source/file.zip
#
-# # Basename of the download module to use for that layer.
-# module: webmap-download
-#
-# cache:
-# # Local path (relative to --cachedir) where to (atomically) save the
-# # downloaded file. The same path can be used by multiple entries as long as
-# # their pairs (source:download:url, source:download:module) match. Any
-# # parent directories are created if needed. If the path is empty or ends
-# # with a '/' character then it treated as a directory and the last component
-# # of source:download:url implicitly used as filename. In that case an error
-# # is raised if no filename can be derived from the URL. source:cache can be
-# # used as an alias when source:cache:path is its only subkey.
-# path: path/to/sub/dir/
-#
-# # Maximum age for caching, in number of seconds ago. If source:cache:path
-# # exists and its mtime and/or ctime is newer than this value then no HTTP
-# # query is made.
-# # (Default: 21600, in other words 6h)
-# max-age: 86400
-#
-# # Optional extracting receipe for archived/compressed sources
+# # Optional extracting recipe for archived/compressed sources
# unar:
# # The archiving format (only 'zip' is currently supported)
# format: zip
@@ -210,7 +717,7 @@ layers:
# import:
# # Path for the dataset holding the source layer (relative to the archive root
# # for archived sources, and to --cachedir otherwise). The value is optional
-# # for non-archived sources, and defaults to source:cache:path if omitted.
+# # for non-archived sources, and defaults to source:path if omitted.
# path: path/to/source/layer.shp
#
# # Format of the source layer to limit allowed driver when opening the dataset.
@@ -250,7 +757,7 @@ layers:
# - replace: 0
# with: 1
- 'lansyta':
+ 'lm_topo250.lansyta':
description: Sveriges län (Lantmäteriet)
create:
geometry-type: MULTIPOLYGON
@@ -262,10 +769,12 @@ layers:
subtype: UUID
unique: true
#width: 36
+ nullable: false
comment: Globalt unik identitet för generaliserat objekt
- name: skapad
type: DateTime
tz: local
+ nullable: false
comment: Tidpunkt när objektet ändrades
- name: lanskod
type: Integer
@@ -274,8 +783,7 @@ layers:
nullable: false
comment: Tvåsiffrig kod för län
source:
- # https://www.lantmateriet.se/sv/geodata/vara-produkter/produktlista/topografi-250-nedladdning-vektor/
- cache: administrativindelning_sverige.zip
+ path: administrativindelning_sverige.zip
unar:
format: zip
import:
@@ -287,8 +795,9 @@ layers:
- objektidentitet
- skapad
- lanskod
+ publish: lansyta
- 'kommunyta':
+ 'lm_topo250.kommunyta':
description: Sveriges kommuner (Lantmäteriet)
create:
geometry-type: MULTIPOLYGON
@@ -300,10 +809,12 @@ layers:
subtype: UUID
unique: true
#width: 36
+ nullable: false
comment: Globalt unik identitet för generaliserat objekt
- name: skapad
type: DateTime
tz: local
+ nullable: false
comment: Tidpunkt när objektet ändrades
- name: kommunkod
type: Integer
@@ -312,8 +823,7 @@ layers:
nullable: false
comment: Fyrsiffrig kod för kommun
source:
- # https://www.lantmateriet.se/sv/geodata/vara-produkter/produktlista/topografi-250-nedladdning-vektor/
- cache: administrativindelning_sverige.zip
+ path: administrativindelning_sverige.zip
unar:
format: zip
import:
@@ -325,115 +835,1598 @@ layers:
- objektidentitet
- skapad
- kommunkod
+ publish: kommunyta
- 'nvr:TILLTRADESFORBUD':
+ 'nvr.Tilltradesforbud':
+ # https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/Naturvardsregistret_beskrivning_av_oppna_data.pdf
+ description: Områden med föreskrifter som inskränker rätten att färdas eller vistas i området, permanent eller under en del av året
+ create:
+ geometry-type: MULTIPOLYGON
+ fields:
+ - name: NVRID
+ type: Integer
+ # XXX how come there is no UNIQUE constraint here?
+ unique: false
+ nullable: false
+ comment: Områdets unika ID i naturvårdsregistret
+ - name: BESLSTAT
+ type: String
+ width: 12
+ nullable: false
+ comment: Beslutsstatus
+ - name: FORESKRTYP
+ type: String
+ width: 16
+ nullable: false
+ - name: FORESKRIFT
+ type: String
+ width: 62
+ nullable: false
+ - name: FRANDATUM
+ type: String
+ width: 10
+ nullable: false
+ - name: TILLDATUM
+ type: String
+ width: 10
+ nullable: false
+ - name: BESKRIVN
+ type: String
+ width: 254
+ - name: OBJEKTNAMN
+ type: String
+ width: 254
+ nullable: false
+ - name: FORSKRNAMN
+ type: String
+ width: 254
source:
- download: 'https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/TILLTRADESFORBUD.zip'
- cache: naturvardsregistret/
+ path: nvk/nvr/TILLTRADESFORBUD.zip
+ unar:
+ format: zip
+ patterns:
+ - 'Tilltradesforbud.*'
+ import:
+ path: 'Tilltradesforbud.shp'
+ format: ESRI Shapefile
+ layername: Tilltradesforbud
+ publish: tilltradesforbud
- 'nvr:NP':
+ 'nvr.Nationalpark':
+ # https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/Naturvardsregistret_beskrivning_av_oppna_data.pdf
+ description: Nationalparker
+ create:
+ geometry-type: MULTIPOLYGON
+ fields:
+ - name: NVRID
+ type: Integer
+ unique: true
+ nullable: false
+ comment: Områdets unika ID i naturvårdsregistret
+ - name: NAMN
+ type: String
+ width: 62
+ nullable: false
+ comment: Områdets namn
+ - name: SKYDDSTYP
+ type: String
+ width: 32
+ nullable: false
+ comment: Skyddstyp
+ - name: BESLSTATUS
+ type: String
+ width: 12
+ nullable: false
+ comment: Beslutsstatus
+ - name: URSBESLDAT
+ type: Date
+ nullable: false
+ comment: Ursprungligt beslutsdatum
+ - name: IKRAFTDATF
+ type: Date
+ comment: Ikraftträdandedatum för föreskrifte
+ - name: URSGALLDAT
+ type: Date
+ comment: Ursprungligt gällandedatum
+ - name: SENGALLDAT
+ type: Date
+ comment: Senaste gällandedatum
+ - name: IUCNKAT
+ alias: IUCNkategori
+ type: String
+ width: 254
+ nullable: false
+ comment: Klassificering av skyddade områden enligt internationella naturvårdsunionens
+ - name: FORVALTARE
+ type: String
+ width: 62
+ nullable: false
+ comment: Förvaltare för området
+ - name: LAND_HA
+ # XXX convert to m²?
+ type: Real
+ comment: Areal land i hektar (våtmarker ingår i landarealen)
+ - name: VATTEN_HA
+ # XXX convert to m²?
+ type: Real
+ comment: Areal vatten i hektar (både sötvatten och marint vatten ingår)
+ - name: SKOG_HA
+ # XXX convert to m²?
+ type: Real
+ comment: Skogsmarksareal i hektar
+ - name: GEOSTATUS
+ type: String
+ width: 62
+ nullable: false
+ comment: Hur ytter gränsen för området har mätts in
+ - name: DIARIENR
+ type: String
+ width: 62
+ nullable: true
+ comment: Diarienummer i beslutande myndighets diarium
+ - name: LAGRUM
+ type: String
+ width: 16
+ nullable: false
+ comment: Lagrum som använts som grund för beslutet
+ - name: BESLMYND
+ type: String
+ width: 32
+ nullable: false
+ comment: Beslutsmyndighet
source:
- download: 'https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/NP.zip'
- cache: naturvardsregistret/
+ path: nvk/nvr/NP.zip
+ unar:
+ format: zip
+ patterns:
+ - 'NP/NP_polygon.*'
+ import:
+ path: 'NP/NP_polygon.shp'
+ format: ESRI Shapefile
+ layername: NP_polygon
+ value-map:
+ DIARIENR:
+ - replace: 'xxxxxx'
+ with: null
+ publish: nationalpark
- 'nvr:NR':
+ 'nvr.Naturreservat':
+ # https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/Naturvardsregistret_beskrivning_av_oppna_data.pdf
+ description: Naturreservat
+ create:
+ geometry-type: MULTIPOLYGON
+ fields:
+ - name: NVRID
+ type: Integer
+ # XXX how come there is no UNIQUE constraint here?
+ unique: false
+ nullable: false
+ comment: Områdets unika ID i naturvårdsregistret
+ - name: NAMN
+ type: String
+ width: 128
+ nullable: false
+ comment: Områdets namn
+ - name: SKYDDSTYP
+ type: String
+ width: 32
+ nullable: false
+ comment: Skyddstyp
+ - name: BESLSTATUS
+ type: String
+ width: 12
+ nullable: false
+ comment: Beslutsstatus
+ - name: URSBESLDAT
+ type: Date
+ nullable: true
+ comment: Ursprungligt beslutsdatum
+ - name: IKRAFTDATF
+ type: Date
+ comment: Ikraftträdandedatum för föreskrifte
+ - name: URSGALLDAT
+ type: Date
+ comment: Ursprungligt gällandedatum
+ - name: SENGALLDAT
+ type: Date
+ comment: Senaste gällandedatum
+ - name: IUCNKAT
+ alias: IUCNkategori
+ type: String
+ width: 254
+ nullable: false
+ comment: Klassificering av skyddade områden enligt internationella naturvårdsunionens
+ - name: FORVALTARE
+ type: String
+ width: 62
+ nullable: true
+ comment: Förvaltare för området
+ - name: LAND_HA
+ # XXX convert to m²?
+ type: Real
+ comment: Areal land i hektar (våtmarker ingår i landarealen)
+ - name: VATTEN_HA
+ # XXX convert to m²?
+ type: Real
+ comment: Areal vatten i hektar (både sötvatten och marint vatten ingår)
+ - name: SKOG_HA
+ # XXX convert to m²?
+ type: Real
+ comment: Skogsmarksareal i hektar
+ - name: GEOSTATUS
+ type: String
+ width: 62
+ nullable: false
+ comment: Hur ytter gränsen för området har mätts in
+ - name: DIARIENR
+ type: String
+ width: 62
+ nullable: true
+ comment: Diarienummer i beslutande myndighets diarium
+ - name: LAGRUM
+ type: String
+ width: 16
+ comment: Lagrum som använts som grund för beslutet
+ - name: BESLMYND
+ type: String
+ width: 32
+ nullable: false
+ comment: Beslutsmyndighet
source:
- download: 'https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/NR.zip'
- cache: naturvardsregistret/
+ path: nvk/nvr/NR.zip
+ unar:
+ format: zip
+ patterns:
+ - 'NR/NR_polygon.*'
+ import:
+ path: 'NR/NR_polygon.shp'
+ format: ESRI Shapefile
+ layername: NR_polygon
+ value-map:
+ DIARIENR:
+ - replace: 'xxxxxx'
+ with: null
+ publish:
+ naturreservat:
+ where: |
+ "BESLMYND" IS NULL OR "BESLMYND" != 'Kommun'
+ naturreservat_kommunalt:
+ where: |
+ "BESLMYND" = 'Kommun'
- 'nvr:NVO':
+ 'nvr.Naturvardsomrade':
+ # https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/Naturvardsregistret_beskrivning_av_oppna_data.pdf
+ description: Naturvårdsområden
+ create:
+ geometry-type: MULTIPOLYGON
+ fields:
+ - name: NVRID
+ type: Integer
+ unique: true
+ nullable: false
+ comment: Områdets unika ID i naturvårdsregistret
+ - name: NAMN
+ type: String
+ width: 64
+ nullable: false
+ comment: Områdets namn
+ - name: SKYDDSTYP
+ type: String
+ width: 32
+ nullable: false
+ comment: Skyddstyp
+ - name: BESLSTATUS
+ type: String
+ width: 12
+ nullable: false
+ comment: Beslutsstatus
+ - name: URSBESLDAT
+ type: Date
+ nullable: false
+ comment: Ursprungligt beslutsdatum
+ - name: IKRAFTDATF
+ type: Date
+ comment: Ikraftträdandedatum för föreskrifte
+ - name: URSGALLDAT
+ type: Date
+ comment: Ursprungligt gällandedatum
+ - name: SENGALLDAT
+ type: Date
+ comment: Senaste gällandedatum
+ - name: IUCNKAT
+ alias: IUCNkategori
+ type: String
+ width: 254
+ nullable: false
+ comment: Klassificering av skyddade områden enligt internationella naturvårdsunionens
+ - name: FORVALTARE
+ type: String
+ width: 62
+ nullable: false
+ comment: Förvaltare för området
+ - name: LAND_HA
+ # XXX convert to m²?
+ type: Real
+ comment: Areal land i hektar (våtmarker ingår i landarealen)
+ - name: VATTEN_HA
+ # XXX convert to m²?
+ type: Real
+ comment: Areal vatten i hektar (både sötvatten och marint vatten ingår)
+ - name: SKOG_HA
+ # XXX convert to m²?
+ type: Real
+ comment: Skogsmarksareal i hektar
+ - name: GEOSTATUS
+ type: String
+ width: 62
+ nullable: false
+ comment: Hur ytter gränsen för området har mätts in
+ - name: DIARIENR
+ type: String
+ width: 62
+ nullable: true
+ comment: Diarienummer i beslutande myndighets diarium
+ - name: LAGRUM
+ type: String
+ width: 16
+ nullable: false
+ comment: Lagrum som använts som grund för beslutet
+ - name: BESLMYND
+ type: String
+ width: 32
+ nullable: false
+ comment: Beslutsmyndighet
source:
- download: 'https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/NVO.zip'
- cache: naturvardsregistret/
+ path: nvk/nvr/NVO.zip
+ unar:
+ format: zip
+ patterns:
+ - 'NVO/NVO_polygon.*'
+ import:
+ path: 'NVO/NVO_polygon.shp'
+ format: ESRI Shapefile
+ layername: NVO_polygon
+ value-map:
+ DIARIENR:
+ - replace: 'xxxxxx'
+ with: null
+ publish: naturvardsomrade
- 'nvr:DVO':
+ 'nvr.Djur_och_vaxtskyddsomrade':
+ # https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/Naturvardsregistret_beskrivning_av_oppna_data.pdf
+ description: Djur- och växtskyddsområden
+ create:
+ geometry-type: MULTIPOLYGON
+ fields:
+ - name: NVRID
+ type: Integer
+ # XXX how come there is no UNIQUE constraint here?
+ unique: false
+ nullable: false
+ comment: Områdets unika ID i naturvårdsregistret
+ - name: NAMN
+ type: String
+ width: 254
+ nullable: false
+ comment: Områdets namn
+ - name: SKYDDSTYP
+ type: String
+ width: 32
+ nullable: false
+ comment: Skyddstyp
+ - name: BESLSTATUS
+ type: String
+ width: 12
+ nullable: false
+ comment: Beslutsstatus
+ - name: URSBESLDAT
+ type: Date
+ nullable: false
+ comment: Ursprungligt beslutsdatum
+ - name: IKRAFTDATF
+ type: Date
+ comment: Ikraftträdandedatum för föreskrifte
+ - name: URSGALLDAT
+ type: Date
+ comment: Ursprungligt gällandedatum
+ - name: SENGALLDAT
+ type: Date
+ comment: Senaste gällandedatum
+ - name: IUCNKAT
+ alias: IUCNkategori
+ type: String
+ width: 254
+ nullable: false
+ comment: Klassificering av skyddade områden enligt internationella naturvårdsunionens
+ - name: FORVALTARE
+ type: String
+ width: 62
+ nullable: false
+ comment: Förvaltare för området
+ - name: LAND_HA
+ # XXX convert to m²?
+ type: Real
+ comment: Areal land i hektar (våtmarker ingår i landarealen)
+ - name: VATTEN_HA
+ # XXX convert to m²?
+ type: Real
+ comment: Areal vatten i hektar (både sötvatten och marint vatten ingår)
+ - name: SKOG_HA
+ # XXX convert to m²?
+ type: Real
+ comment: Skogsmarksareal i hektar
+ - name: GEOSTATUS
+ type: String
+ width: 62
+ nullable: false
+ comment: Hur ytter gränsen för området har mätts in
+ - name: DIARIENR
+ type: String
+ width: 62
+ nullable: true
+ comment: Diarienummer i beslutande myndighets diarium
+ - name: LAGRUM
+ type: String
+ width: 62
+ nullable: false
+ comment: Lagrum som använts som grund för beslutet
+ - name: BESLMYND
+ type: String
+ width: 32
+ nullable: false
+ comment: Beslutsmyndighet
source:
- download: 'https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/DVO.zip'
- cache: naturvardsregistret/
+ path: nvk/nvr/DVO.zip
+ unar:
+ format: zip
+ patterns:
+ - 'DVO/DVO_polygon.*'
+ import:
+ path: 'DVO/DVO_polygon.shp'
+ format: ESRI Shapefile
+ layername: DVO_polygon
+ value-map:
+ DIARIENR:
+ - replace: 'xxxxxx'
+ with: null
+ publish: djur_och_vaxtskyddsomrade
- 'nvr:KR':
+ 'nvr.Kultureservat':
+ # https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/Naturvardsregistret_beskrivning_av_oppna_data.pdf
+ description: Kulturreservat
+ create:
+ geometry-type: MULTIPOLYGON
+ fields:
+ - name: NVRID
+ type: Integer
+ unique: true
+ nullable: false
+ comment: Områdets unika ID i naturvårdsregistret
+ - name: NAMN
+ type: String
+ width: 62
+ nullable: false
+ comment: Områdets namn
+ - name: SKYDDSTYP
+ type: String
+ width: 32
+ nullable: false
+ comment: Skyddstyp
+ - name: BESLSTATUS
+ type: String
+ width: 12
+ nullable: false
+ comment: Beslutsstatus
+ - name: URSBESLDAT
+ type: Date
+ nullable: false
+ comment: Ursprungligt beslutsdatum
+ - name: IKRAFTDATF
+ type: Date
+ comment: Ikraftträdandedatum för föreskrifte
+ - name: URSGALLDAT
+ type: Date
+ comment: Ursprungligt gällandedatum
+ - name: SENGALLDAT
+ type: Date
+ comment: Senaste gällandedatum
+ - name: IUCNKAT
+ alias: IUCNkategori
+ type: String
+ width: 254
+ nullable: false
+ comment: Klassificering av skyddade områden enligt internationella naturvårdsunionens
+ - name: FORVALTARE
+ type: String
+ width: 62
+ nullable: false
+ comment: Förvaltare för området
+ - name: LAND_HA
+ # XXX convert to m²?
+ type: Real
+ comment: Areal land i hektar (våtmarker ingår i landarealen)
+ - name: VATTEN_HA
+ # XXX convert to m²?
+ type: Real
+ comment: Areal vatten i hektar (både sötvatten och marint vatten ingår)
+ - name: SKOG_HA
+ # XXX convert to m²?
+ type: Real
+ comment: Skogsmarksareal i hektar
+ - name: GEOSTATUS
+ type: String
+ width: 62
+ nullable: false
+ comment: Hur ytter gränsen för området har mätts in
+ - name: DIARIENR
+ type: String
+ width: 62
+ nullable: true
+ comment: Diarienummer i beslutande myndighets diarium
+ - name: LAGRUM
+ type: String
+ width: 16
+ nullable: false
+ comment: Lagrum som använts som grund för beslutet
+ - name: BESLMYND
+ type: String
+ width: 32
+ nullable: false
+ comment: Beslutsmyndighet
source:
- download: 'https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/KR.zip'
- cache: naturvardsregistret/
+ path: nvk/nvr/KR.zip
+ unar:
+ format: zip
+ patterns:
+ - 'KR/KR_polygon.*'
+ import:
+ path: 'KR/KR_polygon.shp'
+ format: ESRI Shapefile
+ layername: KR_polygon
+ value-map:
+ DIARIENR:
+ - replace: 'xxxxxx'
+ with: null
+ publish: kulturreservat
- 'nvr:VSO':
+ 'nvr.Vattenskyddsomrade':
+ # https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/Naturvardsregistret_beskrivning_av_oppna_data.pdf
+ description: Vattenskyddsområden
+ create:
+ geometry-type: MULTIPOLYGON
+ fields:
+ - name: NVRID
+ type: Integer
+ # XXX how come there is no UNIQUE constraint here?
+ unique: false
+ nullable: false
+ comment: Områdets unika ID i naturvårdsregistret
+ - name: NAMN
+ type: String
+ width: 254
+ nullable: false
+ comment: Områdets namn
+ - name: SKYDDSTYP
+ type: String
+ width: 32
+ nullable: false
+ comment: Skyddstyp
+ - name: BESLSTATUS
+ type: String
+ width: 12
+ nullable: false
+ comment: Beslutsstatus
+ - name: URSBESLDAT
+ type: Date
+ nullable: false
+ comment: Ursprungligt beslutsdatum
+ - name: IKRAFTDATF
+ type: Date
+ comment: Ikraftträdandedatum för föreskrifte
+ - name: URSGALLDAT
+ type: Date
+ comment: Ursprungligt gällandedatum
+ - name: SENGALLDAT
+ type: Date
+ comment: Senaste gällandedatum
+ - name: TILLSYNSMH
+ type: String
+ width: 64
+ nullable: false
+ comment: Tillsynsmyndighet
+ - name: PROVNMHDIS
+ type: String
+ width: 64
+ comment: Prövningsmyndighet för dispens
+ - name: PROVNMHTIL
+ type: String
+ width: 64
+ comment: Prövningsmyndighet för tillstånd
+ - name: IUCNKAT
+ alias: IUCNkategori
+ type: String
+ width: 254
+ nullable: false
+ comment: Klassificering av skyddade områden enligt internationella naturvårdsunionens
+ - name: LAND_HA
+ # XXX convert to m²?
+ type: Real
+ comment: Areal land i hektar (våtmarker ingår i landarealen)
+ - name: VATTEN_HA
+ # XXX convert to m²?
+ type: Real
+ comment: Areal vatten i hektar (både sötvatten och marint vatten ingår)
+ - name: SKOG_HA
+ # XXX convert to m²?
+ type: Real
+ comment: Skogsmarksareal i hektar
+ - name: GEOSTATUS
+ type: String
+ width: 62
+ nullable: false
+ comment: Hur ytter gränsen för området har mätts in
+ - name: DIARIENR
+ type: String
+ width: 62
+ nullable: true
+ comment: Diarienummer i beslutande myndighets diarium
+ - name: LAGRUM
+ type: String
+ width: 16
+ comment: Lagrum som använts som grund för beslutet
+ - name: BESLMYND
+ type: String
+ width: 32
+ nullable: false
+ comment: Beslutsmyndighet
source:
- download: 'https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/VSO.zip'
- cache: naturvardsregistret/
+ path: nvk/nvr/VSO.zip
+ unar:
+ format: zip
+ patterns:
+ - 'VSO/VSO_polygon.*'
+ import:
+ path: 'VSO/VSO_polygon.shp'
+ format: ESRI Shapefile
+ layername: VSO_polygon
+ value-map:
+ DIARIENR:
+ - replace: 'xxxxxx'
+ with: null
+ publish: vattenskyddsomrade
- 'nvr:LBSO':
+ 'nvr.Landskapsbildsskyddsomrade':
+ # https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/Naturvardsregistret_beskrivning_av_oppna_data.pdf
+ description: Landskapsbildsskyddsområden
+ create:
+ geometry-type: MULTIPOLYGON
+ fields:
+ - name: NVRID
+ type: Integer
+ unique: true
+ nullable: false
+ comment: Områdets unika ID i naturvårdsregistret
+ - name: NAMN
+ type: String
+ width: 62
+ nullable: false
+ comment: Områdets namn
+ - name: SKYDDSTYP
+ type: String
+ width: 32
+ nullable: false
+ comment: Skyddstyp
+ - name: BESLSTATUS
+ type: String
+ width: 12
+ nullable: false
+ comment: Beslutsstatus
+ - name: URSBESLDAT
+ type: Date
+ nullable: false
+ comment: Ursprungligt beslutsdatum
+ - name: IKRAFTDATF
+ type: Date
+ comment: Ikraftträdandedatum för föreskrifte
+ - name: URSGALLDAT
+ type: Date
+ comment: Ursprungligt gällandedatum
+ - name: SENGALLDAT
+ type: Date
+ comment: Senaste gällandedatum
+ - name: IUCNKAT
+ alias: IUCNkategori
+ type: String
+ width: 254
+ nullable: false
+ comment: Klassificering av skyddade områden enligt internationella naturvårdsunionens
+ - name: FORVALTARE
+ type: String
+ width: 62
+ nullable: false
+ comment: Förvaltare för området
+ - name: LAND_HA
+ # XXX convert to m²?
+ type: Real
+ comment: Areal land i hektar (våtmarker ingår i landarealen)
+ - name: VATTEN_HA
+ # XXX convert to m²?
+ type: Real
+ comment: Areal vatten i hektar (både sötvatten och marint vatten ingår)
+ - name: SKOG_HA
+ # XXX convert to m²?
+ type: Real
+ comment: Skogsmarksareal i hektar
+ - name: GEOSTATUS
+ type: String
+ width: 62
+ nullable: false
+ comment: Hur ytter gränsen för området har mätts in
+ - name: DIARIENR
+ type: String
+ width: 62
+ nullable: true
+ comment: Diarienummer i beslutande myndighets diarium
+ - name: LAGRUM
+ type: String
+ width: 16
+ comment: Lagrum som använts som grund för beslutet
+ - name: BESLMYND
+ type: String
+ width: 32
+ nullable: false
+ comment: Beslutsmyndighet
source:
- download: 'https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/LBSO.zip'
- cache: naturvardsregistret/
+ path: nvk/nvr/LBSO.zip
+ unar:
+ format: zip
+ patterns:
+ - 'LBSO/LBSO_polygon.*'
+ import:
+ path: 'LBSO/LBSO_polygon.shp'
+ format: ESRI Shapefile
+ layername: LBSO_polygon
+ value-map:
+ DIARIENR:
+ - replace: 'xxxxxx'
+ with: null
+ publish: landskapsbildsskyddsomrade
- 'nvr:OBO':
+ 'nvr.Biotopskydd':
+ # https://www.skogsstyrelsen.se/globalassets/sjalvservice/karttjanster/geodatatjanster/produktbeskrivningar/biotopskydd---produktbeskrivning.pdf
+ description: Biotopskydd i skogsmark (beslutade av Skogsstyrelsen)
+ create:
+ geometry-type: MULTIPOLYGON
+ fields:
+ - name: Uuid
+ type: String
+ subtype: UUID
+ #width: 36
+ unique: true
+ nullable: false
+ comment: Unik identitet
+ - name: Beteckn
+ type: String
+ width: 12
+ unique: true
+ nullable: false
+ comment: Ärendebeteckning
+ - name: ArendeAr
+ type: Integer
+ subtype: Int16
+ nullable: false
+ comment: År anmälan/ansökan registrerades
+ - name: Biotyp
+ type: String
+ width: 254
+ nullable: false
+ comment: Biotoptyp
+ - name: Naturtyp
+ type: String
+ width: 254
+ - name: AreaTot
+ type: Real
+ - name: AreaProd
+ type: Real
+ - name: Standort
+ type: String
+ width: 254
+ comment: Ståndortsindex
+ - name: Datbeslut
+ type: Date
+ comment: Datum för beslut
+ - name: Url
+ type: String
+ width: 254
+ comment: Länk till visningsformulär i Skogens Pärlor
source:
- download: 'https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/OBO.zip'
- cache: naturvardsregistret/
+ path: sks/sksBiotopskydd_gpkg.zip
+ unar:
+ format: zip
+ import:
+ path: sksBiotopskydd.gpkg
+ format: GPKG
+ layername: BiotopskyddYta
+ value-map:
+ Standort:
+ - replace: 'saknas'
+ with: null
+ publish: skogligt_biotopskyddsomrade
- 'nvr:NM':
+ 'nvr.Ovrigt_biotopskyddsomrade':
+ # https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/Naturvardsregistret_beskrivning_av_oppna_data.pdf
+ description: Biotopskydd utanför skogsmark
+ create:
+ geometry-type: MULTIPOLYGON
+ fields:
+ - name: NVRID
+ type: Integer
+ unique: true
+ nullable: false
+ comment: Områdets unika ID i naturvårdsregistret
+ - name: NAMN
+ type: String
+ width: 62
+ nullable: false
+ comment: Områdets namn
+ - name: SKYDDSTYP
+ type: String
+ width: 32
+ nullable: false
+ comment: Skyddstyp
+ - name: BESLSTATUS
+ type: String
+ width: 12
+ nullable: false
+ comment: Beslutsstatus
+ - name: URSBESLDAT
+ type: Date
+ nullable: false
+ comment: Ursprungligt beslutsdatum
+ - name: IKRAFTDATF
+ type: Date
+ comment: Ikraftträdandedatum för föreskrifte
+ - name: URSGALLDAT
+ type: Date
+ comment: Ursprungligt gällandedatum
+ - name: SENGALLDAT
+ type: Date
+ comment: Senaste gällandedatum
+ - name: IUCNKAT
+ alias: IUCNkategori
+ type: String
+ width: 254
+ nullable: false
+ comment: Klassificering av skyddade områden enligt internationella naturvårdsunionens
+ - name: FORVALTARE
+ type: String
+ width: 62
+ nullable: false
+ comment: Förvaltare för området
+ - name: LAND_HA
+ # XXX convert to m²?
+ type: Real
+ comment: Areal land i hektar (våtmarker ingår i landarealen)
+ - name: VATTEN_HA
+ # XXX convert to m²?
+ type: Real
+ comment: Areal vatten i hektar (både sötvatten och marint vatten ingår)
+ - name: SKOG_HA
+ # XXX convert to m²?
+ type: Real
+ comment: Skogsmarksareal i hektar
+ - name: GEOSTATUS
+ type: String
+ width: 62
+ nullable: false
+ comment: Hur ytter gränsen för området har mätts in
+ - name: DIARIENR
+ type: String
+ width: 62
+ nullable: true
+ comment: Diarienummer i beslutande myndighets diarium
+ - name: LAGRUM
+ type: String
+ width: 16
+ nullable: false
+ comment: Lagrum som använts som grund för beslutet
+ - name: BESLMYND
+ type: String
+ width: 32
+ nullable: false
+ comment: Beslutsmyndighet
source:
- download: 'https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/NM.zip'
- cache: naturvardsregistret/
+ path: nvk/nvr/OBO.zip
+ unar:
+ format: zip
+ patterns:
+ - 'OBO/OBO_polygon.*'
+ import:
+ path: 'OBO/OBO_polygon.shp'
+ format: ESRI Shapefile
+ layername: OBO_polygon
+ value-map:
+ DIARIENR:
+ - replace: 'xxxxxx'
+ with: null
+ publish: ovrigt_biotopskyddsomrade
- 'nvr:IF':
+ 'nvr.Naturminne_punkt':
+ # https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/Naturvardsregistret_beskrivning_av_oppna_data.pdf
+ description: Naturminne, punkt
+ create:
+ geometry-type: MULTIPOINT
+ fields:
+ - name: NVRID
+ type: Integer
+ unique: true
+ nullable: false
+ comment: Områdets unika ID i naturvårdsregistret
+ - name: NAMN
+ type: String
+ width: 62
+ nullable: false
+ comment: Områdets namn
+ - name: SKYDDSTYP
+ type: String
+ width: 32
+ nullable: false
+ comment: Skyddstyp
+ - name: BESLSTATUS
+ type: String
+ width: 12
+ nullable: false
+ comment: Beslutsstatus
+ - name: URSBESLDAT
+ type: Date
+ nullable: false
+ comment: Ursprungligt beslutsdatum
+ - name: IKRAFTDATF
+ type: Date
+ comment: Ikraftträdandedatum för föreskrifte
+ - name: URSGALLDAT
+ type: Date
+ comment: Ursprungligt gällandedatum
+ - name: SENGALLDAT
+ type: Date
+ comment: Senaste gällandedatum
+ - name: IUCNKAT
+ alias: IUCNkategori
+ type: String
+ width: 254
+ nullable: false
+ comment: Klassificering av skyddade områden enligt internationella naturvårdsunionens
+ - name: FORVALTARE
+ type: String
+ width: 62
+ nullable: false
+ comment: Förvaltare för området
+ - name: GEOSTATUS
+ type: String
+ width: 62
+ nullable: false
+ comment: Hur ytter gränsen för området har mätts in
+ - name: DIARIENR
+ type: String
+ width: 62
+ nullable: true
+ comment: Diarienummer i beslutande myndighets diarium
+ - name: LAGRUM
+ type: String
+ width: 64
+ nullable: false
+ comment: Lagrum som använts som grund för beslutet
+ - name: BESLMYND
+ type: String
+ width: 32
+ nullable: false
+ comment: Beslutsmyndighet
source:
- download: 'https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/IF.zip'
- cache: naturvardsregistret/
+ path: nvk/nvr/NM.zip
+ unar:
+ format: zip
+ patterns:
+ - 'NM/NM_point.*'
+ import:
+ path: 'NM/NM_point.shp'
+ format: ESRI Shapefile
+ layername: NM_point
+ publish:
+ naturminne_punkt:
+ minzoom: 4
- 'nvr:SPA_Rikstackande':
+ 'nvr.Naturminne_yta':
+ # https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/Naturvardsregistret_beskrivning_av_oppna_data.pdf
+ description: Naturminne, yta
+ create:
+ geometry-type: MULTIPOLYGON
+ fields:
+ - name: NVRID
+ type: Integer
+ unique: true
+ nullable: false
+ comment: Områdets unika ID i naturvårdsregistret
+ - name: NAMN
+ type: String
+ width: 62
+ nullable: false
+ comment: Områdets namn
+ - name: SKYDDSTYP
+ type: String
+ width: 32
+ nullable: false
+ comment: Skyddstyp
+ - name: BESLSTATUS
+ type: String
+ width: 12
+ nullable: false
+ comment: Beslutsstatus
+ - name: URSBESLDAT
+ type: Date
+ nullable: false
+ comment: Ursprungligt beslutsdatum
+ - name: IKRAFTDATF
+ type: Date
+ comment: Ikraftträdandedatum för föreskrifte
+ - name: URSGALLDAT
+ type: Date
+ comment: Ursprungligt gällandedatum
+ - name: SENGALLDAT
+ type: Date
+ comment: Senaste gällandedatum
+ - name: IUCNKAT
+ alias: IUCNkategori
+ type: String
+ width: 254
+ nullable: false
+ comment: Klassificering av skyddade områden enligt internationella naturvårdsunionens
+ - name: FORVALTARE
+ type: String
+ width: 62
+ nullable: false
+ comment: Förvaltare för området
+ - name: LAND_HA
+ # XXX convert to m²?
+ type: Real
+ comment: Areal land i hektar (våtmarker ingår i landarealen)
+ - name: VATTEN_HA
+ # XXX convert to m²?
+ type: Real
+ comment: Areal vatten i hektar (både sötvatten och marint vatten ingår)
+ - name: SKOG_HA
+ # XXX convert to m²?
+ type: Real
+ comment: Skogsmarksareal i hektar
+ - name: GEOSTATUS
+ type: String
+ width: 62
+ nullable: false
+ comment: Hur ytter gränsen för området har mätts in
+ - name: DIARIENR
+ type: String
+ width: 62
+ nullable: true
+ comment: Diarienummer i beslutande myndighets diarium
+ - name: LAGRUM
+ type: String
+ width: 64
+ nullable: false
+ comment: Lagrum som använts som grund för beslutet
+ - name: BESLMYND
+ type: String
+ width: 32
+ nullable: false
+ comment: Beslutsmyndighet
source:
- download: 'https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/SPA_Rikstackande.zip'
- cache: naturvardsregistret/
+ path: nvk/nvr/NM.zip
+ unar:
+ format: zip
+ patterns:
+ - 'NM/NM_polygon.*'
+ import:
+ path: 'NM/NM_polygon.shp'
+ format: ESRI Shapefile
+ layername: NM_polygon
+ value-map:
+ DIARIENR:
+ - replace: 'xxxxxx'
+ with: null
+ publish: naturminne_yta
- 'nvr:SCI_Rikstackande':
+ 'nvr.Interimistiskt_forbud':
+ # https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/Naturvardsregistret_beskrivning_av_oppna_data.pdf
+ description: Interimistiska förbud
+ create:
+ geometry-type: MULTIPOLYGON
+ fields:
+ - name: NVRID
+ type: Integer
+ unique: true
+ nullable: false
+ comment: Områdets unika ID i naturvårdsregistret
+ - name: NAMN
+ type: String
+ width: 62
+ nullable: false
+ comment: Områdets namn
+ - name: SKYDDSTYP
+ type: String
+ width: 32
+ nullable: false
+ comment: Skyddstyp
+ - name: BESLSTATUS
+ type: String
+ width: 12
+ nullable: false
+ comment: Beslutsstatus
+ - name: URSBESLDAT
+ type: Date
+ nullable: false
+ comment: Ursprungligt beslutsdatum
+ - name: IKRAFTDATF
+ type: Date
+ comment: Ikraftträdandedatum för föreskrifte
+ - name: URSGALLDAT
+ type: Date
+ comment: Ursprungligt gällandedatum
+ - name: SENGALLDAT
+ type: Date
+ comment: Senaste gällandedatum
+ - name: IUCNKAT
+ alias: IUCNkategori
+ type: String
+ width: 254
+ nullable: false
+ comment: Klassificering av skyddade områden enligt internationella naturvårdsunionens
+ - name: FORVALTARE
+ type: String
+ width: 62
+ comment: Förvaltare för området
+ - name: LAND_HA
+ # XXX convert to m²?
+ type: Real
+ comment: Areal land i hektar (våtmarker ingår i landarealen)
+ - name: VATTEN_HA
+ # XXX convert to m²?
+ type: Real
+ comment: Areal vatten i hektar (både sötvatten och marint vatten ingår)
+ - name: SKOG_HA
+ # XXX convert to m²?
+ type: Real
+ comment: Skogsmarksareal i hektar
+ - name: GEOSTATUS
+ type: String
+ width: 62
+ nullable: false
+ comment: Hur ytter gränsen för området har mätts in
+ - name: DIARIENR
+ type: String
+ width: 62
+ nullable: true
+ comment: Diarienummer i beslutande myndighets diarium
+ - name: LAGRUM
+ type: String
+ width: 16
+ nullable: false
+ comment: Lagrum som använts som grund för beslutet
+ - name: BESLMYND
+ type: String
+ width: 32
+ nullable: false
+ comment: Beslutsmyndighet
source:
- download:
- url: 'https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/SCI_Rikstackande.zip'
- max-size: 134217728 # 128MiB
- cache: naturvardsregistret/
+ path: nvk/nvr/IF.zip
+ unar:
+ format: zip
+ patterns:
+ - 'IF/IF_polygon.*'
+ import:
+ path: 'IF/IF_polygon.shp'
+ format: ESRI Shapefile
+ layername: IF_polygon
+ value-map:
+ DIARIENR:
+ - replace: 'xxxxxx'
+ with: null
+ publish: interimistiskt_forbud
- 'nvr:HELCOM':
+ 'nvr.SPA_Rikstackande':
+ # https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/Naturvardsregistret_beskrivning_av_oppna_data.pdf
+ description: Fågeldirektivet (SPA, direktiv 79/409/EEG)
+ create:
+ geometry-type: MULTIPOLYGONZ
+ fields:
+ - name: NAMN
+ type: String
+ width: 62
+ unique: true
+ nullable: false
+ comment: Områdets namn
+ - name: BEVPLAN
+ type: String
+ width: 128
+ nullable: false
+ - name: SITE_CODE
+ type: String
+ width: 9
+ unique: true
+ nullable: false
+ - name: OMRADESTYP
+ type: String
+ width: 16
+ nullable: false
+ - name: UPPLAMNARE
+ type: String
+ width: 62
+ nullable: false
+ - name: SCI_FORSL
+ type: String
+ width: 6
+ - name: SCI_DATUM
+ type: String
+ width: 6
+ - name: SAC_DATUM
+ type: String
+ width: 6
+ - name: SPA_DATUM
+ type: String
+ width: 6
+ nullable: false
+ - name: KVALITET
+ type: String
+ width: 254
+ nullable: false
+ - name: KARAKTAR
+ type: String
+ width: 254
+ nullable: false
+ - name: ARTER
+ type: String
+ width: 254
+ nullable: false
+ - name: NATURTYPER
+ type: String
+ width: 254
source:
- download: 'https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/HELCOM.zip'
- cache: naturvardsregistret/
+ path: nvk/nvr/SPA_Rikstackande.zip
+ unar:
+ format: zip
+ patterns:
+ - 'SPA_Rikstackande/SPA_rikstackande.*'
+ import:
+ path: 'SPA_Rikstackande/SPA_rikstackande.shp'
+ format: ESRI Shapefile
+ layername: SPA_rikstackande
+ publish: fageldirektivet
- 'nvr:Ramsar_2018':
+ 'nvr.SCI_Rikstackande':
+ # https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/Naturvardsregistret_beskrivning_av_oppna_data.pdf
+ description: Habitatdirektivet (SCI, direktiv 92/43/EEG)
+ create:
+ geometry-type: MULTIPOLYGONZ
+ fields:
+ - name: NAMN
+ type: String
+ width: 62
+ # XXX how come there is no UNIQUE constraint here?
+ unique: false
+ nullable: false
+ comment: Områdets namn
+ - name: BEVPLAN
+ type: String
+ width: 128
+ nullable: false
+ - name: SITE_CODE
+ type: String
+ width: 9
+ unique: true
+ nullable: false
+ - name: OMRADESTYP
+ type: String
+ width: 16
+ nullable: false
+ - name: UPPLAMNARE
+ type: String
+ width: 62
+ nullable: false
+ - name: SCI_FORSL
+ type: String
+ width: 6
+ nullable: false
+ - name: SCI_DATUM
+ type: String
+ width: 6
+ - name: SAC_DATUM
+ type: String
+ width: 6
+ - name: SPA_DATUM
+ type: String
+ width: 6
+ - name: KVALITET
+ type: String
+ width: 254
+ nullable: false
+ - name: KARAKTAR
+ type: String
+ width: 254
+ nullable: false
+ - name: ARTER
+ type: String
+ width: 254
+ - name: NATURTYPER
+ type: String
+ width: 254
+ sources:
+ - source:
+ path: nvk/nvr/SCI_Rikstackande.zip
+ unar:
+ format: zip
+ patterns:
+ - 'SCI_Rikstackande/SCI_alvar_AC_lan/SCI_alvar_AC_lan.*'
+ import:
+ path: 'SCI_Rikstackande/SCI_alvar_AC_lan/SCI_alvar_AC_lan.shp'
+ format: ESRI Shapefile
+ layername: SCI_alvar_AC_lan
+ - source:
+ path: nvk/nvr/SCI_Rikstackande.zip
+ unar:
+ format: zip
+ patterns:
+ - 'SCI_Rikstackande/SCI_alvar_BD_lan/SCI_alvar_BD_lan.*'
+ import:
+ path: 'SCI_Rikstackande/SCI_alvar_BD_lan/SCI_alvar_BD_lan.shp'
+ format: ESRI Shapefile
+ layername: SCI_alvar_BD_lan
+ - source:
+ path: nvk/nvr/SCI_Rikstackande.zip
+ unar:
+ format: zip
+ patterns:
+ - 'SCI_Rikstackande/SCI_ej_alvar_rikstackande/SCI_ej_alvar_rikstackande.*'
+ import:
+ path: 'SCI_Rikstackande/SCI_ej_alvar_rikstackande/SCI_ej_alvar_rikstackande.shp'
+ format: ESRI Shapefile
+ layername: SCI_ej_alvar_rikstackande
+ publish: habitatdirektivet
+
+ 'nvr.HELCOM':
+ # https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/Naturvardsregistret_beskrivning_av_oppna_data.pdf
+ description: Marina skyddade områden (Helcom MPA)
+ create:
+ geometry-type: MULTIPOLYGONZ
+ fields:
+ - name: BSPA_ID
+ type: Integer
+ unique: true
+ nullable: false
+ - name: NAME
+ type: String
+ width: 62
+ nullable: false
source:
- download: 'https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/Ramsar_2018.zip'
- cache: naturvardsregistret/
+ path: nvk/nvr/HELCOM.zip
+ unar:
+ format: zip
+ patterns:
+ - 'PS_HELCOM/PS_HELCOM.*'
+ import:
+ path: 'PS_HELCOM/PS_HELCOM.shp'
+ format: ESRI Shapefile
+ layername: PS_HELCOM
+ publish: helcom
- 'nvr:OSPAR':
+ 'nvr.Ramsar':
+ # https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/Naturvardsregistret_beskrivning_av_oppna_data.pdf
+ description: Ramsar-områden (Våtmarkskonventionen)
+ create:
+ geometry-type: MULTIPOLYGON
+ fields:
+ - name: RAMSAR_ID
+ type: Integer
+ unique: true
+ nullable: false
+ - name: SKYDDSTYP
+ type: String
+ width: 32
+ nullable: false
+ comment: Skyddstyp
+ - name: NATION
+ type: String
+ width: 32
+ nullable: false
+ - name: NAMN
+ type: String
+ width: 32
+ unique: true
+ nullable: false
+ - name: LAND_HA
+ # XXX convert to m²?
+ type: Real
+ comment: Areal land i hektar (våtmarker ingår i landarealen)
+ - name: VATTEN_HA
+ # XXX convert to m²?
+ type: Real
+ comment: Areal vatten i hektar (både sötvatten och marint vatten ingår)
+ - name: SKOG_HA
+ # XXX convert to m²?
+ type: Real
+ comment: Skogsmarksareal i hektar
+ - name: LINK
+ type: String
+ width: 254
+ nullable: false
+ - name: URSPR_BESL
+ type: Date
+ nullable: false
+ - name: SEN_BESLUT
+ type: Date
+ - name: LEGAL_ACT
+ type: String
+ width: 254
+ nullable: false
source:
- download: 'https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/OSPAR.zip'
- cache: naturvardsregistret/
+ path: nvk/nvr/Ramsar_2018.zip
+ unar:
+ format: zip
+ patterns:
+ - 'RAMSAR.*'
+ import:
+ path: 'RAMSAR.shp'
+ format: ESRI Shapefile
+ layername: RAMSAR
+ publish: ramsar
- 'nvr:Varldsarv':
+ 'nvr.OSPAR':
+ # https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/Naturvardsregistret_beskrivning_av_oppna_data.pdf
+ description: Marina skyddade områden (Ospar MPA)
+ create:
+ geometry-type: MULTIPOLYGONZ
+ fields:
+ - name: ORIGIN
+ type: String
+ width: 10
+ nullable: false
+ - name: NAMN_N2000
+ type: String
+ width: 64
+ unique: true
+ nullable: false
+ - name: MPA_ID
+ type: String
+ width: 16
+ unique: true
+ nullable: false
+ - name: MPA_NAMN
+ type: String
+ width: 64
+ unique: true
+ nullable: false
+ - name: N2000_SITE
+ type: String
+ width: 16
+ unique: true
+ nullable: false
source:
- download: 'https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/Varldsarv.zip'
- cache: naturvardsregistret/
+ path: nvk/nvr/OSPAR.zip
+ unar:
+ format: zip
+ patterns:
+ - 'PS_OSPAR/PS_OSPAR.*'
+ import:
+ path: 'PS_OSPAR/PS_OSPAR.shp'
+ format: ESRI Shapefile
+ layername: PS_OSPAR
+ publish: ospar
- 'nvr:biosfarsomraden':
+ 'nvr.Varldsarv':
+ # https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/Naturvardsregistret_beskrivning_av_oppna_data.pdf
+ description: Världsarv med mycket höga naturvärden (UNESCO)
+ create:
+ geometry-type: MULTIPOLYGON
+ fields:
+ - name: NAMN
+ type: String
+ width: 64
+ unique: true
+ nullable: false
source:
- download: 'https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/biosfarsomraden.zip'
- cache: naturvardsregistret/
+ path: nvk/nvr/Varldsarv.zip
+ unar:
+ format: zip
+ patterns:
+ - 'VARLDSARV.*'
+ import:
+ path: 'VARLDSARV.shp'
+ format: ESRI Shapefile
+ layername: VARLDSARV
+ publish: varldsarv
- 'nvr:NVA':
+ 'nvr.Biosfarsomraden':
+ # https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/Naturvardsregistret_beskrivning_av_oppna_data.pdf
+ description: Biosfärsområden (UNESCO)
+ create:
+ geometry-type: MULTIPOLYGON
+ fields:
+ - name: SKYDDSTYP
+ type: String
+ width: 32
+ nullable: false
+ comment: Skyddstyp
+ - name: NAMN
+ type: String
+ width: 32
+ unique: true
+ nullable: false
+ - name: LINK
+ type: String
+ width: 254
+ nullable: false
source:
- download: 'https://geodata.naturvardsverket.se/nedladdning/naturvardsregistret/NVA.zip'
- cache: naturvardsregistret/
+ path: nvk/nvr/biosfarsomraden.zip
+ unar:
+ format: zip
+ patterns:
+ - 'BIOSFARSOMRADEN.*'
+ import:
+ path: 'BIOSFARSOMRADEN.shp'
+ format: ESRI Shapefile
+ layername: BIOSFARSOMRADEN
+ publish: biosfarsomraden
- 'sks:AvverkAnm':
- # https://geodpags.skogsstyrelsen.se/geodataport/feeds/AvverkAnm.xml
- description: Avverkningsanmälningar (Skogsstyrelsen)
+ 'nvk.naturvardsavtal':
+ description: Naturvårdsavtal (Naturvårdsverket, Länsstyrelse)
create:
geometry-type: MULTIPOLYGON
fields:
- # https://www.skogsstyrelsen.se/globalassets/sjalvservice/karttjanster/geodatatjanster/produktbeskrivningar/yttre-granser-for-avverkningsanmalda-omraden---produktbeskrivning.pdf
- # ”Ett urval görs så att endast de som är < 5 år och inte avverkade visas. Max 80 %.”
- - name: OBJECTID
+ - name: ID
type: Integer
+ # XXX how come there is no UNIQUE constraint here?
+ unique: false
+ nullable: false
+ - name: DIARIENRNV
+ type: String
+ width: 12
+ # XXX how come there is no UNIQUE constraint here?
+ unique: false
+ nullable: false
+ - name: STATUS
+ type: String
+ width: 32
+ nullable: false
+ - name: OBJNAMN
+ type: String
+ width: 64
+ - name: FASTBET
+ type: String
+ width: 64
+ - name: DATSTART
+ type: Date
+ nullable: false
+ - name: DATSLUT
+ type: Date
+ nullable: false
+ source:
+ path: nvk/nvr/NVA.zip
+ unar:
+ format: zip
+ patterns:
+ - 'NVA.*'
+ import:
+ path: 'NVA.shp'
+ format: ESRI Shapefile
+ layername: NVA
+ publish: naturvardsavtal
+
+ 'sks.naturvardsavtal':
+ description: Naturvårdsavtal (Skogsstyrelsen)
+ create:
+ geometry-type: MULTIPOLYGON
+ fields:
+ - name: Uuid
+ type: String
+ subtype: UUID
+ #width: 36
unique: true
nullable: false
comment: Unik identitet
@@ -448,16 +2441,232 @@ layers:
subtype: Int16
nullable: false
comment: År anmälan/ansökan registrerades
- - name: Avverktyp
+ - name: NvaTyp
type: String
width: 254
+ - name: Naturtyp
+ type: String
+ width: 254
+ - name: AreaTot
+ type: Real
nullable: false
- comment: Vad anmälan/ansökan gäller
- - name: Skogstyp
+ - name: AreaProd
+ type: Real
+ nullable: false
+ - name: Standort
+ type: String
+ width: 254
+ comment: Ståndortsindex
+ - name: DatAvtal
+ type: Date
+ - name: Url
type: String
width: 254
nullable: false
- comment: Anger om avverkning är inom fjällnära skog eller normal skog
+ comment: Länk till visningsformulär i Skogens Pärlor
+ - name: Undertyp
+ type: String
+ width: 64
+ source:
+ path: sks/sksNaturvardsavtal_gpkg.zip
+ unar:
+ format: zip
+ import:
+ path: 'sksNaturvardsavtal.gpkg'
+ format: GPKG
+ layername: NaturvardsavtalYta
+ value-map:
+ Standort:
+ - replace: 'saknas'
+ with: null
+ publish: naturvardsavtal_skogsstyrelsen
+
+ 'nvk.skyddsvard_statlig_skog':
+ description: Skyddsvärda statliga skogar
+ create:
+ geometry-type: MULTIPOLYGON
+ fields:
+ # https://www.naturvardsverket.se/4ac2d0/contentassets/ca013e1f046749e9b01f8bc6f7733626/statlig-skog-skyddsvarda-s-norrbotten-objekt-del1.pdf
+ - name: ID
+ type: Integer
+ nullable: false
+ # XXX how come there is no UNIQUE constraint here?
+ #unique: true
+ - name: NAMN
+ type: String
+ width: 62
+ nullable: false
+ - name: AR
+ type: Integer
+ subtype: Int16
+ nullable: false
+ comment: År
+ - name: NATURGEOGR
+ type: String
+ width: 62
+ comment: Naturgeografisk region
+ - name: OBJEKTKATE
+ type: String
+ width: 12
+ comment: Objektskategori
+ - name: MARKAGARE
+ type: String
+ width: 254
+ comment: Markägare
+ - name: VARDEKARNA
+ # XXX convert to m²?
+ type: Real
+ nullable: false
+ comment: Areal värdekärna (ha)
+ - name: UTV_MARK
+ # XXX convert to m²?
+ type: Real
+ nullable: false
+ comment: Areal utvecklingsmark (ha)
+ - name: TOTAL_AREA
+ # XXX convert to m²?
+ type: Real
+ nullable: false
+ comment: Totalareal (ha)
+ - name: LAND
+ # XXX convert to m²?
+ type: Real
+ nullable: false
+ comment: Areal land (ha)
+ - name: VATTEN
+ # XXX convert to m²?
+ type: Real
+ nullable: false
+ comment: Areal vatten (ha)
+ - name: PROD_SKOG
+ # XXX convert to m²?
+ type: Real
+ nullable: false
+ comment: Areal produktiv skogsmark (ha)
+ - name: SKOG_O_FJG
+ # XXX convert to m²?
+ type: Real
+ nullable: false
+ comment: Areal produktiv skogsmark ovanför fjällnära gräns (ha)
+ - name: SKOG_N_FJG
+ # XXX convert to m²?
+ type: Real
+ nullable: false
+ comment: Areal produktiv skogsmark nedanför fjällnära gräns (ha)
+ - name: SKYDDSZON
+ # XXX convert to m²?
+ type: Real
+ nullable: false
+ comment: Areal skyddszon (ha)
+ - name: ARRO_MARK
+ # XXX convert to m²?
+ type: Real
+ nullable: false
+ comment: Areal arronderingsmark (ha)
+ - name: KRITERIER
+ type: String
+ width: 254
+ nullable: false
+ - name: BESKRIVN
+ type: String
+ width: 254
+ nullable: false
+ - name: LST_BEDOMN
+ type: String
+ width: 254
+ nullable: false
+ - name: KALLOR
+ type: String
+ width: 254
+ source:
+ path: nvk/Skyddsvarda_statliga_skogar.zip
+ unar:
+ format: zip
+ patterns:
+ - 'SNUS.*'
+ import:
+ path: SNUS.shp
+ format: ESRI Shapefile
+ layername: SNUS
+ value-map:
+ KRITERIER:
+ - replace: '(.*[^.])\.\.\.'
+ with: '{0}…'
+ type: regex
+ BESKRIVN:
+ - replace: '(.*[^.])\.\.\.'
+ with: '{0}…'
+ type: regex
+ LST_BEDOMN:
+ - replace: '(.*[^.])\.\.\.'
+ with: '{0}…'
+ type: regex
+ KALLOR:
+ - replace: '(.*[^.])\.\.\.'
+ with: '{0}…'
+ type: regex
+ publish: snus
+
+ 'lst.pagaende_naturreservatsbildning':
+ description: LstBD Pågående naturreservatsbildning
+ create:
+ geometry-type: MULTIPOLYGON
+ fields:
+ - name: NAMN
+ type: String
+ width: 62
+ nullable: false
+ - name: GRANSJUST
+ type: Date
+ - name: DOS_ID
+ type: Integer
+ source:
+ # XXX Unfortunately only Norrbotten (lstBD) provides this right now
+ path: lst/lstext.Pagaende_reservatsbildning.zip
+ unar:
+ format: zip
+ patterns:
+ - 'lstext.Pagaende_reservatsbildning.*'
+ import:
+ path: lstext.Pagaende_reservatsbildning.shp
+ format: ESRI Shapefile
+ layername: lstext.Pagaende_reservatsbildning
+ value-map:
+ GRANSJUST:
+ # 1900-01-01 innebär att datum ej identifierats
+ - replace: '19000101'
+ with: null
+ - replace: '([0-9]{4})([0-9]{2})([0-9]{2})(?:[0-9]{6})?'
+ with: '{0}-{1}-{2}'
+ type: regex
+ publish: pagaende_naturreservatsbildning
+
+
+ 'sks.avverk_anmald':
+ # https://geodpags.skogsstyrelsen.se/geodataport/feeds/AvverkAnm.xml
+ description: Avverkningsanmälningar (Skogsstyrelsen)
+ create:
+ geometry-type: MULTIPOLYGON
+ fields:
+ # https://www.skogsstyrelsen.se/globalassets/sjalvservice/karttjanster/geodatatjanster/produktbeskrivningar/yttre-granser-for-avverkningsanmalda-omraden---produktbeskrivning.pdf
+ # ”Ett urval görs så att endast de som är < 5 år och inte avverkade visas. Max 80 %.”
+ - name: OBJECTID
+ type: Integer
+ unique: true
+ nullable: false
+ comment: Unik identitet
+ - name: Beteckn
+ type: String
+ width: 12
+ # XXX how come there is no UNIQUE constraint here?
+ #unique: true
+ nullable: false
+ comment: Ärendebeteckning
+ - name: ArendeAr
+ type: Integer
+ subtype: Int16
+ nullable: false
+ comment: År anmälan/ansökan registrerades
- name: Inkomdatum
type: Date
nullable: false
@@ -471,19 +2680,17 @@ layers:
- name: SkogsodlHa
type: Real
subtype: Float32
- nullable: false
comment: Areal plantering (ha)
- name: NatforHa
type: Real
subtype: Float32
- nullable: false
comment: Areal naturlig föryngring (ha)
- name: AvvSasong
type: String
width: 254
nullable: false
comment: Avverkningssäsong
- - name: ArendeStat
+ - name: ArendeStatus
type: String
width: 254
nullable: false
@@ -492,40 +2699,37 @@ layers:
type: Real
subtype: Float32
comment: Avverkad areal (ha)
- - name: Avverkning
+ - name: AvverkningsanmalanKlass
type: String
width: 254
nullable: false
comment: Avverkningsamalan/NyAvverkningsanmalan
source:
- download:
- url: 'https://geodpags.skogsstyrelsen.se/geodataport/data/sksAvverkAnm.zip'
- max-size: 134217728 # 128MiB
- cache: sks/
+ path: sks/sksAvverkAnm_gpkg.zip
unar:
format: zip
- patterns:
- - 'sksAvverkAnm.*'
import:
- path: sksAvverkAnm.shp
- format: ESRI Shapefile
- layername: sksAvverkAnm
+ path: sksAvverkAnm.gpkg
+ format: GPKG
+ layername: AvverkningsAnmalanYta
field-map:
- OBJECTID
- Beteckn
- ArendeAr
- - Avverktyp
- - Skogstyp
- Inkomdatum
- AnmaldHa
- SkogsodlHa
- NatforHa
+ - ArendeStatus
- AvvSasong
- - ArendeStat
- AvvHa
- - Avverkning
+ - AvverkningsanmalanKlass
+ publish:
+ anmald:
+ fields:
+ ts: Inkomdatum
- 'sks:UtfordAvverk':
+ 'sks.avverk_utford':
# https://geodpags.skogsstyrelsen.se/geodataport/feeds/UtfordAvverk.xml
description: Utförd avverkning (Skogsstyrelsen)
create:
@@ -564,27 +2768,17 @@ layers:
subtype: Float32
nullable: false
comment: Areal anmält (ha)
- - name: SkogsodlHa
- type: Real
- subtype: Float32
- nullable: false
- comment: Areal plantering (ha)
- name: NatforHa
type: Real
subtype: Float32
- nullable: false
comment: Areal naturlig föryngring (ha)
- name: Avvdatum
type: Date
- nullable: false
comment: Datum för avverkning
- name: KallaDatum
- type: Date
- comment: Ursprung för datum för avverkning (vid ”Uppgift saknas” är det vanligen Skogsstyrelsens personal som registrerat datumet)
- - name: KallaAreal
type: String
width: 62
- comment: Ursprung för areal avverkning (vid ”Uppgift saknas” är det vanligen Skogsstyrelsens personal som registrerat datumet)
+ comment: Ursprung för datum för avverkning (vid ”Uppgift saknas” är det vanligen Skogsstyrelsens personal som registrerat datumet)
- name: Forebild
type: String
width: 62
@@ -598,157 +2792,268 @@ layers:
subtype: Float32
nullable: false
comment: Areal för ytan (ha)
+ source:
+ path: sks/sksUtfordAvverk_gpkg.zip
+ unar:
+ format: zip
+ import:
+ path: sksUtfordAvverk.gpkg
+ format: GPKG
+ layername: UtfordAvverkningYta
+ field-map:
+ OBJECTID: OBJECTID
+ Beteckn: Beteckn
+ Arendear: ArendeAr
+ Avverktyp: Avverktyp
+ Skogstyp: Skogstyp
+ AnmaldHa: AnmaldHa
+ Natforha: NatforHa
+ Avvdatum: Avvdatum
+ KallaDatum: KallaDatum
+ Forebild: Forebild
+ Efterbild: Efterbild
+ Arealha: ArealHa
+ value-map:
+ Beteckn:
+ - replace: 'Visas ej'
+ with: null
+ publish:
+ utford:
+ fields:
+ ts: Avvdatum
- sources:
- - source:
- download:
- url: 'https://geodpags.skogsstyrelsen.se/geodataport/data/sksUtfordAvverk-2000-2015.zip'
- max-size: 805306368 # 768MiB
- cache:
- path: sks/
- max-age: 2592000 # 30d
- unar:
- format: zip
- patterns:
- - 'sksUtfordAvverk-2000-2015.*'
- import:
- path: sksUtfordAvverk-2000-2015.shp
- format: ESRI Shapefile
- layername: sksUtfordAvverk-2000-2015
- field-map:
- OBJECTID: OBJECTID
- Beteckn: Beteckn
- Arendear: ArendeAr
- Avverktyp: Avverktyp
- Skogstyp: Skogstyp
- AnmaldHa: AnmaldHa
- SkogsodlHa: SkogsodlHa
- Natforha: NatforHa
- Avvdatum: Avvdatum
- KallaDatum: KallaDatum
- KallaAreal: KallaAreal
- Forebild: Forebild
- Efterbild: Efterbild
- Arealha: ArealHa
- value-map:
- Beteckn:
- - replace: 'Visas ej'
- with: null
-
- - source:
- download:
- url: 'https://geodpags.skogsstyrelsen.se/geodataport/data/sksUtfordAvverk-2016-2019.zip'
- max-size: 805306368 # 768MiB
- cache:
- path: sks/
- max-age: 2592000 # 30d
- unar:
- format: zip
- patterns:
- - 'sksUtfordAvverk-2016-2019.*'
- import:
- path: sksUtfordAvverk-2016-2019.shp
- format: ESRI Shapefile
- layername: sksUtfordAvverk-2016-2019
- field-map:
- OBJECTID: OBJECTID
- Beteckn: Beteckn
- Arendear: ArendeAr
- Avverktyp: Avverktyp
- Skogstyp: Skogstyp
- AnmaldHa: AnmaldHa
- SkogsodlHa: SkogsodlHa
- Natforha: NatforHa
- Avvdatum: Avvdatum
- KallaDatum: KallaDatum
- KallaAreal: KallaAreal
- Forebild: Forebild
- Efterbild: Efterbild
- Arealha: ArealHa
- value-map:
- Beteckn:
- - replace: 'Visas ej'
- with: null
+ 'sametinget.betesomrade':
+ description: 'Samebyarnas betesområden: Renbetesområden'
+ create:
+ # https://ext-dokument.lansstyrelsen.se/Gemensamt/Geodata/Datadistribution/Information,%20Skiktf%C3%B6rteckning%20och%20f%C3%B6rklaringar.pdf
+ geometry-type: MULTIPOLYGON
+ fields:
+ - name: SAMEBY_ID
+ type: Integer
+ unique: true
+ nullable: false
+ - name: BY_ID
+ type: Integer
+ - name: NAMN
+ type: String
+ width: 62
+ nullable: false
+ - name: SIGNATUR
+ type: String
+ width: 25
+ nullable: false
+ - name: SAMEBY_TYP
+ type: String
+ width: 62
+ nullable: false
+ - name: BY_OMR
+ type: Integer
+ subtype: Bool
+ nullable: false
+ - name: OVR_OMR
+ type: Integer
+ subtype: Bool
+ nullable: false
+ - name: AKTUALITET
+ type: Date
+ nullable: false
+ source:
+ path: sametinget/Samebyarnas_betesomraden.zip
+ unar:
+ format: zip
+ patterns:
+ - 'Samebyarnas_betesomraden/Samebyarnas betesområden/IRENMARK_DBO_sameby.*'
+ import:
+ path: 'Samebyarnas_betesomraden/Samebyarnas betesområden/IRENMARK_DBO_sameby.shp'
+ format: ESRI Shapefile
+ layername: IRENMARK_DBO_sameby
+ value-map:
+ BY_ID:
+ - replace: 9999
+ with: null
+ publish: betesomrade
- - source:
- download:
- url: 'https://geodpags.skogsstyrelsen.se/geodataport/data/sksUtfordAvverk-2020-2022.zip'
- max-size: 805306368 # 768MiB
- cache:
- path: sks/
- max-age: 864000 # 10d
- unar:
- format: zip
- patterns:
- - 'sksUtfordAvverk-2020-2022.*'
- import:
- path: sksUtfordAvverk-2020-2022.shp
- format: ESRI Shapefile
- layername: sksUtfordAvverk-2020-2022
- field-map:
- OBJECTID: OBJECTID
- Beteckn: Beteckn
- Arendear: ArendeAr
- Avverktyp: Avverktyp
- Skogstyp: Skogstyp
- AnmaldHa: AnmaldHa
- SkogsodlHa: SkogsodlHa
- Natforha: NatforHa
- Avvdatum: Avvdatum
- KallaDatum: KallaDatum
- KallaAreal: KallaAreal
- Forebild: Forebild
- Efterbild: Efterbild
- Arealha: ArealHa
- value-map:
- Beteckn:
- - replace: 'Visas ej'
- with: null
+ 'sametinget.flyttled':
+ description: 'Samebyarnas markanvändningsredovisning: Flyttled'
+ create:
+ # https://ext-dokument.lansstyrelsen.se/Gemensamt/Geodata/Datadistribution/Information,%20Skiktf%C3%B6rteckning%20och%20f%C3%B6rklaringar.pdf
+ geometry-type: MULTILINESTRING
+ fields:
+ - name: LED_ID
+ type: Integer
+ nullable: false
+ # NOTE: these could be provided as a list instead
+ - name: BYNR1
+ type: Integer
+ nullable: false
+ - name: BYNR2
+ type: Integer
+ nullable: false
+ - name: BYNR3
+ type: Integer
+ nullable: false
+ - name: SAMEBY1
+ type: String
+ width: 62
+ - name: SAMEBY2
+ type: String
+ width: 62
+ - name: SAMEBY3
+ type: String
+ width: 62
+ - name: KKOD
+ type: Integer
+ nullable: false
+ - name: BESKRIVNIN
+ type: String
+ width: 62
+ - name: ARSTID
+ type: String
+ width: 62
+ - name: KONV_AR
+ type: String
+ width: 62
+ - name: SIGNATUR
+ type: String
+ width: 25
+ - name: RIKSINTR
+ type: Integer
+ subtype: Bool
+ nullable: false
+ - name: FAST_LED
+ type: Integer
+ subtype: Bool
+ nullable: false
+ - name: AKTUALITET
+ # XXX these have a mix of YYYY, YYMMDD, YYYYMMDD
+ type: String
+ width: 10
+ - name: GlobalID
+ type: String
+ subtype: UUID
+ #width: 36
+ unique: true
+ nullable: false
+ source:
+ path: sametinget/Samebyarnas_markanvandningsredovisning.zip
+ unar:
+ format: zip
+ patterns:
+ - 'Samebyarnas markanvändningsredovisning/Stategiska områden/IRENMARK_DBO_led.*'
+ import:
+ path: 'Samebyarnas markanvändningsredovisning/Stategiska områden/IRENMARK_DBO_led.shp'
+ format: ESRI Shapefile
+ layername: IRENMARK_DBO_led
+ value-map:
+ GlobalID:
+ - replace: '\{([0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12})\}'
+ with: '{0}'
+ type: regex
+ publish: flyttled
- - source:
- download:
- url: 'https://geodpags.skogsstyrelsen.se/geodataport/data/sksUtfordAvverk-2023-.zip'
- max-size: 1073741824 # 1GiB
- cache: sks/
- unar:
- format: zip
- patterns:
- - 'sksUtfordAvverk-2023-.*'
- import:
- path: sksUtfordAvverk-2023-.shp
- format: ESRI Shapefile
- layername: sksUtfordAvverk-2023-
- field-map:
- OBJECTID: OBJECTID
- Beteckn: Beteckn
- Arendear: ArendeAr
- Avverktyp: Avverktyp
- Skogstyp: Skogstyp
- AnmaldHa: AnmaldHa
- SkogsodlHa: SkogsodlHa
- Natforha: NatforHa
- Avvdatum: Avvdatum
- KallaDatum: KallaDatum
- KallaAreal: KallaAreal
- Forebild: Forebild
- Efterbild: Efterbild
- Arealha: ArealHa
- value-map:
- Beteckn:
- - replace: 'Visas ej'
- with: null
-
- 'st:betesomraden':
+ 'sametinget.riksintresse_rennaringen':
+ description: 'Riksintresse Rennäringen'
+ create:
+ geometry-type: MULTIPOLYGON
+ fields:
+ - name: LAGRUM
+ type: String
+ width: 254
+ nullable: false
+ - name: AKTUALITET
+ type: Date
+ nullable: false
+ - name: SIGNATUR
+ type: String
+ width: 25
+ nullable: false
+ - name: LANK
+ type: String
+ width: 254
+ - name: GlobalID
+ type: String
+ subtype: UUID
+ #width: 36
+ unique: true
+ nullable: false
source:
- download: 'https://ext-dokument.lansstyrelsen.se/Gemensamt/Geodata/Datadistribution/SWEREF99TM/Sametinget/Samebyarnas_betesomraden.zip'
- cache: sametinget/
+ path: sametinget/ren.riks_ren.zip
+ unar:
+ format: zip
+ patterns:
+ - 'ren.riks_ren.*'
+ import:
+ path: ren.riks_ren.shp
+ format: ESRI Shapefile
+ layername: ren.riks_ren
+ value-map:
+ GlobalID:
+ - replace: '\{([0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12})\}'
+ with: '{0}'
+ type: regex
+ publish: riks_ren
- 'st:markanvandning':
+ 'sametinget.riksintresse_rennaringen_karnomrade':
+ description: 'Riksintresse Rennäringen — Kärnområde'
+ create:
+ geometry-type: MULTIPOLYGON
+ fields:
+ - name: LANK
+ type: String
+ width: 254
+ nullable: false
+ - name: LANSKOD
+ type: String
+ width: 25
+ nullable: false
+ - name: OMR_NR
+ type: Integer
+ - name: ARET_RUNT
+ type: Integer
+ - name: SAMEBY
+ type: String
+ width: 62
+ nullable: false
+ - name: ANSVARIG
+ type: String
+ width: 25
+ nullable: false
+ - name: AKTUALITET
+ type: Date
+ nullable: false
+ - name: SIGNATUR
+ type: String
+ width: 25
+ - name: GlobalID
+ type: String
+ subtype: UUID
+ #width: 36
+ unique: true
+ nullable: false
source:
- download: 'http://ext-dokument.lansstyrelsen.se/Gemensamt/Geodata/Datadistribution/SWEREF99TM/Sametinget/Samebyarnas_markanvandningsredovisning.zip'
- cache: sametinget/
+ path: sametinget/ren.omr_riks.zip
+ unar:
+ format: zip
+ patterns:
+ - 'ren.omr_riks.*'
+ import:
+ path: ren.omr_riks.shp
+ format: ESRI Shapefile
+ layername: ren.omr_riks
+ value-map:
+ OMR_NR:
+ - replace: 9999
+ with: null
+ ARET_RUNT:
+ - replace: 9999
+ with: null
+ GlobalID:
+ - replace: '\{([0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12})\}'
+ with: '{0}'
+ type: regex
+ publish: omr_riks
- 'vbk:vindkraftverk':
+ 'vbk.vindkraftverk':
description: Vindbrukskollen landbaserade vindkraftverk (Länsstyrelsen)
create:
geometry-type: POINT
@@ -857,16 +3162,15 @@ layers:
subtype: Bool
nullable: false
source:
- download: 'https://ext-dokument.lansstyrelsen.se/gemensamt/geodata/ShapeExport/lst.vbk_vindkraftverk.zip'
- cache: vbk/
+ path: vbk/lst.vbk_vindkraftverk.zip
unar:
format: zip
patterns:
- - 'LST.vbk_vindkraftverk.*'
+ - 'lst.vbk_vindkraftverk.*'
import:
- path: LST.vbk_vindkraftverk.shp
+ path: lst.vbk_vindkraftverk.shp
format: ESRI Shapefile
- layername: LST.vbk_vindkraftverk
+ layername: lst.vbk_vindkraftverk
field-map:
VERKID: VerkID
OMRID: OmrID
@@ -929,18 +3233,51 @@ layers:
- replace: '([0-9]{4})([0-9]{2})([0-9]{2})'
with: '{0}-{1}-{2}'
type: regex
- EJAKTUELL:
- - replace: 'Yes'
- with: '1'
- - replace: 'No'
- with: '0'
- RADERAD:
- - replace: 'Yes'
- with: '1'
- - replace: 'No'
- with: '0'
+ publish:
+ turbine_completed:
+ minzoom: 4
+ where: |
+ "Raderat" IS FALSE AND "Statuskod" = 4
+ fields:
+ ts: SenasteUppdaterat
+ turbine_processed:
+ minzoom: 4
+ where: |
+ "Raderat" IS FALSE AND "Statuskod" = 1
+ fields:
+ ts: SenasteUppdaterat
+ turbine_approved:
+ minzoom: 4
+ where: |
+ "Raderat" IS FALSE AND "Statuskod" = 3
+ fields:
+ ts: SenasteUppdaterat
+ turbine_revoked:
+ minzoom: 4
+ where: |
+ "Raderat" IS FALSE AND ("Statuskod" = 6 OR "Statuskod" = 9)
+ fields:
+ ts: SenasteUppdaterat
+ turbine_rejected:
+ minzoom: 4
+ where: |
+ "Raderat" IS FALSE AND "Statuskod" = 7
+ fields:
+ ts: SenasteUppdaterat
+ turbine_dismounted:
+ minzoom: 4
+ where: |
+ "Raderat" IS FALSE AND "Statuskod" = 5
+ fields:
+ ts: SenasteUppdaterat
+ turbine_appealed:
+ minzoom: 4
+ where: |
+ "Raderat" IS FALSE AND "Statuskod" = 8
+ fields:
+ ts: SenasteUppdaterat
- 'vbk:projekteringsomraden':
+ 'vbk.projekteringsomraden':
description: Vindbrukskollen landbaserade projekteringsområden (Länsstyrelsen)
create:
geometry-type: MULTIPOLYGON
@@ -1022,16 +3359,15 @@ layers:
subtype: Bool
nullable: false
source:
- download: 'https://ext-dokument.lansstyrelsen.se/gemensamt/geodata/ShapeExport/lst.vbk_projekteringsomraden.zip'
- cache: vbk/
+ path: vbk/lst.vbk_projekteringsomraden.zip
unar:
format: zip
patterns:
- - 'LST.vbk_projekteringsomraden.*'
+ - 'lst.vbk_projekteringsomraden.*'
import:
- path: LST.vbk_projekteringsomraden.shp
+ path: lst.vbk_projekteringsomraden.shp
format: ESRI Shapefile
- layername: LST.vbk_projekteringsomraden
+ layername: lst.vbk_projekteringsomraden
field-map:
OMRID: OmrID
PROJNAMN: Projektnamn
@@ -1080,18 +3416,19 @@ layers:
- replace: '([0-9]{4})([0-9]{2})([0-9]{2})'
with: '{0}-{1}-{2}'
type: regex
- EJAKTUELL:
- - replace: 'Yes'
- with: '1'
- - replace: 'No'
- with: '0'
- Raderat:
- - replace: 'Yes'
- with: '1'
- - replace: 'No'
- with: '0'
+ publish:
+ area_current:
+ where: |
+ "Raderat" IS FALSE AND "EjAktuell" IS FALSE
+ fields:
+ ts: SenasteUppdaterat
+ area_notcurrent:
+ where: |
+ "Raderat" IS FALSE AND "EjAktuell" IS NOT FALSE
+ fields:
+ ts: SenasteUppdaterat
- 'vbk:havsbaserad_vindkraft':
+ 'vbk.havsbaserad_vindkraft':
description: Vindbrukskollen havsbaserad vindkraft (Länsstyrelsen)
create:
geometry-type: MULTIPOLYGON
@@ -1100,13 +3437,7 @@ layers:
alias: Områdes-ID
type: String
width: 10
- # XXX The provided GeoPKG splits multi polygons into several
- # features of geometry type polygon. lst.vbk_vindkraftverk.zip
- # has also LST.vbk_havsbaserad_vindkraft.shp with the proper
- # features, but unfortunately that layer doesn't seem to be
- # updated as often (and also isn't official). So we remove
- # the UNIQUE condition for now.
- #unique: true
+ unique: true
nullable: false
comment: ID-nummer i Vindbruksollen för projekteringsområdet
- name: Projektnamn
@@ -1239,36 +3570,37 @@ layers:
subtype: Bool
nullable: false
source:
- download: 'https://ext-dokument.lansstyrelsen.se/gemensamt/geodata/ShapeExport/lst.vbk_havsbaserad_vindkraft.zip'
- cache: vbk/
+ path: vbk/lst.vbk_havsbaserad_vindkraft.zip
unar:
format: zip
+ patterns:
+ - 'lst.vbk_havsbaserad_vindkraft.*'
import:
- path: LST.vbk_havsbaserad_vindkraft.gpkg
- format: GPKG
- layername: vbk_havsbaserad_vindkraft
+ path: lst.vbk_havsbaserad_vindkraft.shp
+ format: ESRI Shapefile
+ layername: lst.vbk_havsbaserad_vindkraft
field-map:
OMRID: OmrID
- HAVSPARKNAMN: Projektnamn
+ HAVSPARKNA: Projektnamn
Orgnamn: Organisationsnamn
Orgnr: Organisationsnummer
- ArendeStatus: Projektstatus
+ ArendeStat: Projektstatus
DNR: Diarienummer
- AndringsansokanPagar: AndringsansokanPagar
+ Andringsan: AndringsansokanPagar
SAMRAD: SamradsunderlagInlamnat
ANSOKINL: AnsokanInlamnat
ATERKALL: AnsokanAterkallad
- ANSOKTILLST: AnsokanBeviljad
+ ANSOKTILLS: AnsokanBeviljad
ANSOKAVSL: AnsokanAvslagen
- ANSOKOVERKL: AnsokanOverklagad
+ ANSOKOVERK: AnsokanOverklagad
N2000ANS: Natura2000_Ansokan
N2000BES: Natura2000_Beslutdatum
UNDERBYGGN: UnderByggnation
UPPFORD: Uppfort
Planantmin: PlaneratAntalVerkMin
planantmax: PlaneratAntalVerkMax
- Planhojdmin: PlaneradHojdMin
- Planhojdmax: PlaneradHojdMax
+ Planhojdmi: PlaneradHojdMin
+ Planhojdma: PlaneradHojdMax
PlanGWhmin: PlaneradProduktionMin
PlanGWhmax: PlaneradProduktionMax
PBYGGSTART: PlaneradByggstart
@@ -1277,9 +3609,9 @@ layers:
Uppfortant: UppfortAntalVerk
BevMaxHojd: BeviljadMaxhojd
InstallEff: InstalleradEffekt
- BeraknadGWh: Calprod
+ BeraknadGW: Calprod
Elomrade: ElNamn
- SenasteUppdaterat: SenasteUppdaterat
+ SenasteUpp: SenasteUppdaterat
Raderat: Raderat
value-map:
Orgnamn:
@@ -1291,7 +3623,7 @@ layers:
DNR:
- replace: ''
with: null
- AndringsansokanPagar:
+ Andringsan:
- replace: 'Ja'
with: '1'
- replace: 'Nej'
@@ -1306,502 +3638,1828 @@ layers:
with: '1'
- replace: 'No'
with: '0'
+ SenasteUpp:
+ - replace: '([0-9]{4})([0-9]{2})([0-9]{2})'
+ with: '{0}-{1}-{2}'
+ type: regex
+ publish:
+ offshore_completed:
+ where: |
+ "Raderat" IS FALSE AND "Projektstatus" = 'Uppförd'
+ fields:
+ ts: SenasteUppdaterat
+ offshore_approved:
+ where: |
+ "Raderat" IS FALSE AND "Projektstatus" = 'Tillståndsansökan beviljad'
+ fields:
+ ts: SenasteUppdaterat
+ offshore_amended:
+ where: |
+ "Raderat" IS FALSE AND "Projektstatus" = 'Ändringsansökan'
+ fields:
+ ts: SenasteUppdaterat
+ offshore_rejected:
+ where: |
+ "Raderat" IS FALSE AND "Projektstatus" = 'Tillståndsansökan avslagen'
+ fields:
+ ts: SenasteUppdaterat
+ offshore_appealed:
+ where: |
+ "Raderat" IS FALSE AND "Projektstatus" = 'Överklagad'
+ fields:
+ ts: SenasteUppdaterat
+ offshore_applied:
+ where: |
+ "Raderat" IS FALSE AND "Projektstatus" = 'Tillståndsansökan inlämnad'
+ fields:
+ ts: SenasteUppdaterat
+ offshore_consultation:
+ where: |
+ "Raderat" IS FALSE AND "Projektstatus" = 'Samråd inför tillståndsansökan'
+ fields:
+ ts: SenasteUppdaterat
+ offshore_investigation:
+ where: |
+ "Raderat" IS FALSE AND "Projektstatus" = 'Inledande undersökningar'
+ fields:
+ ts: SenasteUppdaterat
+ offshore_revoked:
+ where: |
+ "Raderat" IS FALSE AND "Projektstatus" = 'Inte aktuell eller återkallad'
+ fields:
+ ts: SenasteUppdaterat
- # The list of layers available on the WMS server can be found at
- # https://maps3.sgu.se/geoserver/wms?SERVICE=WMS&VERSION=1.11&REQUEST=GetCapabilities
- 'mrr:bearbetningskoncessioner_applied':
- description: Bearbetningskoncessioner, ansökta (SGU)
+ 'mrr.ut_metaller_industrimineral_ansokta':
+ # https://resource.sgu.se/dokument/produkter/mineralrattigheter-beskrivning.pdf
+ description: Undersökningstillstånd - Metaller och industrimineral, ansökta (SGU)
create:
geometry-type: MULTIPOLYGON
fields:
- - name: Name
+ - name: name
+ type: String
+ #unique: true
+ nullable: false
+ width: 254
+ comment: Namn på ansökt undersökningsområde
+ - name: diarynr
type: String
unique: true
nullable: false
+ width: 16
+ comment: Ärendenummer i diariet
+ - name: appl_date
+ type: Date
+ nullable: false
+ comment: Datum när ansökan inkom till Bergsstaten
+ - name: mineral
+ type: String
+ nullable: false
width: 254
- comment: Benämning på området
- - name: Mineral
+ comment: Koncessionsmineral som ska eftersökas
+ - name: owners
type: String
nullable: false
width: 254
- comment: Koncessionsmineral
- - name: Applicant
+ comment: Sökanden av undersökningstillståndet
+ source:
+ path: mrr/mineralrattigheter.zip
+ unar:
+ format: zip
+ import:
+ path: mineralrattigheter.gpkg
+ format: GPKG
+ layername: ut_metaller_industrimineral_ansokta
+ publish:
+ appl_met:
+ fields:
+ ts: appl_date
+
+ 'mrr.ut_diamant_ansokta':
+ # https://resource.sgu.se/dokument/produkter/mineralrattigheter-beskrivning.pdf
+ description: Undersökningstillstånd - Diamant, ansökta (SGU)
+ create:
+ geometry-type: MULTIPOLYGON
+ fields:
+ - name: name
type: String
+ unique: true
nullable: false
width: 254
- comment: Sökandens namn
- - name: ApplicationDate
+ comment: Namn på ansökt undersökningsområde
+ - name: diarynr
+ type: String
+ unique: true
+ nullable: false
+ width: 16
+ comment: Ärendenummer i diariet
+ - name: appl_date
type: Date
nullable: false
- - name: DiaryNr
+ comment: Datum när ansökan inkom till Bergsstaten
+ - name: mineral
+ type: String
+ nullable: false
+ width: 254
+ comment: Koncessionsmineral som ska eftersökas
+ - name: owners
+ type: String
+ nullable: false
+ width: 254
+ comment: Sökanden av undersökningstillståndet
+ source:
+ path: mrr/mineralrattigheter.zip
+ unar:
+ format: zip
+ import:
+ path: mineralrattigheter.gpkg
+ format: GPKG
+ layername: ut_diamant_ansokta
+ publish:
+ appl_ogd:
+ fields:
+ ts: appl_date
+
+ 'mrr.bearbetningskoncessioner_ansokta':
+ # https://resource.sgu.se/dokument/produkter/mineralrattigheter-beskrivning.pdf
+ description: Bearbetningskoncessioner, ansökta (SGU)
+ create:
+ geometry-type: MULTIPOLYGON
+ fields:
+ - name: name
+ type: String
+ unique: true
+ nullable: false
+ width: 254
+ comment: Namn på ansökt bearbetningskoncession
+ - name: diarynr
type: String
unique: true
nullable: false
width: 16
- - name: LastUpdated
+ comment: Ärendenummer i diariet
+ - name: appl_date
type: Date
nullable: false
- comment: Datum för senaste uppdatering
+ comment: Datum när ansökan inkom till Bergsstaten
+ - name: mineral
+ type: String
+ nullable: false
+ width: 254
+ comment: Ansökta koncessionsmineraler
+ - name: owners
+ type: String
+ nullable: false
+ width: 254
+ comment: Sökanden av bearbetningskoncessionen
source:
- download:
- module: webmap-download-mrr
- layername: 'MRR:SE.GOV.SGU.MRR.BEARBETNINGSKONCESSIONER_APPLIED_VY'
- cache: mrr/bearbetningskoncessioner_applied.geojson
+ path: mrr/mineralrattigheter.zip
+ unar:
+ format: zip
import:
- format: GeoJSON
- layername: 'MRR:SE.GOV.SGU.MRR.BEARBETNINGSKONCESSIONER_APPLIED_VY'
- field-map:
- 'Name': Name
- 'Mineral': Mineral
- 'Applicant': Applicant
- 'Application date': ApplicationDate
- 'Diary nr': DiaryNr
- 'Last updated': LastUpdated
- value-map:
- 'Last updated':
- - replace: '([0-9]{4})([0-9]{2})([0-9]{2})'
- with: '{0}-{1}-{2}'
- type: regex
+ path: mineralrattigheter.gpkg
+ format: GPKG
+ layername: bearbetningskoncessioner_ansokta
+ publish:
+ appl_ec:
+ fields:
+ ts: appl_date
- 'mrr:bearbetningskoncessioner_approved':
- description: Bearbetningskoncessioner, beviljade (SGU)
+ 'mrr.markanvisningar_bk_ansokta':
+ # https://resource.sgu.se/dokument/produkter/mineralrattigheter-beskrivning.pdf
+ description: Markanvisningar till bearbetningskoncessioner, ansökta (SGU)
create:
geometry-type: MULTIPOLYGON
fields:
- - name: Name
+ - name: name
type: String
unique: true
nullable: false
width: 254
- comment: Benämning på området
- - name: Mineral
+ comment: Namn på ansökt markanvisning
+ - name: diarynr
type: String
+ unique: true
nullable: false
- width: 254
- comment: Koncessionsmineral
- - name: Owner
+ width: 16
+ comment: Ärendenummer i diariet
+ - name: conc_name
type: String
nullable: false
width: 254
- comment: Ägares namn
- - name: ValidFrom
+ comment: Bearbetningskoncession(er) som markanvisningen hör till
+ - name: appl_date
type: Date
nullable: false
- comment: När tillståndets giltighet börjar
- - name: ValidTo
- type: Date
+ comment: Datum när ansökan inkom till Bergsstaten
+ source:
+ path: mrr/mineralrattigheter.zip
+ unar:
+ format: zip
+ import:
+ path: mineralrattigheter.gpkg
+ format: GPKG
+ layername: markanvisningar_bk_ansokta
+
+ 'mrr.ut_metaller_industrimineral_beviljade':
+ # https://resource.sgu.se/dokument/produkter/mineralrattigheter-beskrivning.pdf
+ description: Undersökningstillstånd - Metaller och industrimineral, beviljade (SGU)
+ create:
+ geometry-type: MULTIPOLYGON
+ fields:
+ - name: name
+ type: String
+ unique: true
nullable: false
- comment: När tillståndets giltighet slutar
- - name: DiaryNr
+ width: 254
+ comment: Namn på beviljat undersökningstillstånd
+ - name: licenceid
+ type: String
+ unique: true
+ width: 16
+ comment: Tillståndsid för undersökningstillståndet
+ - name: diarynr
type: String
unique: true
+ nullable: false
width: 16
- - name: LastUpdated
+ comment: Ärendenummer i diariet
+ - name: appl_date
+ type: Date
+ nullable: false
+ comment: Datum när ansökan inkom till Bergsstaten
+ - name: dec_date
+ type: Date
+ nullable: false
+ comment: Datum när undersökningstillståndet beviljades
+ - name: validfrom
+ type: Date
+ nullable: false
+ comment: Datum från och med när undersökningstillståndet började gälla
+ - name: validto
type: Date
nullable: false
- comment: Datum för senaste uppdatering
+ comment: Sista dagen undersökningstillståndet gäller
+ - name: mineral
+ type: String
+ nullable: false
+ width: 254
+ comment: Koncessionsmineral som eftersöks
+ - name: owners
+ type: String
+ nullable: false
+ width: 254
+ comment: Innehavare av undersökningstillståndet
source:
- download:
- module: webmap-download-mrr
- layername: 'MRR:SE.GOV.SGU.MRR.BEARBETNINGSKONCESSIONER_APPROVED_VY'
- cache: mrr/bearbetningskoncessioner_approved.geojson
+ path: mrr/mineralrattigheter.zip
+ unar:
+ format: zip
import:
- format: GeoJSON
- layername: 'MRR:SE.GOV.SGU.MRR.BEARBETNINGSKONCESSIONER_APPROVED_VY'
- field-map:
- 'Name': Name
- 'Mineral': Mineral
- 'Owner': Owner
- 'Valid from': ValidFrom
- 'Valid to': ValidTo
- 'Diary nr': DiaryNr
- 'Last updated': LastUpdated
+ path: mineralrattigheter.gpkg
+ format: GPKG
+ layername: ut_metaller_industrimineral_beviljade
value-map:
- 'Diary nr':
- - replace: ''
+ licenceid:
+ - replace: '-'
with: null
- 'Last updated':
- - replace: '([0-9]{4})([0-9]{2})([0-9]{2})'
- with: '{0}-{1}-{2}'
- type: regex
+ publish:
+ appr_met:
+ fields:
+ ts: dec_date
- 'mrr:markanvisningar':
- description: Markanvisning till koncession (SGU)
+ 'mrr.ut_diamant_beviljade':
+ # https://resource.sgu.se/dokument/produkter/mineralrattigheter-beskrivning.pdf
+ description: Undersökningstillstånd - Diamant, beviljade (SGU)
create:
geometry-type: MULTIPOLYGON
fields:
- - name: Name
+ - name: name
type: String
+ unique: true
nullable: false
width: 254
- comment: Benämning på området
- - name: DecisionDate
- type: Date
- comment: Beslutsdatum
- - name: DiaryNr
+ comment: Namn på beviljat undersökningstillstånd
+ - name: licenceid
type: String
unique: true
width: 16
- - name: LastUpdated
+ comment: Tillståndsid för undersökningstillståndet
+ - name: diarynr
+ type: String
+ unique: true
+ nullable: false
+ width: 16
+ comment: Ärendenummer i diariet
+ - name: appl_date
+ type: Date
+ nullable: false
+ comment: Datum när ansökan inkom till Bergsstaten
+ - name: dec_date
+ type: Date
+ nullable: false
+ comment: Datum när undersökningstillståndet beviljades
+ - name: validfrom
type: Date
nullable: false
- comment: Datum för senaste uppdatering
+ comment: Datum från och med när undersökningstillståndet började gälla
+ - name: validto
+ type: Date
+ nullable: false
+ comment: Sista dagen undersökningstillståndet gäller
+ - name: mineral
+ type: String
+ nullable: false
+ width: 254
+ comment: Koncessionsmineral som eftersöks
+ - name: owners
+ type: String
+ nullable: false
+ width: 254
+ comment: Innehavare av undersökningstillståndet
source:
- download:
- module: webmap-download-mrr
- layername: 'MRR:SE.GOV.SGU.MRR.MARKANVISNINGAR_VY'
- cache: mrr/markanvisningar.geojson
+ path: mrr/mineralrattigheter.zip
+ unar:
+ format: zip
import:
- format: GeoJSON
- layername: 'MRR:SE.GOV.SGU.MRR.MARKANVISNINGAR_VY'
- field-map:
- 'Name': Name
- 'Decision date': DecisionDate
- 'Diary nr': DiaryNr
- 'Last updated': LastUpdated
+ path: mineralrattigheter.gpkg
+ format: GPKG
+ layername: ut_diamant_beviljade
value-map:
- 'Decision date':
- - replace: ''
- with: null
- 'Diary nr':
- - replace: ''
+ licenceid:
+ - replace: '-'
with: null
- 'Last updated':
- - replace: '([0-9]{4})([0-9]{2})([0-9]{2})'
- with: '{0}-{1}-{2}'
- type: regex
+ publish:
+ appr_ogd:
+ fields:
+ ts: dec_date
- 'mrr:mineral_applied':
- description: Undersökningstillstånd, metallar och mineral, ansökta (SGU)
+ 'mrr.bearbetningskoncessioner_beviljade':
+ # https://resource.sgu.se/dokument/produkter/mineralrattigheter-beskrivning.pdf
+ description: Bearbetningskoncessioner, beviljade (SGU)
create:
geometry-type: MULTIPOLYGON
fields:
- - name: Name
+ - name: name
type: String
unique: true
nullable: false
width: 254
- comment: Benämning på området
- - name: Mineral
+ comment: Namn på beviljad bearbetningskoncession
+ - name: licenceid
+ type: String
+ unique: true
+ width: 16
+ comment: Tillståndsid för bearbetningskoncessionen
+ - name: diarynr
+ type: String
+ # XXX how come there is no UNIQUE constraint here?
+ #unique: true
+ nullable: false
+ width: 16
+ comment: Ärendenummer i diariet
+ - name: appl_date
+ type: Date
+ nullable: false
+ comment: Datum när ansökan inkom till Bergsstaten
+ - name: dec_date
+ type: Date
+ nullable: false
+ comment: Datum när bearbetningskoncessionen beviljades
+ - name: validfrom
+ type: Date
+ nullable: false
+ comment: Datum från och med när bearbetningskoncessionen började gälla
+ - name: validto
+ type: Date
+ nullable: false
+ comment: Sista dagen bearbetningskoncessionen gäller
+ - name: mineral
type: String
nullable: false
width: 254
comment: Koncessionsmineral
- - name: Applicant
+ - name: owners
type: String
nullable: false
width: 254
- comment: Sökandens namn
- - name: ApplicationDate
- type: Date
+ comment: Innehavare av bearbetningskoncessionen
+ source:
+ path: mrr/mineralrattigheter.zip
+ unar:
+ format: zip
+ import:
+ path: mineralrattigheter.gpkg
+ format: GPKG
+ layername: bearbetningskoncessioner_beviljade
+ value-map:
+ licenceid:
+ - replace: '-'
+ with: null
+ publish:
+ appr_ec:
+ fields:
+ ts: dec_date
+
+ 'mrr.markanvisningar_bk_beviljade':
+ # https://resource.sgu.se/dokument/produkter/mineralrattigheter-beskrivning.pdf
+ description: Markanvisningar till bearbetningskoncessioner, beviljade (SGU)
+ create:
+ geometry-type: MULTIPOLYGON
+ fields:
+ - name: name
+ type: String
nullable: false
- - name: DiaryNr
+ width: 254
+ comment: Namn på beviljad markanvisning
+ - name: licenceid
type: String
unique: true
+ width: 16
+ comment: Tillståndsid för markanvisningen
+ - name: diarynr
+ type: String
+ # XXX how come there is no UNIQUE constraint here?
+ #unique: true
nullable: false
width: 16
- - name: LastUpdated
+ comment: Ärendenummer i diariet
+ - name: conc_name
+ type: String
+ nullable: false
+ width: 254
+ comment: Bearbetningskoncession(er) som markanvisningen hör till
+ - name: appl_date
+ type: Date
+ nullable: false
+ comment: Datum när ansökan inkom till Bergsstaten
+ - name: dec_date
type: Date
nullable: false
- comment: Datum för senaste uppdatering
+ comment: Datum när markanvisningen beviljades
source:
- download:
- module: webmap-download-mrr
- layername: 'MRR:SE.GOV.SGU.MRR.MINERAL_APPLIED_VY'
- cache: mrr/mineral_applied.geojson
+ path: mrr/mineralrattigheter.zip
+ unar:
+ format: zip
import:
- format: GeoJSON
- layername: 'MRR:SE.GOV.SGU.MRR.MINERAL_APPLIED_VY'
- field-map:
- 'Name': Name
- 'Mineral': Mineral
- 'Applicant': Applicant
- 'Application date': ApplicationDate
- 'Diary nr': DiaryNr
- 'Last updated': LastUpdated
+ path: mineralrattigheter.gpkg
+ format: GPKG
+ layername: markanvisningar_bk_beviljade
value-map:
- 'Last updated':
- - replace: '([0-9]{4})([0-9]{2})([0-9]{2})'
- with: '{0}-{1}-{2}'
- type: regex
+ licenceid:
+ - replace: '-'
+ with: null
+ publish:
+ appr_dl:
+ fields:
+ ts: dec_date
- 'mrr:mineral_approved':
- description: Undersökningstillstånd, metallar och mineral, beviljade (SGU)
+ 'mrr.ut_metaller_industrimineral_forbud':
+ # https://resource.sgu.se/dokument/produkter/mineralrattigheter-beskrivning.pdf
+ description: Undersökningstillstånd - Metaller och industrimineral, förbud (SGU)
create:
geometry-type: MULTIPOLYGON
fields:
- - name: Name
+ - name: name
type: String
unique: true
nullable: false
width: 254
- comment: Benämning på området
- - name: Mineral
+ comment: Namn på undersökningstillstånd under förbudsår
+ - name: licenceid
+ type: String
+ unique: true
+ width: 16
+ comment: Tillståndsid för undersökningstillståndet
+ - name: diarynr
+ type: String
+ # XXX how come there is no UNIQUE constraint here?
+ #unique: true
+ nullable: false
+ width: 16
+ comment: Ärendenummer i diariet
+ - name: validfrom
+ type: Date
+ nullable: false
+ comment: Datum då undersökningstillståndets förbudsår startar
+ - name: validto
+ type: Date
+ nullable: false
+ comment: Datum då undersökningstillståndets förbudsår slutar
+ - name: mineral
type: String
nullable: false
width: 254
- comment: Koncessionsmineral
- - name: Owner
+ comment: Koncessionsmineral som eftersökts
+ - name: owners
type: String
nullable: false
width: 254
- comment: Ägares namn
- - name: LicenceID
+ comment: Innehavare av undersökningstillståndet
+ - name: prospdata_url
+ type: String
+ width: 254
+ comment: Länk till nedladdning av återrapporterad prospekteringsinformation
+ - name: prospdata_filesize_mb
+ type: Real
+ subtype: Float32
+ comment: Filstorlek i Mb för återrapporterad prospekteringsinformation
+ source:
+ path: mrr/mineralrattigheter.zip
+ unar:
+ format: zip
+ import:
+ path: mineralrattigheter.gpkg
+ format: GPKG
+ layername: ut_metaller_industrimineral_forbud
+ value-map:
+ licenceid:
+ - replace: '-'
+ with: null
+
+ 'mrr.ut_diamant_forbud':
+ # https://resource.sgu.se/dokument/produkter/mineralrattigheter-beskrivning.pdf
+ description: Undersökningstillstånd - Diamant, förbud (SGU)
+ create:
+ geometry-type: MULTIPOLYGON
+ fields:
+ - name: name
+ type: String
+ unique: true
+ nullable: false
+ width: 254
+ comment: Namn på undersökningstillstånd under förbudsår
+ - name: licenceid
type: String
unique: true
+ width: 16
+ comment: Tillståndsid för undersökningstillståndet
+ - name: diarynr
+ type: String
+ # XXX how come there is no UNIQUE constraint here?
+ #unique: true
nullable: false
- width: 8
- - name: ValidFrom
+ width: 16
+ comment: Ärendenummer i diariet
+ - name: validfrom
type: Date
nullable: false
- comment: När tillståndets giltighet börjar
- - name: ValidTo
+ comment: Datum då undersökningstillståndets förbudsår startar
+ - name: validto
type: Date
nullable: false
- comment: När tillståndets giltighet slutar
- - name: DiaryNr
+ comment: Datum då undersökningstillståndets förbudsår slutar
+ - name: mineral
+ type: String
+ nullable: false
+ width: 254
+ comment: Koncessionsmineral som eftersökts
+ - name: owners
type: String
- unique: true
- width: 16
- - name: LastUpdated
- type: Date
nullable: false
- comment: Datum för senaste uppdatering
+ width: 254
+ comment: Innehavare av undersökningstillståndet
+ - name: prospdata_url
+ type: String
+ width: 254
+ comment: Länk till nedladdning av återrapporterad prospekteringsinformation
+ - name: prospdata_filesize_mb
+ type: Real
+ subtype: Float32
+ comment: Filstorlek i Mb för återrapporterad prospekteringsinformation
source:
- download:
- module: webmap-download-mrr
- layername: 'MRR:SE.GOV.SGU.MRR.MINERAL_APPROVED_VY'
- cache: mrr/mineral_approved.geojson
+ path: mrr/mineralrattigheter.zip
+ unar:
+ format: zip
import:
- format: GeoJSON
- layername: 'MRR:SE.GOV.SGU.MRR.MINERAL_APPROVED_VY'
- field-map:
- 'Name': Name
- 'Mineral': Mineral
- 'Owner': Owner
- 'Licence id': LicenceID
- 'Valid from': ValidFrom
- 'Valid to': ValidTo
- 'Diary nr': DiaryNr
- 'Last updated': LastUpdated
+ path: mineralrattigheter.gpkg
+ format: GPKG
+ layername: ut_diamant_forbud
value-map:
- 'Diary nr':
- - replace: ''
+ licenceid:
+ - replace: '-'
with: null
- 'Last updated':
- - replace: '([0-9]{4})([0-9]{2})([0-9]{2})'
- with: '{0}-{1}-{2}'
- type: regex
-# 'mrr:mineral_expired':
-# source:
-# download:
-# module: webmap-download-mrr
-# layername: 'MRR:SE.GOV.SGU.MRR.MINERAL_EXPIRED_2'
-# cache: mrr/mineral_expired.geojson
-#
-# 'mrr:mineral_prohibited':
-# source:
-# download:
-# module: webmap-download-mrr
-# layername: 'MRR:SE.GOV.SGU.MRR.MINERAL_PROHIBITED_2'
-# cache: mrr/mineral_prohibited.geojson
-#
-# 'mrr:ogd_expired':
-# source:
-# download:
-# module: webmap-download-mrr
-# layername: 'MRR:SE.GOV.SGU.MRR.OGD_EXPIRED_2'
-# cache: mrr/ogd_expired.geojson
-# 'mrr:ogd_prohibited':
-# source:
-# download:
-# module: webmap-download-mrr
-# layername: 'MRR:SE.GOV.SGU.MRR.OGD_PROHIBITED_2'
-# cache: mrr/ogd_prohibited.geojson
-
- 'mrr:olja_gas_diamant_applied':
- description: Undersökningstillstånd, olja, gas och diamant, ansökta (SGU)
+ 'mrr.ut_metaller_industrimineral_forfallna':
+ # https://resource.sgu.se/dokument/produkter/mineralrattigheter-beskrivning.pdf
+ description: Undersökningstillstånd - Metaller och industrimineral, förfallna (SGU)
create:
geometry-type: MULTIPOLYGON
fields:
- - name: Name
+ - name: name
type: String
- unique: true
+ # XXX how come there is no UNIQUE constraint here?
+ #unique: true
nullable: false
width: 254
- comment: Benämning på området
- - name: Mineral
+ comment: Namn på förfallet undersökningstillstånd
+ - name: licenceid
+ type: String
+ unique: true
+ width: 16
+ comment: Tillståndsid för undersökningstillståndet
+ - name: diarynr
+ type: String
+ # XXX how come there is no UNIQUE constraint here?
+ #unique: true
+ nullable: false
+ width: 16
+ comment: Ärendenummer i diariet
+ - name: validfrom
+ type: Date
+ nullable: false
+ comment: Datum från och med när undersökningstillståndet började gälla
+ - name: validto
+ type: Date
+ nullable: false
+ comment: Sista dagen undersökningstillståndet gällde
+ - name: mineral
type: String
nullable: false
width: 254
- comment: Koncessionsmineral
- - name: Applicant
+ comment: Koncessionsmineral som eftersökts
+ - name: owners
type: String
nullable: false
+ width: 510
+ comment: Innehavare av undersökningstillståndet
+ - name: prospdata_url
+ type: String
width: 254
- comment: Sökandens namn
- - name: ApplicationDate
- type: Date
+ comment: Länk till nedladdning av återrapporterad prospekteringsinformation
+ - name: prospdata_filesize_mb
+ type: Real
+ subtype: Float32
+ comment: Filstorlek i Mb för återrapporterad prospekteringsinformation
+ source:
+ path: mrr/mineralrattigheter.zip
+ unar:
+ format: zip
+ import:
+ path: mineralrattigheter.gpkg
+ format: GPKG
+ layername: ut_metaller_industrimineral_forfallna
+ value-map:
+ licenceid:
+ - replace: '-'
+ with: null
+
+ 'mrr.ut_olja_gas_diamant_forfallna':
+ # https://resource.sgu.se/dokument/produkter/mineralrattigheter-beskrivning.pdf
+ description: Undersökningstillstånd - Olja, gas och diamant, förfallna (SGU)
+ create:
+ geometry-type: MULTIPOLYGON
+ fields:
+ - name: name
+ type: String
+ # XXX how come there is no UNIQUE constraint here?
+ #unique: true
nullable: false
- - name: DiaryNr
+ width: 254
+ comment: Namn på förfallet undersökningstillstånd
+ - name: licenceid
type: String
unique: true
+ width: 16
+ comment: Tillståndsid för undersökningstillståndet
+ - name: diarynr
+ type: String
+ # XXX how come there is no UNIQUE constraint here?
+ #unique: true
nullable: false
width: 16
- - name: LastUpdated
+ comment: Ärendenummer i diariet
+ - name: validfrom
+ type: Date
+ nullable: false
+ comment: Datum från och med när undersökningstillståndet började gälla
+ - name: validto
type: Date
nullable: false
- comment: Datum för senaste uppdatering
+ comment: Sista dagen undersökningstillståndet gällde
+ - name: mineral
+ type: String
+ nullable: false
+ width: 254
+ comment: Koncessionsmineral som eftersökts
+ - name: owners
+ type: String
+ nullable: false
+ width: 510
+ comment: Innehavare av undersökningstillståndet
+ - name: prospdata_url
+ type: String
+ width: 254
+ comment: Länk till nedladdning av återrapporterad prospekteringsinformation
+ - name: prospdata_filesize_mb
+ type: Real
+ subtype: Float32
+ comment: Filstorlek i Mb för återrapporterad prospekteringsinformation
source:
- download:
- module: webmap-download-mrr
- layername: 'MRR:SE.GOV.SGU.MRR.OLJA_GAS_DIAMANT_APPLIED_VY'
- cache: mrr/olja_gas_diamant_applied.geojson
+ path: mrr/mineralrattigheter.zip
+ unar:
+ format: zip
import:
- format: GeoJSON
- layername: 'MRR:SE.GOV.SGU.MRR.OLJA_GAS_DIAMANT_APPLIED_VY'
- field-map:
- 'Name': Name
- 'Mineral': Mineral
- 'Applicant': Applicant
- 'Application date': ApplicationDate
- 'Diary nr': DiaryNr
- 'Last updated': LastUpdated
+ path: mineralrattigheter.gpkg
+ format: GPKG
+ layername: ut_olja_gas_diamant_forfallna
value-map:
- 'Last updated':
- - replace: '([0-9]{4})([0-9]{2})([0-9]{2})'
- with: '{0}-{1}-{2}'
- type: regex
+ licenceid:
+ - replace: '-'
+ with: null
- 'mrr:olja_gas_diamant_approved':
- description: Undersökningstillstånd, olja, gas och diamant, beviljade (SGU)
+ 'mrr.bearbetningskoncessioner_forfallna':
+ # https://resource.sgu.se/dokument/produkter/mineralrattigheter-beskrivning.pdf
+ description: Bearbetningskoncessioner, förfallna (SGU)
create:
geometry-type: MULTIPOLYGON
fields:
- - name: Name
+ - name: name
type: String
unique: true
nullable: false
width: 254
- comment: Benämning på området
- - name: Mineral
+ comment: Namn på förfallen bearbetningskoncession
+ - name: licenceid
+ type: String
+ # XXX how come there is no UNIQUE constraint here?
+ #unique: true
+ width: 16
+ comment: Tillståndsid för undersökningstillståndet
+ - name: diarynr
+ type: String
+ # XXX how come there is no UNIQUE constraint here?
+ #unique: true
+ nullable: false
+ width: 16
+ comment: Ärendenummer i diariet
+ - name: appl_date
+ type: Date
+ comment: Datum när ansökan inkom till Bergsstaten
+ - name: mineral
type: String
nullable: false
width: 254
comment: Koncessionsmineral
- - name: Owner
+ - name: owners
type: String
nullable: false
width: 254
- comment: Ägares namn
- - name: LicenceID
+ comment: Innehavare av bearbetningskoncessionen
+ source:
+ path: mrr/mineralrattigheter.zip
+ unar:
+ format: zip
+ import:
+ path: mineralrattigheter.gpkg
+ format: GPKG
+ layername: bearbetningskoncessioner_forfallna
+ value-map:
+ licenceid:
+ - replace: '-'
+ with: null
+
+ 'nvk.riksintresse_naturvard':
+ description: Riksintresse naturvård
+ create:
+ geometry-type: MULTIPOLYGON
+ fields:
+ - name: SKYDD
type: String
- unique: true
+ width: 64
nullable: false
- width: 8
- - name: ValidFrom
- type: Date
+ - name: AMNESOMRAD
+ type: String
+ width: 64
+ nullable: false
+ - name: NAMN
+ type: String
+ width: 127
+ nullable: false
+ - name: BESKRIVNIN
+ type: String
+ width: 254
nullable: false
- comment: När tillståndets giltighet börjar
- - name: ValidTo
+ - name: LAGRUM
+ type: String
+ width: 64
+ nullable: false
+ - name: BESLUTSDAT
type: Date
nullable: false
- comment: När tillståndets giltighet slutar
- - name: DiaryNr
+ - name: ORGINALID
+ type: String
+ width: 16
+ # XXX how come there is no UNIQUE constraint here?
+ unique: false
+ nullable: false
+ - name: RIKSID
+ type: Integer
+ # XXX how come there is no UNIQUE constraint here?
+ unique: false
+ nullable: false
+ source:
+ path: nvk/RI_Naturvard.zip
+ unar:
+ format: zip
+ patterns:
+ - 'RIKSINTRESSE_NATURVARD.*'
+ import:
+ path: 'RIKSINTRESSE_NATURVARD.shp'
+ format: ESRI Shapefile
+ layername: RIKSINTRESSE_NATURVARD
+ publish: naturvard
+
+ 'nvk.riksintresse_friluftsliv':
+ description: Riksintresse friluftsliv
+ create:
+ geometry-type: MULTIPOLYGON
+ fields:
+ - name: SKYDD
+ type: String
+ width: 64
+ nullable: false
+ - name: OMRADESNR
type: String
+ width: 16
unique: true
+ nullable: false
+ - name: AMNESOMR
+ type: String
width: 16
- - name: LastUpdated
+ nullable: false
+ - name: NAMN
+ type: String
+ width: 127
+ nullable: false
+ - name: LANK_VARDE
+ type: String
+ width: 127
+ nullable: false
+ - name: BESLDATUM
type: Date
+ - name: LAGRUM
+ type: String
+ width: 64
nullable: false
- comment: Datum för senaste uppdatering
+ - name: ARENDENR
+ type: String
+ width: 11
+ nullable: false
+ - name: LANK_BESLU
+ type: String
+ width: 127
+ nullable: false
+ - name: AKTIVITET
+ type: String
+ width: 127
+ - name: NATURTYP
+ type: String
+ width: 127
+ - name: AREA_LAND_
+ # XXX convert to m²?
+ type: Real
+ comment: Areal land i hektar
+ - name: AREA_VATTE
+ # XXX convert to m²?
+ type: Real
+ comment: Areal vatten i hektar
source:
- download:
- module: webmap-download-mrr
- layername: 'MRR:SE.GOV.SGU.MRR.OLJA_GAS_DIAMANT_APPROVED_VY'
- cache: mrr/olja_gas_diamant_approved.geojson
+ path: nvk/RI_Friluftsliv.zip
+ unar:
+ format: zip
+ patterns:
+ - 'RIKSINTRESSE_FRILUFTSLIV.*'
import:
- format: GeoJSON
- layername: 'MRR:SE.GOV.SGU.MRR.OLJA_GAS_DIAMANT_APPROVED_VY'
+ path: 'RIKSINTRESSE_FRILUFTSLIV.shp'
+ format: ESRI Shapefile
+ layername: RIKSINTRESSE_FRILUFTSLIV
+ publish: friluftsliv
+
+ 'lst.riksintresse_rorligt_friluftsliv':
+ description: Rörligt friluftsliv (MB 4 kap 1 och 2 §§)
+ create:
+ geometry-type: MULTIPOLYGON
+ fields:
+ - name: ORIGINALID
+ type: String
+ width: 16
+ - name: NAMN
+ type: String
+ width: 64
+ - name: BESKRIVNIN
+ type: String
+ width: 254
+ - name: METODBESKR
+ type: String
+ width: 254
+ - name: TILLKDATUM
+ type: Date
+ - name: REVDATUM
+ type: Date
+ - name: ANM
+ type: String
+ width: 254
+ comment: Anmärkning
+ - name: OBJEKTLANK
+ type: String
+ width: 254
+ - name: REFERENS
+ type: String
+ width: 254
+ source:
+ path: lst/lst.LST_RI_Rorligt_friluftsliv_MB4kap2.zip
+ unar:
+ format: zip
+ patterns:
+ - 'lst.LST_RI_Rorligt_friluftsliv_MB4kap2.*'
+ import:
+ path: 'lst.LST_RI_Rorligt_friluftsliv_MB4kap2.shp'
+ format: ESRI Shapefile
+ layername: lst.LST_RI_Rorligt_friluftsliv_MB4kap2
+ publish: rorligt_friluftsliv
+
+ 'lst.riksintresse_obruten_kust':
+ description: Obruten kust (MB 4 kap 3 §)
+ create:
+ geometry-type: MULTIPOLYGON
+ fields:
+ - name: ORIGINALID
+ type: String
+ width: 16
+ - name: NAMN
+ type: String
+ width: 64
+ - name: BESKRIVNIN
+ type: String
+ width: 254
+ - name: METODBESKR
+ type: String
+ width: 254
+ - name: TILLKDATUM
+ type: Date
+ - name: REVDATUM
+ type: Date
+ - name: ANM
+ type: String
+ width: 254
+ comment: Anmärkning
+ - name: OBJTYP
+ type: String
+ width: 254
+ - name: OBJEKTLANK
+ type: String
+ width: 254
+ - name: REFERENS
+ type: String
+ width: 254
+ source:
+ path: lst/lst.LST_RI_Obruten_kust_MB4kap3.zip
+ unar:
+ format: zip
+ patterns:
+ - 'lst.LST_RI_Obruten_kust_MB4kap3.*'
+ import:
+ path: 'lst.LST_RI_Obruten_kust_MB4kap3.shp'
+ format: ESRI Shapefile
+ layername: lst.LST_RI_Obruten_kust_MB4kap3
+ publish: obruten_kust
+
+ 'lst.riksintresse_obrutet_fjall':
+ description: Obrutet fjäll (MB 4 kap 5 §)
+ create:
+ geometry-type: MULTIPOLYGON
+ fields:
+ - name: ORIGINALID
+ type: String
+ width: 16
+ unique: true
+ - name: NAMN
+ type: String
+ width: 64
+ nullable: false
+ - name: BESKRIVNIN
+ type: String
+ width: 254
+ - name: METODBESKR
+ type: String
+ width: 254
+ - name: TILLKDATUM
+ type: Date
+ - name: REVDATUM
+ type: Date
+ - name: OBJEKTLANK
+ type: String
+ width: 254
+ - name: REFERENS
+ type: String
+ width: 254
+ source:
+ path: lst/lst.Lst_RI_Obrutet_fjall_MB4kap5.zip
+ unar:
+ format: zip
+ patterns:
+ - 'lst.Lst_RI_Obrutet_fjall_MB4kap5.*'
+ import:
+ path: 'lst.Lst_RI_Obrutet_fjall_MB4kap5.shp'
+ format: ESRI Shapefile
+ layername: lst.Lst_RI_Obrutet_fjall_MB4kap5
+ publish: obrutet_fjall
+
+ 'lst.riksintresse_skyddade_vattendrag':
+ description: Skyddade vattendrag (MB 4 kap 6 §)
+ create:
+ geometry-type: MULTIPOLYGON
+ fields:
+ - name: ORIGINALID
+ type: String
+ width: 16
+ unique: true
+ - name: NAMN
+ type: String
+ width: 64
+ nullable: false
+ - name: BESKRIVNIN
+ type: String
+ width: 254
+ - name: METODBESKR
+ type: String
+ width: 254
+ - name: TILLKDATUM
+ type: Date
+ - name: REVDATUM
+ type: Date
+ - name: ANM
+ type: String
+ width: 254
+ comment: Anmärkning
+ - name: DIG_SKALA
+ type: Integer
+ - name: OBJEKTLANK
+ type: String
+ width: 254
+ - name: REFERENS
+ type: String
+ width: 254
+ source:
+ path: lst/lst.LST_RI_Skyddade_vattendrag_MB4kap6.zip
+ unar:
+ format: zip
+ patterns:
+ - 'lst.LST_RI_Skyddade_vattendrag_MB4kap6.*'
+ import:
+ path: 'lst.LST_RI_Skyddade_vattendrag_MB4kap6.shp'
+ format: ESRI Shapefile
+ layername: lst.LST_RI_Skyddade_vattendrag_MB4kap6
+ map-value:
+ DIG_SKALA:
+ - replace: 0
+ width: null
+ publish: skyddade_vattendrag
+
+ 'svk.ledningar':
+ description: Kraftledningar (befintliga)
+ create:
+ geometry-type: MULTILINESTRING
+ fields:
+ - name: Placement
+ type: String
+ width: 32
+ - name: Voltage
+ # XXX convert to V?
+ type: Integer
+ source:
+ path: svk/SVK_STAMNAT.zip
+ unar:
+ format: zip
+ patterns:
+ - 'SVK_LEDNINGAR.*'
+ import:
+ path: 'SVK_LEDNINGAR.shp'
+ format: ESRI Shapefile
+ layername: SVK_LEDNINGAR
field-map:
- 'Name': Name
- 'Mineral': Mineral
- 'Owner': Owner
- 'Licence id': LicenceID
- 'Valid from': ValidFrom
- 'Valid to': ValidTo
- 'Diary nr': DiaryNr
- 'Last updated': LastUpdated
+ 'FÖRLÄGGN': Placement
+ 'SPÄNNING': Voltage
value-map:
- 'Diary nr':
- - replace: ''
+ 'SPÄNNING':
+ - replace: 'Okänd'
with: null
- 'Last updated':
- - replace: '([0-9]{4})([0-9]{2})([0-9]{2})'
- with: '{0}-{1}-{2}'
- type: regex
+ - replace: '0'
+ with: null
+ publish: ledningar
+
+ 'svk.stolpar':
+ description: Stolpar (befintliga)
+ create:
+ geometry-type: POINTZ
+ fields: []
+ source:
+ path: svk/SVK_STAMNAT.zip
+ unar:
+ format: zip
+ patterns:
+ - 'SVK_STOLPAR.*'
+ import:
+ path: 'SVK_STOLPAR.shp'
+ format: ESRI Shapefile
+ layername: SVK_STOLPAR
+ publish: stolpar
+
+ 'svk.stationsomraden':
+ description: Stationsomraden
+ create:
+ geometry-type: MULTIPOLYGONZ
+ fields: []
+ source:
+ path: svk/SVK_STAMNAT.zip
+ unar:
+ format: zip
+ patterns:
+ - 'STATIONSOMRÅDEN.*'
+ import:
+ path: 'STATIONSOMRÅDEN.shp'
+ format: ESRI Shapefile
+ layername: STATIONSOMRÅDEN
+ publish:
+ stationer:
+ transform-geometry: centroid
+ maxzoom: 6
+ stationsomraden:
+ target_name: stationer
+ minzoom: 7
- 'mrr:torvkoncessioner':
- description: Torvkoncessioner (SGU)
+ 'svk.transmissionsnatsprojekt':
+ description: Transmissionsnätsprojekt
+ create:
+ geometry-type: MULTILINESTRING
+ fields:
+ - name: Name
+ type: String
+ width: 254
+ - name: Voltage
+ # XXX convert to V?
+ type: Integer
+ - name: Url
+ type: String
+ width: 254
+ import:
+ path: custom/svk/transmissionsnatsprojekt.geojson
+ format: GeoJSON
+ field-map:
+ 'name': Name
+ 'voltage': Voltage
+ 'url': Url
+ publish: transmissionsnatsprojekt
+
+ 'misc.gigafactories':
+ description: Stora industrisatsningar
create:
geometry-type: MULTIPOLYGON
fields:
- name: Name
type: String
+ width: 254
+ - name: Url
+ type: String
+ width: 254
+ import:
+ path: custom/gigafactories.geojson
+ format: GeoJSON
+ field-map:
+ 'name': Name
+ 'url': Url
+ publish:
+ gigafactories_points:
+ transform-geometry: centroid
+ target_name: gigafactories
+ maxzoom: 5
+ gigafactories:
+ minzoom: 6
+
+ 'misc.dammar':
+ description: Dammar
+ create:
+ # https://www.smhi.se/polopoly_fs/1.34541!/dammprod%202013_3%2C%20beskrivning%2C%20SVAR2012_2.pdf
+ geometry-type: POINT
+ fields:
+ - name: DammID
+ type: String
+ subtype: UUID
+ #width: 36
unique: true
nullable: false
- width: 254
- comment: Benämning på området
- - name: Mineral
+ comment: Dammenhetens identitet
+ - name: LST_OBJID
+ type: String
+ width: 32
+ comment: Länsstyrelsens objektid
+ - name: Datum
+ type: Date
+ nullable: false
+ comment: Datum för registrering av dammenheten i SVAR
+ - name: DNamn
+ type: String
+ width: 64
+ comment: Dammenhetens namn
+ - name: Status
+ type: Integer
+ subtype: Int16
+ nullable: false
+ - name: Regleringstyp
+ type: Integer
+ subtype: Int16
+ nullable: false
+ - name: Konstruktion
+ type: Integer
+ subtype: Int16
+ nullable: false
+ - name: ByggAr
+ type: Integer
+ subtype: Int16
+ comment: År för första byggnation av dammenheten
+ - name: DammHojd
+ type: Real
+ subtype: Float32
+ comment: Dammdelens högsta höjd (m)
+ - name: KronLangd
+ type: Real
+ subtype: Float32
+ comment: Krönlängd (m)
+ - name: Fiskvag
+ type: Integer
+ subtype: Int16
+ nullable: false
+ comment: Förekomst och typ av fiskväg vid dammenheten
+ - name: FiskvagByggAr
+ type: Integer
+ subtype: Int16
+ comment: Byggår fiskväg
+ - name: Fiskavledare
+ type: Integer
+ subtype: Int16
+ comment: Finns fiskavledare till fiskvägen
+ - name: Vandringshinder
+ type: Integer
+ subtype: Bool
+ nullable: false
+ comment: Om dammenheten utgör ett vandringshinder
+ - name: HARO
+ type: Integer
+ nullable: false
+ comment: Huvudavrinningsområdesnummer
+ - name: Vattendistrikt
+ type: String
+ width: 10
+ nullable: false
+ comment: Huvudavrinningsområdesnummer
+ - name: inrapp_lst
+ type: String
+ width: 32
+ nullable: false
+ comment: Den Länsstyrelse dammenheten är inrapporterad av
+ - name: eu_cd
+ type: String
+ width: 32
+ comment: Vattenförekomstidentitet
+ - name: vf_typ
+ type: String
+ width: 1
+ comment: Typ av vattenförekomst
+ - name: vy_eucd
+ type: String
+ width: 32
+ comment: Vattenförekomstidentitet för eventuell vattenyta kopplat till dammanläggning
+ - name: vy_vf_typ
+ type: String
+ width: 1
+ comment: Typ av vattenförekomst för eventuell vattenyta kopplat till dammanläggning
+ - name: DammanlID
+ type: String
+ width: 64
+ comment: Identitet för eventuell dammanläggning dammenheten är kopplad till
+ - name: Namn
+ type: String
+ width: 64
+ comment: Dammanläggningens namn
+ - name: Verksamhet
+ type: Integer
+ subtype: Int16
+ - name: OmbyggAr
+ type: Integer
+ subtype: Int16
+ comment: År för idrifttagande av anläggning i dess nuvarande skepnad
+ - name: DG
+ type: Real
+ subtype: Float32
+ comment: Högsta dämningsgräns (m) enligt tillstånd
+ - name: SG
+ type: Real
+ subtype: Float32
+ comment: Högsta dämningsgräns (m) enligt tillstånd
+ - name: HojdSys
+ type: Integer
+ subtype: Int16
+ comment: Höjdsystem som DG och SG räknats i
+ - name: MY
+ type: Real
+ comment: Magasinsyta (km²) vid angiven DG
+ - name: RV
+ type: Real
+ comment: Reglerbar volym (milj. m³)
+ - name: Kommentar
type: String
width: 254
- comment: Koncessionsmineral
- - name: Owner
+ comment: Inrapporterade kommentarer från Länsstyrelserna
+ - name: XX_Distance
+ type: Real
+ comment: Distance to the closest SvK station or production dam
+ source:
+ #download: 'https://opendata-view.smhi.se/SMHI_vatten_DamOrWeir/HY.PhysicalWaters.ManMadeObject/ows?service=WFS&request=GetFeature&typeNames=HY.PhysicalWaters.ManMadeObject&outputFormat=SHAPE-ZIP&srsName=EPSG:3006&format_options=charset:utf-8'
+ path: custom/HY_PhysicalWaters_ManMadeObject.zip
+ unar:
+ format: zip
+ patterns:
+ - 'HY_PhysicalWaters_ManMadeObject.*'
+ import:
+ path: 'HY_PhysicalWaters_ManMadeObject.shp'
+ format: ESRI Shapefile
+ layername: HY_PhysicalWaters_ManMadeObject
+ field-map:
+ dammid: DammID
+ lst_objid: LST_OBJID
+ datum: Datum
+ dnamn: DNamn
+ status: Status
+ regl_typ: Regleringstyp
+ konstr: Konstruktion
+ byggar: ByggAr
+ dammhojd: DammHojd
+ kron: KronLangd
+ fiskvag: Fiskvag
+ fbygg: FiskvagByggAr
+ fiskavl: Fiskavledare
+ vhinder: Vandringshinder
+ haro: HARO
+ rbd: Vattendistrikt
+ inrapp_lst: inrapp_lst
+ eu_cd: eu_cd
+ vf_typ: vf_typ
+ vy_eucd: vy_eucd
+ vy_vf_typ: vy_vf_typ
+ dammanlid: DammanlID
+ namn: Namn
+ verksmht: Verksamhet
+ ombyggar: OmbyggAr
+ dg: DG
+ sg: SG
+ hojd_sys: HojdSys
+ my: MY
+ rv: RV
+ kommentar: Kommentar
+ XXdistance: XX_Distance
+ value-map:
+ dammid:
+ - replace: '\{([0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12})\}'
+ with: '{0}'
+ type: regex
+ byggar:
+ - replace: 0
+ with: null
+ dammhojd:
+ - replace: 0
+ with: null
+ kron:
+ - replace: 0
+ with: null
+ fbygg:
+ - replace: 0
+ with: null
+ vhinder:
+ - replace: 2
+ with: 0
+ ombyggar:
+ - replace: 0
+ with: null
+ dg:
+ - replace: 0
+ with: null
+ sg:
+ - replace: 0
+ with: null
+ my:
+ - replace: 0
+ with: null
+ rv:
+ - replace: 0
+ with: null
+ publish:
+ dammar:
+ where: |
+ "Status" = 1 AND "XX_Distance" BETWEEN 0 AND 2000
+
+ 'sks.nyckelbiotop':
+ description: Nyckelbiotoper - Skogsstyrelsen
+ create:
+ geometry-type: MULTIPOLYGON
+ fields:
+ # https://skogsstyrelsen.se/globalassets/sjalvservice/karttjanster/geodatatjanster/produktbeskrivningar/nyckelbiotoper---produktbeskrivning.pdf
+ - name: Beteckn
+ type: String
+ width: 12
+ unique: true
+ nullable: false
+ comment: Ärendebeteckning
+ - name: Objnamn
type: String
+ width: 62
+ comment: Namn på objektet
+ - name: Datinv
+ type: Date
nullable: false
+ comment: Datum för fältinventering
+ - name: Biotop1
+ type: String
+ width: 62
+ - name: Biotop2
+ type: String
+ width: 62
+ - name: Biotop3
+ type: String
+ width: 62
+ - name: Beskrivn1
+ type: String
+ width: 62
+ - name: Beskrivn2
+ type: String
+ width: 62
+ - name: Beskrivn3
+ type: String
+ width: 62
+ - name: Beskrivn4
+ type: String
+ width: 62
+ - name: Beskrivn5
+ type: String
+ width: 62
+ - name: Beskrivn6
+ type: String
+ width: 62
+ - name: Beskrivn7
+ type: String
+ width: 62
+ - name: Beskrivn8
+ type: String
+ width: 62
+ - name: Url
+ type: String
width: 254
- comment: Ägares namn
- - name: ValidFrom
+ nullable: false
+ comment: Länk till visningsformulär i Skogens Pärlor
+ source:
+ path: sks/sksNyckelbiotoper_gpkg.zip
+ unar:
+ format: zip
+ import:
+ path: sksNyckelbiotoper.gpkg
+ format: GPKG
+ layername: NyckelbiotopYta
+ value-map:
+ Biotop1:
+ - replace: 'saknas'
+ with: null
+ Biotop2:
+ - replace: 'saknas'
+ with: null
+ Biotop3:
+ - replace: 'saknas'
+ with: null
+ Beskrivn1:
+ - replace: 'saknas'
+ with: null
+ Beskrivn2:
+ - replace: 'saknas'
+ with: null
+ Beskrivn3:
+ - replace: 'saknas'
+ with: null
+ Beskrivn4:
+ - replace: 'saknas'
+ with: null
+ Beskrivn5:
+ - replace: 'saknas'
+ with: null
+ Beskrivn6:
+ - replace: 'saknas'
+ with: null
+ Beskrivn7:
+ - replace: 'saknas'
+ with: null
+ Beskrivn8:
+ - replace: 'saknas'
+ with: null
+ publish: nyckelbiotop
+
+ 'sks.nyckelbiotop_storskogsbruk':
+ description: Nyckelbiotoper - storskogsbruket
+ create:
+ geometry-type: MULTIPOLYGON
+ fields:
+ # https://skogsstyrelsen.se/globalassets/sjalvservice/karttjanster/geodatatjanster/produktbeskrivningar/storskogsbrukets-nyckelbiotoper---produktbeskrivning.pdf
+ - name: objectid
+ type: Integer
+ unique: true
+ nullable: false
+ comment: Unik identitet
+ - name: Org
+ type: String
+ width: 62
+ nullable: false
+ comment: Namn på Organisation som gjort inventeringen
+ - name: InkomDatum
type: Date
nullable: false
- comment: När tillståndets giltighet börjar
- - name: ValidTo
+ comment: Datum då data inkommit till Skogsstyrelsen
+ - name: Url
+ type: String
+ width: 254
+ nullable: false
+ comment: Länk till Skogens Pärlors visningsformulär
+ source:
+ path: sks/sksStorskogsbrNyckelb_gpkg.zip
+ unar:
+ format: zip
+ import:
+ path: sksStorskogsbrNyckelb.gpkg
+ format: GPKG
+ layername: StorskogsbuketsNyckelbiotop
+ publish: nyckelbiotop_storskogsbruk
+
+ 'sks.naturvarde':
+ description: Objekt med naturvärden - Skogsstyrelsen
+ create:
+ geometry-type: MULTIPOLYGON
+ fields:
+ # https://skogsstyrelsen.se/globalassets/sjalvservice/karttjanster/geodatatjanster/produktbeskrivningar/objekt-med-naturvarden---produktbeskrivning.pdf
+ - name: ObjectId
+ type: Integer
+ unique: true
+ nullable: false
+ comment: Unik identitet
+ - name: Beteckn
+ type: String
+ width: 12
+ unique: true
+ nullable: false
+ comment: Ärendebeteckning
+ - name: Objnamn
+ type: String
+ width: 62
+ comment: Namn på objektet
+ - name: Datinv
type: Date
nullable: false
- comment: När tillståndets giltighet slutar
- - name: DiaryNr
+ comment: Datum för fältinventering
+ - name: Biotop1
+ type: String
+ width: 62
+ - name: Biotop2
+ type: String
+ width: 62
+ - name: Biotop3
+ type: String
+ width: 62
+ - name: Beskrivn1
+ type: String
+ width: 62
+ - name: Beskrivn2
+ type: String
+ width: 62
+ - name: Beskrivn3
+ type: String
+ width: 62
+ - name: Url
type: String
+ width: 254
+ nullable: false
+ comment: Länk till visningsformulär i Skogens Pärlor
+ source:
+ path: sks/sksNaturvarden_gpkg.zip
+ unar:
+ format: zip
+ import:
+ path: sksNaturvarden.gpkg
+ format: GPKG
+ layername: NaturvardeYta
+ value-map:
+ Biotop1:
+ - replace: saknas
+ with: null
+ Biotop2:
+ - replace: saknas
+ with: null
+ Biotop3:
+ - replace: saknas
+ with: null
+ Beskrivn1:
+ - replace: saknas
+ with: null
+ Beskrivn2:
+ - replace: saknas
+ with: null
+ Beskrivn3:
+ - replace: saknas
+ with: null
+ publish: naturvarde_sks
+
+ 'sks.sumpskog':
+ description: Sumpskogar
+ create:
+ geometry-type: MULTIPOLYGON
+ fields:
+ # https://skogsstyrelsen.se/globalassets/sjalvservice/karttjanster/geodatatjanster/produktbeskrivningar/sumpskog---produktbeskrivning.pdf
+ - name: OBJECTID
+ type: Integer
unique: true
- width: 16
- - name: LastUpdated
+ nullable: false
+ comment: Unik identitet
+ - name: Namn
+ type: String
+ width: 62
+ comment: Objektnamn
+ - name: Hydrtext
+ type: String
+ width: 62
+ comment: Hydrologisk text, ex. kärrskog, mosseskog
+ - name: Tradtext
+ type: String
+ width: 62
+ nullable: false
+ comment: Trädslag
+ - name: Delklass
+ type: String
+ width: 62
+ comment: Klass på delobjektet
+ - name: Klassu
+ type: String
+ width: 62
+ comment: Klass på objektet
+ - name: Lovandel
+ type: String
+ width: 62
+ comment: Lövandel
+ - name: Krontakn
+ type: String
+ width: 62
+ comment: Krontäckning
+ - name: Huggklas
+ type: String
+ width: 62
+ comment: Huggningsklass
+ - name: Andelva
+ type: String
+ width: 62
+ comment: Andel öppet vatten
+ - name: Ingrepp
+ type: String
+ width: 62
+ comment: Ingrepp på delobjekt (max 4)
+ - name: Ingrpavv
+ type: String
+ width: 62
+ comment: Grad av påverkan på delobjekt (max 4)
+ - name: Objnyck
+ type: String
+ width: 62
+ comment: Nyckelord på objektnivå
+ - name: Delnyck
+ type: String
+ width: 62
+ comment: Nyckelord på delobjektsnivå
+ - name: Flygar
+ type: Integer
+ subtype: Int16
+ comment: Flygbildsår
+ - name: Faltdat
+ type: Date
+ comment: Faltdat
+ - name: Invtekn
+ type: String
+ width: 62
+ nullable: false
+ comment: Inventeringsteknik
+ - name: Invdat
type: Date
nullable: false
- comment: Datum för senaste uppdatering
+ comment: Inventeringdatum
+ - name: Ansvmynd
+ type: String
+ width: 62
+ nullable: false
+ comment: Ansvarig myndighet
+ - name: Url
+ type: String
+ width: 252
+ nullable: false
+ comment: Länk till Skogens pärlors formulär för objektet
source:
- download:
- module: webmap-download-mrr
- layername: 'MRR:SE.GOV.SGU.MRR.TORVKONCESSIONER_VY'
- cache: mrr/torvkoncessioner.geojson
+ path: sks/sksSumpskogar_gpkg.zip
+ unar:
+ format: zip
import:
- format: GeoJSON
- layername: 'MRR:SE.GOV.SGU.MRR.TORVKONCESSIONER_VY'
- field-map:
- 'Name': Name
- 'Mineral': Mineral
- 'Owner': Owner
- 'Valid from': ValidFrom
- 'Valid to': ValidTo
- 'Diary nr': DiaryNr
- 'Last updated': LastUpdated
+ path: sksSumpskogar.gpkg
+ format: GPKG
+ layername: SumpskogYta
+ rstrip-strings: true
value-map:
- 'Mineral':
- - replace: ''
+ Namn:
+ - replace: 'Namn ej angivet'
+ with: null
+ Klassu:
+ - replace: 'saknas'
+ with: null
+ Krontakn:
+ - replace: 'saknas'
+ with: null
+ Huggklas:
+ - replace: 'saknas'
+ with: null
+ Andelva:
+ - replace: 'saknas'
+ with: null
+ Ingrepp:
+ - replace: 'saknas'
with: null
- 'Diary nr':
+ Ingrpavv:
+ - replace: 'saknas'
+ with: null
+ Objnyck:
+ - replace: 'saknas'
+ with: null
+ Delnyck:
+ - replace: 'saknas'
+ with: null
+ Flygar:
+ - replace: 'saknas'
+ with: null
+ publish: sumpskog
+
+ 'sks.atervatningsavtal':
+ description: Återvätningsavtal
+ create:
+ geometry-type: MULTIPOLYGON
+ fields:
+ # https://skogsstyrelsen.se/globalassets/sjalvservice/karttjanster/geodatatjanster/produktbeskrivningar/atervatningsavtal---produktbeskrivning.pdf
+ - name: Uuid
+ type: String
+ subtype: UUID
+ #width: 36
+ unique: true
+ nullable: false
+ comment: Unikt ID
+ - name: Beteckn
+ type: String
+ width: 12
+ nullable: false
+ comment: Ärendebeteckning
+ - name: ArendeAr
+ type: Integer
+ subtype: Int16
+ nullable: false
+ comment: Ärendeår
+ - name: AvtalatDatum
+ type: Date
+ comment: Avtalat datum
+ - name: Url
+ type: String
+ width: 252
+ comment: Länk till Skogens pärlors formulär för objektet
+ source:
+ path: sks/sksAtervatningYta_gpkg.zip
+ unar:
+ format: zip
+ import:
+ path: sksAtervatningYta.gpkg
+ format: GPKG
+ layername: AtervatningYta
+ value-map:
+ Url:
- replace: ''
with: null
- 'Last updated':
- - replace: '([0-9]{4})([0-9]{2})([0-9]{2})'
- with: '{0}-{1}-{2}'
- type: regex
+ publish: atervatningsavtal
+
+ 'nvk.kskog':
+ description: "Sannolikt och potentiell kontinuitetsskog (preciserad 2024)"
+ type: raster
+ source:
+ path: nvk/Sannolikt_och_potentiell_kontinuitetsskog_BorealRegion_2024.zip
+ unar:
+ format: zip
+ patterns:
+ - 'Sannolikt_och_potentiell_kontinuitetsskog_BorealRegion_2024/Sannolikt_och_potentiell_kontinuitetsskog_BorealRegion_2024.*'
+ import:
+ path: Sannolikt_och_potentiell_kontinuitetsskog_BorealRegion_2024/Sannolikt_och_potentiell_kontinuitetsskog_BorealRegion_2024.tif
+ format: GTiff
+ publish:
+ 1: "Sannolikt kontinuitetsskog (preciserad)"
+ 2: "Sannolikt påverkad kontinuitetsskog (preciserad)"
+ 3: "Sannolikt kontinuitetsskog i fjällen (grövre precisering)"
+ 4: "Potentiell kontinuitetsskog (2015)"
diff --git a/export_mvt.py b/export_mvt.py
new file mode 100644
index 0000000..b56fba1
--- /dev/null
+++ b/export_mvt.py
@@ -0,0 +1,619 @@
+#!/usr/bin/python3
+
+#----------------------------------------------------------------------
+# Backend utilities for the Klimatanalys Norr project (create MVT tiles)
+# Copyright © 2024-2025 Guilhem Moulin <info@guilhem.se>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+#----------------------------------------------------------------------
+
+# pylint: disable=invalid-name, missing-module-docstring, fixme
+
+from os import O_RDONLY, O_WRONLY, O_CREAT, O_EXCL, O_TRUNC, O_CLOEXEC, O_DIRECTORY, F_OK
+import os
+from errno import EAGAIN
+import json
+import logging
+from pathlib import Path
+import shutil
+import tempfile
+from typing import Any, Iterator, Optional
+from time import monotonic as time_monotonic, time_ns
+
+import brotli
+from osgeo import gdal, ogr, osr
+
+from common import BadConfiguration, escape_identifier, format_bytes, format_time
+from common_gdal import (
+ getExtent,
+ getSRS,
+ getSpatialFilterFromGeometry,
+ getEscapedTableName,
+ executeSQL,
+)
+from rename_exchange import rename_exchange
+
+def parseTilingScheme(scheme : list[Any]) -> tuple[osr.SpatialReference, ogr.Geometry|None]:
+ """Get SRS end extent from MVT tiling scheme (crs, tile_origin_upper_left_x,
+ tile_origin_upper_left_y, tile_dimension_zoom_0)."""
+ if scheme is None:
+ srs = osr.SpatialReference()
+ # standard WebMercator tiling scheme
+ srs.ImportFromEPSG(3857)
+ return srs, None
+ if not isinstance(scheme, list) or len(scheme) != 4:
+ raise BadConfiguration(f'Invalid tiling scheme: {scheme}')
+ srs = getSRS(scheme[0])
+ if not srs.IsProjected():
+ raise RuntimeError('SRS is not projected: ' + srs.ExportToPrettyWkt())
+
+ minX = minY = maxX = maxY = None
+ for i in range(srs.GetAxesCount()):
+ orientation = srs.GetAxisOrientation('PROJCS', i)
+ if orientation == osr.OAO_North:
+ assert minY is None and maxY is None
+ maxY = scheme[2]
+ minY = maxY - scheme[3]
+ elif orientation == osr.OAO_South:
+ assert minY is None and maxY is None
+ minY = scheme[2]
+ maxY = minY + scheme[3]
+ elif orientation == osr.OAO_East:
+ assert minX is None and maxX is None
+ minX = scheme[1]
+ maxX = minX + scheme[3]
+ elif orientation == osr.OAO_West:
+ assert minX is None and maxX is None
+ maxX = scheme[1]
+ minX = maxX - scheme[3]
+ if minX is None or minY is None or maxX is None or maxY is None:
+ raise RuntimeError('Unknown axes meaning for ' + srs.ExportToPrettyWkt())
+ extent = (minX, minY, maxX, maxY)
+ logging.debug('Parsed tiling scheme: extent=%s, srs="%s"', str(extent), srs.GetName())
+ return srs, getExtent(extent, srs=srs)
+
+# pylint: disable-next=dangerous-default-value
+def createMVT(drv : gdal.Driver, path : str,
+ options : dict[str,str|int|float|None] = {},
+ default_options : dict[str,Any]|None = None) -> gdal.Dataset:
+ """Create and return the MVT file/directory (which must not exist)."""
+ # merge options from the config file
+ default_map = {
+ 'min-zoom': 'MINZOOM',
+ 'max-zoom': 'MAXZOOM',
+ 'max-size': 'MAX_SIZE',
+ 'max-features': 'MAX_FEATURES',
+ 'simplification': 'SIMPLIFICATION',
+ 'simplification-max-zoom': 'SIMPLIFICATION_MAX_ZOOM',
+ 'tiling-scheme': 'TILING_SCHEME',
+ 'extent': 'EXTENT',
+ }
+ if default_options is not None:
+ for k, v in default_options.items():
+ if k not in default_map:
+ logging.warning('No default map for key "%s", ignoring', k)
+ continue
+ if options is None:
+ options = {}
+ k = default_map[k]
+ if k not in options:
+ if isinstance(v, list):
+ v = ','.join(map(str, v))
+ options[k] = v
+
+ kwargs = { 'eType': gdal.GDT_Unknown }
+ if options is not None:
+ kwargs['options'] = opts = []
+ for k, v in options.items():
+ opts.append(k + '=' + str(v))
+
+ logging.debug('Create(%s, %s, eType=%s%s)', drv.ShortName, path, kwargs['eType'],
+ ', options=' + str(kwargs['options']) if 'options' in kwargs else '')
+ return drv.Create(path, 0, 0, 0, **kwargs)
+
+# pylint: disable-next=too-many-branches
+def exportSourceLayer(lyr_src : ogr.Layer,
+ lyr_dst : ogr.Layer,
+ layerdef : dict[str,Any],
+ fieldMap : tuple[list[str],list[int]],
+ extent : ogr.Geometry|None = None) -> int:
+ """Export a source layer."""
+ count0 = -1
+ if lyr_src.TestCapability(ogr.OLCFastFeatureCount):
+ count0 = lyr_src.GetFeatureCount(force=0)
+
+ layername = lyr_src.GetName()
+ srs_src = lyr_src.GetSpatialRef()
+ if srs_src is None:
+ raise RuntimeError(f'Source layer "{layername}" has no SRS')
+ srs_dst = lyr_dst.GetSpatialRef()
+ if srs_dst is None:
+ raise RuntimeError(f'Destination layer "{lyr_dst.GetName()}" has no SRS')
+
+ if srs_dst.IsSame(srs_src):
+ logging.debug('Source and destination have the same SRS (%s), '
+ 'skipping coordinate transformation',
+ srs_dst.GetName())
+ ct = None
+ else:
+ # TODO Use GetSupportedSRSList() and SetActiveSRS() with GDAL ≥3.7.0
+ # when possible, see apps/ogr2ogr_lib.cpp
+ # pylint: disable=duplicate-code
+ logging.debug('Creating transforming from source SRS (%s) to destination SRS (%s)',
+ srs_src.GetName(), srs_dst.GetName())
+ ct = osr.CoordinateTransformation(srs_src, srs_dst)
+ if ct is None:
+ raise RuntimeError('Could not create transformation from source SRS '
+ f'({srs_src.GetName()}) to destination SRS ({srs_dst.GetName()})')
+
+ # get geometry field of the source layer
+ defn = lyr_src.GetLayerDefn()
+ geomFieldCount = defn.GetGeomFieldCount()
+ if geomFieldCount != 1:
+ logging.warning('Source layer "%s" has %d != 1 geometry fields',
+ layername, geomFieldCount)
+ if geomFieldCount == 0:
+ return 0
+ geomField = defn.GetGeomFieldDefn(0)
+
+ if extent is None:
+ spatialFilter = None
+ else:
+ # transform extent to source SRS
+ spatialFilter = getSpatialFilterFromGeometry(extent, srs_src)
+
+ transform_geometry = layerdef.get('transform-geometry', None)
+ columns = [ 'm.' + escape_identifier(lyr_src.GetFIDColumn()) ] + fieldMap[0]
+ geomFieldName_esc = escape_identifier(geomField.GetName())
+ if transform_geometry is None:
+ columns.append('m.' + geomFieldName_esc)
+ elif transform_geometry == 'centroid':
+ columns.append('ST_Centroid(m.' + geomFieldName_esc + ') AS ' + geomFieldName_esc)
+ else:
+ raise BadConfiguration(f'Unsupported geometry transformation: {transform_geometry}')
+
+ query = 'SELECT ' + ', '.join(columns) + ' FROM ' + getEscapedTableName(lyr_src) + ' m'
+
+ cond = layerdef.get('where', None)
+ if cond is not None:
+ query += ' WHERE ' + cond.strip()
+
+ ds_src = lyr_src.GetDataset()
+ with executeSQL(ds_src, query, spatialFilter=spatialFilter) as lyr_src2:
+ count1 = -1
+ if lyr_src2.TestCapability(ogr.OLCFastFeatureCount):
+ count1 = lyr_src2.GetFeatureCount(force=0)
+ if count0 >= 0 and count1 >= 0:
+ logging.debug('Source layer "%s" has %d features, of which %d are to be exported',
+ layername, count0, count1)
+
+ fieldMap = fieldMap[1]
+ logging.debug('Field map: %s', str(fieldMap))
+
+ geom_type = lyr_src2.GetGeomType()
+ bFlatten = geom_type == ogr.wkbUnknown or ogr.GT_HasM(geom_type) or ogr.GT_HasZ(geom_type)
+ bTransform = bFlatten or ct is not None
+
+ feature_count = 0
+ defn_dst = lyr_dst.GetLayerDefn()
+ feature = lyr_src2.GetNextFeature()
+ while feature is not None:
+ feature2 = ogr.Feature(defn_dst)
+ feature2.SetFromWithMap(feature, False, fieldMap)
+ if bTransform:
+ geom = feature2.GetGeometryRef()
+ if ct is not None and geom.Transform(ct) != ogr.OGRERR_NONE:
+ raise RuntimeError('Could not apply coordinate transformation')
+ if bFlatten:
+ geom.FlattenTo2D()
+ feature2.SetGeometryDirectly(geom)
+ feature2.SetFID(feature.GetFID())
+ if lyr_dst.CreateFeature(feature2) != ogr.OGRERR_NONE:
+ raise RuntimeError(f'Could not transfer source feature #{feature.GetFID()}')
+ feature_count += 1
+ feature = lyr_src2.GetNextFeature()
+
+ logging.info('Exported %d features to MVT layer "%s" from "%s"',
+ feature_count, lyr_dst.GetName(), layername)
+ return feature_count
+
+def list_files(top : str,
+ dir_fd : Optional[int] = None,
+ follow_symlinks : bool = False,
+ ext : Optional[str] = None) -> Iterator[tuple[str,int]]:
+ """Generator of filenames and dir_fds."""
+ for _dirname, _, filenames, dir_fd2 in os.fwalk(top=top,
+ dir_fd=dir_fd,
+ follow_symlinks=follow_symlinks):
+ for filename in filenames:
+ if ext is None or filename.lower().endswith(ext):
+ yield filename, dir_fd2
+
+def write_all(fd : int, buf : bytes) -> int:
+ """Wrapper around os.write() that loops until the entire data is written."""
+ offset = 0
+ while offset < len(buf):
+ try:
+ n = os.write(fd, buf[offset:])
+ except IOError as e:
+ if e.errno != EAGAIN:
+ raise e
+ #logging.debug('Got EAGAIN while trying to write')
+ else:
+ #logging.debug('Wrote %d bytes of %d', n, len(buf) - offset)
+ offset += n
+ return offset
+
+def compress_brotli(path : str,
+ suffix : str = '.br',
+ dir_fd : Optional[int] = None,
+ # TODO increase chunksize to see if helps with performance
+ chunksize : int = 65536,
+ oFlags : int = 0,
+ **kwargs) -> tuple[int, int]:
+ """Compress a file to Brotli, returning a pair of original and compressed size."""
+ compressor = brotli.Compressor(**kwargs)
+ fd_in = os.open(path, O_RDONLY|O_CLOEXEC, dir_fd=dir_fd)
+ size_in = size_out = 0
+ try:
+ # hard-code the mode to save an fstat(2) call
+ fd_out = os.open(path + suffix, O_WRONLY|O_CREAT|O_CLOEXEC|oFlags,
+ mode=0o0644, dir_fd=dir_fd)
+ try:
+ buf_in = os.read(fd_in, chunksize)
+ while len(buf_in) > 0:
+ #logging.debug('Read %d bytes of %d', len(buf_in), chunksize)
+ size_in += len(buf_in)
+ size_out += write_all(fd_out, compressor.process(buf_in))
+ buf_in = os.read(fd_in, chunksize)
+ size_out += write_all(fd_out, compressor.finish())
+ finally:
+ os.close(fd_out)
+ finally:
+ os.close(fd_in)
+ return size_in, size_out
+
+def getLayerMetadata(layers : dict[str,Any],
+ sources : dict[str,Any],
+ license_info: dict[str,str|dict[str,str]],
+ last_modified : dict[str,int],
+ last_updated : int) -> dict[str,int|dict[int|str|dict[str,str]]]:
+ """Return a dictionary suitable for metadata.json"""
+ layers2 = {}
+ for k, v in layers.items():
+ layers2[k] = x = {}
+ if 'description' in v:
+ x['description'] = v['description']
+ source_paths = []
+ for src in v.get('sources', []):
+ if 'source' not in src or src['source'] is None:
+ continue
+ if 'path' not in src['source']:
+ continue
+ source_path = src['source']['path']
+ if source_path is not None:
+ source_paths.append(source_path)
+ if len(source_paths) > 0:
+ # remove duplicates but preserve order
+ x['source_files'] = list(dict.fromkeys(source_paths))
+
+ source_files = {}
+ for source_path in { p for v in layers2.values() for p in v.get('source_files', []) }:
+ source_files[source_path] = x = {}
+ if source_path in sources and 'url' in sources[source_path]:
+ x['url'] = sources[source_path]['url']
+ if source_path not in license_info:
+ logging.warning('Source path %s lacks license information', source_path)
+ else:
+ license_info0 = license_info[source_path]
+ for k in ('description', 'copyright', 'product_url'):
+ if k in license_info0:
+ x[k] = license_info0[k]
+ if 'license' in license_info0:
+ if isinstance(license_info0['license'], str):
+ x['license'] = { 'name': license_info0['license'] }
+ elif isinstance(license_info0['license'], dict):
+ x['license'] = license_info0['license'].copy()
+ if source_path not in last_modified:
+ logging.warning('Source path %s lack last_modified value', source_path)
+ else:
+ x['last_modified'] = last_modified[source_path]
+
+ return {
+ 'layers': layers2,
+ 'source_files': source_files,
+ 'last_updated': last_updated
+ }
+
+def exportMetadata(basedir : Path, data : dict[str,Any],
+ dir_fd : Optional[int] = None,
+ compress : bool = False) -> None:
+ """Generate metadata.json"""
+ data = json.dumps(data, ensure_ascii=False, separators=(',',':')).encode('utf-8')
+ path = basedir.joinpath('metadata.json')
+ flags = O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC
+
+ fd = os.open(str(path), flags, mode=0o644, dir_fd=dir_fd)
+ try:
+ write_all(fd, data)
+ finally:
+ os.close(fd)
+
+ if not compress:
+ return
+
+ compressor = brotli.Compressor(mode=brotli.MODE_GENERIC, quality=11)
+ fd = os.open(str(path.with_suffix('.json.br')), flags, mode=0o644, dir_fd=dir_fd)
+ try:
+ write_all(fd, compressor.process(data))
+ write_all(fd, compressor.finish())
+ finally:
+ os.close(fd)
+
+def getFieldMap(lyr_dst : ogr.Layer, lyr_src : ogr.Layer,
+ fieldMap : dict[str,str]|None) -> tuple[list[str],list[int]]:
+ """Create fields on the destination MVT layer, and return a list of
+ column statements along with a field map for the MVT export."""
+ if fieldMap is None or len(fieldMap) == 0:
+ return [], []
+
+ if not lyr_dst.TestCapability(ogr.OLCCreateField):
+ raise RuntimeError(f'Destination layer "{lyr_dst.GetName()}" lacks '
+ 'field creation capability')
+
+ columns = {}
+ defn_src = lyr_src.GetLayerDefn()
+ drv_src = lyr_src.GetDataset().GetDriver()
+ for fld_dst, fld_src in fieldMap.items():
+ idx_src = defn_src.GetFieldIndex(fld_src)
+ if idx_src < 0:
+ raise RuntimeError(f'Source layer "{lyr_src.GetName()}" has no field named "{fld_src}"')
+
+ defn_dst = ogr.FieldDefn()
+ defn_src_fld = defn_src.GetFieldDefn(idx_src)
+ if fld_dst == 'ts':
+ if defn_src_fld.GetType() not in (ogr.OFTDate, ogr.OFTDateTime):
+ raise RuntimeError(f'Field "{fld_src}" of source layer "{lyr_src.GetName()}"'
+ ' has type ' + ogr.GetFieldTypeName(defn_src_fld.GetType()) +
+ ' (Date or DateTime expected)')
+ defn_dst.SetType(ogr.OFTInteger)
+ # signed int16 allows expressing dates from 1880-04-15 to 2059-09-18
+ # which should be more than enough (it's not clear if the MVT format takes
+ # advantage of the reduced storage though)
+ defn_dst.SetSubType(ogr.OFSTInt16)
+
+ if drv_src.ShortName == 'PostgreSQL':
+ column = 'CAST(m.' + escape_identifier(fld_src)
+ column += ' - date \'1970-01-01\' AS smallint)'
+ elif drv_src.ShortName in ('SQLite', 'GPKG'):
+ column = 'CAST(floor(julianday(m.' + escape_identifier(fld_src) + ')'
+ column += ' - 2440587.5) AS smallint)'
+ else:
+ raise NotImplementedError(f'Unsupported source driver {drv_src.ShortName} for '
+ f'field "{fld_src}" (MVT field "{fld_dst}")')
+
+ else:
+ raise NotImplementedError(f'Destination MVT field "{fld_dst}"')
+
+ columns[fld_dst] = column
+
+ defn_dst.SetName(fld_dst)
+ defn_dst.SetNullable(defn_src_fld.IsNullable())
+ logging.debug('Create output field "%s" with type=%s, subtype=%s, nullable=%d',
+ defn_dst.GetName(),
+ ogr.GetFieldTypeName(defn_dst.GetType()),
+ ogr.GetFieldSubTypeName(defn_dst.GetSubType()),
+ defn_dst.IsNullable())
+
+ if lyr_dst.CreateField(defn_dst, approx_ok=False) != gdal.CE_None:
+ raise RuntimeError(f'Could not create field "{fld_dst}" '
+ f'in destination MVT layer "{lyr_dst.GetName()}"')
+
+ indices = {}
+ defn_dst = lyr_dst.GetLayerDefn()
+ for i in range(defn_dst.GetFieldCount()):
+ fld = defn_dst.GetFieldDefn(i)
+ name = fld.GetName()
+ if name in columns:
+ indices[name] = i
+ else:
+ logging.warning('Destination layer has unknown field #%d "%s"', i, name)
+
+ ret = [None] * len(columns)
+ fieldMap = [-1] * defn_dst.GetFieldCount()
+ for idx, name in enumerate(columns.keys()):
+ i = indices[name] # intentionally crash if we didn't create that field
+ fieldMap[i] = idx
+ ret[idx] = columns[name] + ' AS ' + escape_identifier(name)
+ return (ret, fieldMap)
+
+# pylint: disable-next=too-many-branches, too-many-locals, too-many-statements
+def exportMVT(ds : gdal.Dataset,
+ layers : dict[str,dict[str,Any]],
+ sources : dict[str,Any],
+ license_info: dict[str,str|dict[str,str]],
+ last_modified : dict[str,int],
+ dst : Path,
+ drvname : str = 'MVT',
+ default_options : dict[str,Any]|None = None,
+ tile_extension : str = '.pbf',
+ compress : bool = False,
+ compress_metadata : bool = False) -> None:
+ """Export some layers to MVT."""
+ drv = gdal.GetDriverByName(drvname)
+ if drv is None:
+ raise RuntimeError(f'Unknown GDAL driver for format "{drvname}"')
+
+ srs, extent = parseTilingScheme(default_options.get('tiling-scheme', None))
+
+ last_modified_ns = max(last_modified.values()) * 1000000 if len(last_modified) > 0 else None
+
+ export_layers = {}
+ mvtconf = {}
+ for layername, layerdef in layers.items():
+ exportdef = layerdef.get('publish', None)
+ if exportdef is None:
+ raise RuntimeError(f'Layer "{layername}" has no publication definition')
+ if isinstance(exportdef, str):
+ exportdef = { exportdef:{} }
+ elif isinstance(exportdef, list):
+ exportdef = { l:{} for l in exportdef }
+ for export_layername, export_layerdef in exportdef.items():
+ if export_layername in export_layers:
+ raise RuntimeError(f'Duplicate definition for {export_layername}')
+ x = {}
+ for k in ('target_name', 'minzoom', 'maxzoom'):
+ if k in export_layerdef:
+ x[k] = export_layerdef[k]
+ mvtconf[export_layername] = x
+ export_layers[export_layername] = (layername, export_layerdef)
+
+ # use a sibling temporary directory to make sure we can atomically rename/exchange
+ # directories
+ tmpdir = tempfile.mkdtemp(prefix='.tmp.mvt-', dir=dst.parent)
+ logging.debug('Using "%s" as temporary directory for MVT', tmpdir)
+
+ mvtname = 'mvt'
+ dbname = 'db'
+ dir_fd = os.open(tmpdir, O_RDONLY|O_CLOEXEC|O_DIRECTORY)
+ try:
+ start = time_monotonic()
+ os.mkdir(dbname, mode=0o700, dir_fd=dir_fd)
+ basedir = Path(f'/proc/self/fd/{dir_fd}')
+ creation_time = time_ns()
+ dso = createMVT(drv, path=str(basedir.joinpath(mvtname)),
+ default_options=default_options,
+ options = {
+ 'FORMAT': 'DIRECTORY',
+ # OpenLayers doesn't support compressed tiles, so instead
+ # we use brotli_static to let the browser transparently
+ # uncompress the responses
+ 'COMPRESS': 'NO',
+ 'TYPE': 'overlay',
+ 'BUFFER': 32,
+ 'TILE_EXTENSION': tile_extension.removeprefix('.'),
+ 'TEMPORARY_DB': str(basedir.joinpath(dbname).joinpath('tmp.db')),
+ 'CONF': json.dumps(mvtconf, ensure_ascii=False, separators=(',',':')),
+ })
+
+ layer_count = feature_count = 0
+ for layername, (layername_src, layerdef) in export_layers.items():
+ # create destination layer
+ lyr_src = ds.GetLayerByName(layername_src)
+ if lyr_src is None:
+ raise RuntimeError(f'Source dataset has no layer named "{layername_src}"')
+ transform_geometry = layerdef.get('transform-geometry', None)
+ if transform_geometry is None:
+ geom_type = ogr.GT_Flatten(lyr_src.GetGeomType())
+ elif transform_geometry == 'centroid':
+ geom_type = ogr.wkbPoint
+ else:
+ raise BadConfiguration(f'Unsupported geometry transformation: {transform_geometry}')
+ logging.debug('Creating destination MVT layer "%s" with SRS %s and type %s',
+ layername, srs.GetName(), ogr.GeometryTypeToName(geom_type))
+ lyr_dst = dso.CreateLayer(layername, srs=srs, geom_type=geom_type)
+ if lyr_dst is None:
+ raise RuntimeError(f'Could not create destination layer "{layername}"')
+
+ fieldMap = getFieldMap(lyr_dst, lyr_src, fieldMap=layerdef.get('fields', None))
+
+ # TODO: GDAL exports features to a temporary SQLite database even though the source
+ # is PostGIS hence is able to generate MVT with ST_AsMVT(). Letting PostGIS generate
+ # tiles is likely to speed up things.
+ feature_count += exportSourceLayer(lyr_src, lyr_dst, layerdef,
+ fieldMap=fieldMap,
+ extent=extent)
+ layer_count += 1
+ lyr_dst = None
+ lyr_src = None
+
+ dso = None # close MVT dataset
+ start2 = time_monotonic()
+ logging.info('Exported %d features to %d MVT layers in %s',
+ feature_count, layer_count, format_time(start2 - start))
+
+ tile_count = size_tot = size_tot_z = 0
+ size_min = size_max = size_min_z = size_max_z = None
+ for filename, dir_fd2 in list_files(top=mvtname, dir_fd=dir_fd,
+ follow_symlinks=False,
+ ext=tile_extension):
+ tile_count += 1
+ if not compress:
+ szi = os.stat(filename, dir_fd=dir_fd2).st_size
+ else:
+ # TODO: benchmark brotli quality to trade-off compression ratio vs. execution time
+ szi, szo = compress_brotli(filename,
+ dir_fd=dir_fd2,
+ oFlags=O_EXCL,
+ mode=brotli.MODE_GENERIC,
+ quality=5)
+ size_tot_z += szo
+ if size_min_z is None or szo < size_min_z:
+ size_min_z = szo
+ if size_max_z is None or size_max_z < szo:
+ size_max_z = szo
+ size_tot += szi
+ if size_min is None or szi < size_min:
+ size_min = szi
+ if size_max is None or size_max < szi:
+ size_max = szi
+
+ if tile_count > 0:
+ logging.info('Tile count: %d [min=%s, max=%s, sum=%s, avg=%s]',
+ tile_count,
+ format_bytes(size_min), format_bytes(size_max),
+ format_bytes(size_tot), format_bytes(round(size_tot/tile_count)))
+ if compress:
+ logging.info('Compression ratio: %.1f%% in %s [min=%s, max=%s, sum=%s, avg=%s]',
+ 100. * (1. - size_tot_z/size_tot),
+ format_time(time_monotonic() - start2),
+ format_bytes(size_min_z), format_bytes(size_max_z),
+ format_bytes(size_tot_z), format_bytes(round(size_tot_z/tile_count)))
+
+ exportMetadata(basedir=Path(mvtname),
+ data=getLayerMetadata({k:layers[v] for k,(v,_) in export_layers.items()},
+ sources=sources,
+ license_info=license_info,
+ last_modified=last_modified,
+ last_updated=creation_time // 1000000),
+ dir_fd=dir_fd,
+ compress=compress_metadata)
+
+ if last_modified_ns is not None:
+ os.utime(mvtname, ns=(last_modified_ns, last_modified_ns),
+ dir_fd=dir_fd, follow_symlinks=False)
+
+ try:
+ # atomically exchange paths
+ rename_exchange(mvtname, dst, olddirfd=dir_fd)
+ except FileNotFoundError:
+ # dst doesn't exist, use normal os.rename() instead
+ os.rename(mvtname, dst, src_dir_fd=dir_fd)
+
+ finally:
+ lyr_dst = None
+ dso = None # close MVT dataset
+ srs = None
+ for p in (dbname, mvtname):
+ if os.access(p, F_OK, dir_fd=dir_fd, follow_symlinks=False):
+ logging.debug('rmtree("%s/%s")', tmpdir, p)
+ shutil.rmtree(p, dir_fd=dir_fd)
+
+ logging.debug('rmdir("%s")', tmpdir)
+ os.rmdir(tmpdir)
+
+ try:
+ os.close(dir_fd)
+ except (OSError, ValueError):
+ logging.exception('Could not close directory')
diff --git a/export_raster.py b/export_raster.py
new file mode 100644
index 0000000..a2f23c1
--- /dev/null
+++ b/export_raster.py
@@ -0,0 +1,251 @@
+#!/usr/bin/python3
+
+#----------------------------------------------------------------------
+# Backend utilities for the Klimatanalys Norr project (Cloud Optimized GeoTIFF generator)
+# Copyright © 2025 Guilhem Moulin <info@guilhem.se>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+#----------------------------------------------------------------------
+
+# pylint: disable=invalid-name, missing-module-docstring
+
+from os import O_RDONLY, O_CLOEXEC, O_DIRECTORY, F_OK
+import os
+import sys
+import logging
+from pathlib import Path
+from typing import Any
+import shutil
+import tempfile
+from time import time_ns
+
+from osgeo import gdal, ogr, osr
+from osgeo.gdalconst import (
+ OF_RASTER as GDAL_OF_RASTER,
+ OF_READONLY as GDAL_OF_READONLY,
+ OF_VERBOSE_ERROR as GDAL_OF_VERBOSE_ERROR,
+)
+
+from common import BadConfiguration
+from import_source import importSource0
+from common_gdal import (
+ gdalSetOpenExArgs,
+ gdalVersionMin,
+ getSpatialFilterFromGeometry,
+)
+from export_mvt import exportMetadata, getLayerMetadata
+from rename_exchange import rename_exchange
+
+def processRaster(layername : str,
+ layerdef : dict[str,Any],
+ sources : dict[str,Any],
+ license_info: dict[str,str|dict[str,str]],
+ last_modified : dict[str,int],
+ dst : Path,
+ cachedir : Path|None = None,
+ extent : ogr.Geometry|None = None,
+ compress_metadata : bool = False) -> None:
+ """Process a raster file."""
+ source = layerdef['sources']
+ assert layerdef['type'] == 'raster'
+ if len(source) != 1:
+ raise BadConfiguration(f'{layername} has {len(source)} != 1 sources')
+ publish = layerdef.get('publish', None)
+ if publish is None or len(publish) < 1:
+ raise BadConfiguration(f'{layername} has no export definition')
+ if not isinstance(publish, dict) or not all(isinstance(l, str) for l in publish.values()):
+ raise BadConfiguration(f'{layername} has invalid export definition {publish}')
+ source = source[0]
+
+ if sys.stderr.isatty():
+ from tqdm import tqdm # pylint: disable=import-outside-toplevel
+ progress = tqdm
+ else:
+ progress = None
+
+ if len(last_modified) < 1:
+ last_modified_ns = None
+ else:
+ last_modified_ns = max(last_modified.values()) * 1000000
+ try:
+ st = os.stat(str(dst))
+ if last_modified_ns <= st.st_mtime_ns:
+ logging.info('Output directory "%s" is up to date, skipping', str(dst))
+ return
+ except (OSError, ValueError):
+ #logging.warning('Could not stat(%s)', str(dst))
+ pass
+
+ # use a sibling temporary directory to make sure we can atomically rename/exchange
+ # directories
+ tmpdir = tempfile.mkdtemp(prefix='.tmp.' + dst.name + '-', dir=dst.parent)
+ logging.debug('Using "%s" as temporary directory for MVT', tmpdir)
+
+ dir_fd = os.open(tmpdir, O_RDONLY|O_CLOEXEC|O_DIRECTORY)
+ try:
+ creation_time = time_ns()
+ os.mkdir(dst.name, mode=0o755, dir_fd=dir_fd)
+
+ source['import'] |= {
+ '_progress': progress,
+ '_dest': str(Path(f'/proc/self/fd/{dir_fd}').joinpath(dst.name)
+ .joinpath(dst.name + '.tiff'))
+ }
+ importSource0(None, **source['source'], args=source['import'],
+ cachedir=cachedir,
+ extent=extent,
+ callback=_processRaster2)
+
+ exportMetadata(basedir=Path(dst.name),
+ data=getLayerMetadata({str(i):layerdef | {'description':desc}
+ for i,desc in publish.items()},
+ sources=sources,
+ license_info=license_info,
+ last_modified=last_modified,
+ last_updated=creation_time // 1000000),
+ dir_fd=dir_fd, # pylint: disable=duplicate-code
+ compress=compress_metadata)
+
+ if last_modified_ns is not None:
+ os.utime(dst.name, ns=(last_modified_ns, last_modified_ns),
+ dir_fd=dir_fd, follow_symlinks=False)
+
+ try:
+ # atomically exchange paths
+ rename_exchange(dst.name, dst, olddirfd=dir_fd)
+ except FileNotFoundError:
+ # dst doesn't exist, use normal os.rename() instead
+ os.rename(dst.name, dst, src_dir_fd=dir_fd)
+
+ finally:
+ if progress is not None and '_pbar' in source['import']:
+ source['import'].pop('_pbar').close()
+ if os.access(dst.name, F_OK, dir_fd=dir_fd, follow_symlinks=False):
+ logging.debug('rmtree("%s/%s")', tmpdir, dst.name)
+ shutil.rmtree(dst.name, dir_fd=dir_fd)
+
+ logging.debug('rmdir("%s")', tmpdir)
+ os.rmdir(tmpdir)
+
+ try:
+ os.close(dir_fd) # pylint: disable=duplicate-code
+ except (OSError, ValueError):
+ logging.exception('Could not close directory')
+
+def _processRaster2(_ : None, path : str, args : dict[str,Any],
+ basedir : Path|None, extent : ogr.Geometry|None) -> gdal.Dataset:
+ kwargs, _ = gdalSetOpenExArgs(args, flags=GDAL_OF_RASTER|GDAL_OF_READONLY|GDAL_OF_VERBOSE_ERROR)
+ path2 = path if basedir is None else str(basedir.joinpath(path))
+
+ logging.debug('OpenEx(%s, %s)', path2, str(kwargs))
+ ds = gdal.OpenEx(path2, **kwargs) # pylint: disable=duplicate-code
+ if ds is None:
+ raise RuntimeError(f'Could not open {path2}')
+
+ if ds.RasterCount != 1:
+ raise NotImplementedError(f'Input raster {path2} has {ds.RasterCount} != 1 bands')
+ rb = ds.GetRasterBand(1)
+
+ gt = ds.GetGeoTransform()
+ xs = ds.RasterXSize
+ ys = ds.RasterYSize
+
+ srs = ds.GetSpatialRef()
+ srs.SetAxisMappingStrategy(gdal.osr.OAMS_TRADITIONAL_GIS_ORDER) # force x,y
+ ulx, uly = gdal.ApplyGeoTransform(gt, 0, 0)
+ lrx, lry = gdal.ApplyGeoTransform(gt, xs, ys)
+ assert ulx <= lrx
+ assert uly >= lry
+
+ extent = getSpatialFilterFromGeometry(extent, srs)
+ ct = osr.CoordinateTransformation(extent.GetSpatialReference(), srs)
+ extent = extent.GetEnvelope()
+ ulxy = ct.TransformPoint(extent[0], extent[3])
+ lrxy = ct.TransformPoint(extent[1], extent[2])
+ assert ulxy[0] <= lrxy[0]
+ assert ulxy[1] >= lrxy[1]
+
+ ulx2 = max(ulx, ulxy[0])
+ uly2 = min(uly, ulxy[1])
+ lrx2 = min(lrx, lrxy[0])
+ lry2 = max(lry, lrxy[1])
+ assert ulx2 < lrx2
+ assert lry2 < uly2
+
+ # don't care about overview here, GDAL will take the ceiling when sizing
+ # (the source width is not even disible by 2)
+ r = (lrx2 - ulx2) % abs(gt[1])
+ if r != 0:
+ # extend X boundaries to preserve xres
+ d = abs(gt[1]) - r
+ if ulxy[0] < ulx:
+ ulx2 -= d
+ else:
+ lrx2 += r
+ assert (lrx2 - ulx2) % abs(gt[1]) == 0
+
+ r = (uly2 - lry2) % abs(gt[5])
+ if r != 0:
+ # extend Y boundaries to preserve yres
+ d = abs(gt[5]) - r
+ if lrxy[1] < lry:
+ uly2 += r
+ else:
+ lry2 -= d
+ assert (uly2 - lry2) % abs(gt[5]) == 0
+
+ # see https://gdal.org/en/stable/drivers/raster/cog.html
+ creationOptions = [
+ 'BLOCKSIZE=256',
+ 'COMPRESS=LZW',
+ 'RESAMPLING=NEAREST',
+ 'OVERVIEWS=IGNORE_EXISTING',
+ ]
+ if (rb.GetColorInterpretation() in (gdal.GCI_PaletteIndex, gdal.GCI_GrayIndex)
+ and rb.DataType == gdal.GDT_Byte):
+ # 8-bit gray, assume a palette so don't interpolate
+ creationOptions.append('RESAMPLING=NEAREST')
+ if gdalVersionMin(maj=3, min=11):
+ creationOptions.append('INTERLEAVE=BAND')
+ creationOptions.append('STATISTICS=YES')
+
+ warpOptions = {
+ 'format': 'COG',
+ # preserve source SRS and resolution
+ 'outputBounds': (ulx2, lry2, lrx2, uly2),
+ 'setColorInterpretation': True,
+ 'creationOptions': creationOptions,
+ }
+
+ if args.get('_progress', None) is None:
+ callback = pbar = None
+ else:
+ callback = _gdal_callback
+ pbar = args['_pbar'] = args['_progress'](
+ total=100,
+ leave=False,
+ bar_format='{l_bar}{bar}| [{elapsed}<{remaining}]',
+ )
+
+ logging.debug('warp(%s, ds, %s)', args['_dest'],
+ ', '.join([str(k) + '=' + (f'\'{v}\'' if isinstance(v,str) else str(v))
+ for k,v in warpOptions.items()]))
+ return gdal.Warp(args['_dest'], ds,
+ **warpOptions,
+ callback=callback,
+ callback_data=pbar,
+ )
+
+def _gdal_callback(info, _message, pbar):
+ pbar.update(info * 100 - pbar.n)
diff --git a/webmap-download b/geodata-download
index fc5ceee..5e191ad 100755
--- a/webmap-download
+++ b/geodata-download
@@ -2,7 +2,7 @@
#----------------------------------------------------------------------
# Backend utilities for the Klimatanalys Norr project (download common layers)
-# Copyright © 2024 Guilhem Moulin <info@guilhem.se>
+# Copyright © 2024-2025 Guilhem Moulin <info@guilhem.se>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -18,8 +18,23 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#----------------------------------------------------------------------
-from os import O_RDONLY, O_WRONLY, O_CREAT, O_TRUNC, O_CLOEXEC, O_PATH, O_DIRECTORY, O_TMPFILE
-import os, sys
+# pylint: disable=invalid-name, missing-module-docstring, fixme
+# pylint: enable=invalid-name
+
+from os import (
+ O_RDONLY,
+ O_WRONLY,
+ O_CREAT,
+ O_TRUNC,
+ O_CLOEXEC,
+ O_PATH,
+ O_DIRECTORY,
+ O_TMPFILE,
+ path as os_path,
+ curdir as os_curdir,
+)
+import os
+import sys
from fcntl import flock, LOCK_EX
import logging
from time import time, monotonic as time_monotonic
@@ -27,35 +42,54 @@ import argparse
import itertools
from pathlib import Path
from email.utils import parsedate_to_datetime, formatdate
-from hashlib import sha256
+from typing import Optional, NoReturn, Never
import requests
import common
+from common import parse_config_dl, getSourcePathLockFileName
+
+def download_trystream(url : str, **kwargs) -> requests.Response:
+ """GET a url, trying a number of times. Return immediately after the
+ first chunk is received"""
-def download_trystream(url, **kwargs):
- max_tries = 10
- f = kwargs.pop('session', requests)
+ max_retries = kwargs.pop('max_retries', 10)
+ f = kwargs.pop('session', None)
+ if f is None:
+ f = requests
for i in itertools.count(1):
try:
r = f.get(url, **kwargs, stream=True)
except (requests.Timeout, requests.ConnectionError):
- if i < max_tries:
+ if i < max_retries:
logging.error('timeout')
continue
raise
- else:
- r.raise_for_status()
- return r
-def download(url, dest, dir_fd=None, headers={}, session=requests, progress=None):
+ r.raise_for_status()
+ return r
+
+class DownloadTooLarge(Exception):
+ """Exception raised when a downloaded file exceeds max-size"""
+ def __init__(self, max_size : int) -> Never:
+ super().__init__(f'Payload exceeds max-size ({max_size})')
+
+# pylint: disable-next=dangerous-default-value
+def download(dest : str,
+ dl : dict[str, dict[str, str|int]],
+ dir_fd : Optional[int] = None,
+ headers : dict[str, str] = {},
+ session : Optional[requests.sessions.Session] = None,
+ progress = None) -> None:
+ """Process a single download recipe"""
+
url = None if dl is None else dl.get('url', None)
if url is None:
logging.error('%s has no source URL, ignoring', dest)
return
max_size = dl.get('max-size', 2**26) # 64MiB
logging.info('Downloading %s…', url)
- destPath = Path(dest)
- dest_tmp = str(destPath.with_stem(f'.{destPath.stem}.new'))
+ dest_path = Path(dest)
+ dest_tmp = str(dest_path.with_stem(f'.{dest_path.stem}.new'))
try:
# delete any leftover
os.unlink(dest_tmp, dir_fd=dir_fd)
@@ -64,10 +98,7 @@ def download(url, dest, dir_fd=None, headers={}, session=requests, progress=None
start = time_monotonic()
r = download_trystream(url, headers=headers, session=session, timeout=30)
- if r.status_code == requests.codes.not_modified:
- # XXX shouldn't we call os.utime(dest) to bump its ctime here?
- # otherwise we'll make several queries and get multiple 304
- # replies if the file is used by multiple layers
+ if r.status_code == 304:
logging.info('%s: %d Not Modified', dest, r.status_code)
return
@@ -86,7 +117,7 @@ def download(url, dest, dir_fd=None, headers={}, session=requests, progress=None
# XXX we can't use TemporaryFile as it uses O_EXCL, cf.
# https://discuss.python.org/t/temporaryfile-contextmanager-that-allows-creating-a-directory-entry-on-success/19094/2
- fd = os.open(os.path.dirname(dest), O_WRONLY|O_CLOEXEC|O_TMPFILE, mode=0o644, dir_fd=dir_fd)
+ fd = os.open(os_path.dirname(dest), O_WRONLY|O_CLOEXEC|O_TMPFILE, mode=0o644, dir_fd=dir_fd)
try:
if progress is not None:
pbar = progress(
@@ -103,12 +134,12 @@ def download(url, dest, dir_fd=None, headers={}, session=requests, progress=None
pbar.update(chunk_size)
size += chunk_size
if max_size is not None and size > max_size:
- raise Exception(f'Payload exceeds max-size ({max_size})')
+ raise DownloadTooLarge(max_size)
fp.write(chunk)
r = None
if last_modified is not None:
- os.utime(fd, times=(last_modified, last_modified), follow_symlinks=True)
+ os.utime(fd, times=(last_modified, last_modified))
# XXX unfortunately there is no way for linkat() to clobber the destination,
# so we use a temporary file; it's racy, but thanks to O_TMPFILE better
@@ -129,15 +160,18 @@ def download(url, dest, dir_fd=None, headers={}, session=requests, progress=None
raise e
elapsed = time_monotonic() - start
- logging.info("%s: Downloaded %s in %s (%s/s)", dest, common.format_bytes(size),
- common.format_time(elapsed), common.format_bytes(int(size/elapsed)))
+ logging.info('%s: Downloaded %s in %s (%s/s)', dest,
+ common.format_bytes(size),
+ common.format_time(elapsed),
+ common.format_bytes(int(size/elapsed)))
-if __name__ == '__main__':
- common.init_logger(app=os.path.basename(__file__), level=logging.INFO)
+# pylint: disable-next=missing-function-docstring
+def main() -> NoReturn:
+ common.init_logger(app=os_path.basename(__file__), level=logging.INFO)
parser = argparse.ArgumentParser(description='Download or update GIS layers.')
- parser.add_argument('--cachedir', default=os.curdir,
- help=f'destination directory for downloaded files (default: {os.curdir})')
+ parser.add_argument('--cachedir', default=os_curdir,
+ help=f'destination directory for downloaded files (default: {os_curdir})')
parser.add_argument('--lockdir', default=None,
help='optional directory for lock files')
parser.add_argument('--quiet', action='store_true',
@@ -146,31 +180,49 @@ if __name__ == '__main__':
help=argparse.SUPPRESS)
parser.add_argument('--exit-code', default=True, action=argparse.BooleanOptionalAction,
help='whether to exit with status 1 in case of download failures')
+ parser.add_argument('--force', default=False, action='store_true',
+ help='always download regardless of age')
parser.add_argument('groupname', nargs='*', help='group layer name(s) to process')
args = parser.parse_args()
- if args.debug > 0:
+ if args.debug > 0: # pylint: disable=duplicate-code
logging.getLogger().setLevel(logging.DEBUG)
if args.debug > 1:
- from http.client import HTTPConnection
+ from http.client import HTTPConnection # pylint: disable=import-outside-toplevel
HTTPConnection.debuglevel = 1
- requests_log = logging.getLogger("urllib3")
+ requests_log = logging.getLogger('urllib3')
requests_log.setLevel(logging.DEBUG)
requests_log.propagate = True
- common.load_config(groupnames=None if args.groupname == [] else args.groupname)
+ config = common.parse_config(groupnames=None if args.groupname == [] else args.groupname)
+ downloads = parse_config_dl(config.get('downloads', []))
- sources = []
- for name, layerdefs in common.config.get('layers', {}).items():
- for layerdef in layerdefs['sources']:
- sourcedef = layerdef.get('source', {})
- sourcedef['layername'] = name
- sources.append(sourcedef)
+ rv = 0
+ download_paths = set()
+ for layername, layerdef in config.get('layers', {}).items():
+ sources = layerdef.get('sources', None)
+ if sources is None or len(sources) < 1:
+ logging.warning('Layer "%s" has no source, ignoring', layername)
+ continue
+ for idx, source in enumerate(sources):
+ if 'source' not in source:
+ continue
+ source = source['source']
+ path = None if source is None else source.get('path', None)
+ if path is None:
+ logging.error('Source #%d of layer "%s" has no path, ignoring',
+ idx, layername)
+ rv = 1
+ elif path not in downloads:
+ logging.warning('Ignoring unknown source of path "%s" from layer "%s"',
+ path, layername)
+ else:
+ download_paths.add(path)
if args.quiet or not sys.stderr.isatty():
pbar = None
else:
- from tqdm import tqdm
+ from tqdm import tqdm # pylint: disable=import-outside-toplevel
pbar = tqdm
# intentionally leave the dirfd open until the program terminates
@@ -178,45 +230,32 @@ if __name__ == '__main__':
destdir_fd = os.open(args.cachedir, opendir_args)
lockdir_fd = None if args.lockdir is None else os.open(args.lockdir, opendir_args)
- sessionRequests = requests.Session()
-
- rv = 0
- downloads = set()
- for source in sources:
- dl = source.get('download', None)
- dl_module = None if dl is None else dl.get('module', None)
- if dl_module is None:
- fetch = download
- else:
- dl_module = __import__(dl_module)
- fetch = dl_module.download
-
- cache = source.get('cache', None)
- dest = None if cache is None else cache.get('path', None)
- if dest is None:
- raise Exception('Impossible')
-
- dest = str(dest) # convert from Path()
- if dest in downloads:
- logging.info('%s was already downloaded, skipping', dest)
- continue
+ session_requests = requests.Session()
+ for dest in download_paths:
+ dl = downloads[dest]
headers = {}
- user_agent = common.config.get('User-Agent', None)
+ user_agent = config.get('User-Agent', None)
if user_agent is not None:
headers['User-Agent'] = user_agent
try:
# create parent directories
- destdir = os.path.dirname(dest)
- common.makedirs(destdir, mode=0o755, dir_fd=destdir_fd, exist_ok=True, logging=logging)
+ destdir = os_path.dirname(dest)
+ common.makedirs(destdir, mode=0o755, dir_fd=destdir_fd, exist_ok=True)
# place an exclusive lock on a lockfile as the destination can be used by other layers
# hence might be updated in parallel
if lockdir_fd is not None:
- lockfile = sha256(dest.encode('utf-8')).hexdigest() + '.lck'
- # use O_TRUNC to bump lockfile's mtime
- lock_fd = os.open(lockfile, O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, mode=0o644, dir_fd=lockdir_fd)
+ umask = os.umask(0o002)
+ lockfile = getSourcePathLockFileName(dest)
+ try:
+ # use O_TRUNC to bump lockfile's mtime
+ lock_fd = os.open(lockfile, O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, mode=0o664,
+ dir_fd=lockdir_fd)
+ finally:
+ os.umask(umask)
+
try:
if lockdir_fd is not None:
logging.debug('flock("%s", LOCK_EX)', lockfile)
@@ -227,24 +266,26 @@ if __name__ == '__main__':
# the file doesn't exist, or stat() failed for some reason
pass
else:
- max_age = cache.get('max-age', 6*3600) # 6h
- if max_age is not None:
- s = max_age + max(st.st_ctime, st.st_mtime) - time()
- if s > 0:
- logging.info('%s: Too young, try again in %s',
- dest, common.format_time(s))
- continue
- headers['If-Modified-Since'] = formatdate(timeval=st.st_mtime, localtime=False, usegmt=True)
- fetch(dl, dest, dir_fd=destdir_fd,
- headers=headers, session=sessionRequests,
- progress=pbar)
- downloads.add(dest)
+ if not args.force:
+ max_age = dl.get('max-age', 6*3600) # 6h
+ if max_age is not None:
+ s = max_age + max(st.st_ctime, st.st_mtime) - time()
+ if s > 0:
+ logging.info('%s: Too young, try again in %s', dest,
+ common.format_time(s))
+ continue
+ headers['If-Modified-Since'] = formatdate(timeval=st.st_mtime,
+ localtime=False, usegmt=True)
+ download(dest, dl, dir_fd=destdir_fd,
+ headers=headers, session=session_requests,
+ progress=pbar)
finally:
if lockdir_fd is not None:
os.close(lock_fd)
- except Exception:
- logging.exception('Could not download %s as %s',
- dl.get('url', source['layername']), dest)
+ except Exception: # pylint: disable=broad-exception-caught
+ logging.exception('Could not download %s as %s', dl.get('url', '[N/A]'), dest)
if args.exit_code:
rv = 1
- exit(rv)
+ sys.exit(rv)
+
+main()
diff --git a/geodata-import b/geodata-import
new file mode 100755
index 0000000..2f0f5b4
--- /dev/null
+++ b/geodata-import
@@ -0,0 +1,794 @@
+#!/usr/bin/python3
+
+#----------------------------------------------------------------------
+# Backend utilities for the Klimatanalys Norr project (extract/import layers)
+# Copyright © 2024-2025 Guilhem Moulin <info@guilhem.se>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+#----------------------------------------------------------------------
+
+# pylint: disable=invalid-name, missing-module-docstring, fixme
+
+from os import O_RDONLY, O_WRONLY, O_CREAT, O_TRUNC, O_CLOEXEC, O_PATH, O_DIRECTORY
+import os
+from stat import S_ISREG
+import sys
+from fcntl import flock, LOCK_EX, LOCK_SH
+import logging
+import argparse
+import re
+from datetime import datetime, timedelta, timezone, UTC
+from math import modf
+from pathlib import Path
+from time import monotonic as time_monotonic
+from typing import Any, Optional, NoReturn
+import traceback
+
+from osgeo import gdal, ogr, osr
+from osgeo.gdalconst import (
+ CE_None as GDAL_CE_None,
+ DCAP_DEFAULT_FIELDS as GDAL_DCAP_DEFAULT_FIELDS,
+ DCAP_NOTNULL_FIELDS as GDAL_DCAP_NOTNULL_FIELDS,
+ DCAP_UNIQUE_FIELDS as GDAL_DCAP_UNIQUE_FIELDS,
+)
+from osgeo import gdalconst
+
+import common
+from common import (
+ BadConfiguration,
+ parse_config_dl,
+ escape_identifier,
+ escape_literal_str,
+ getSourcePathLockFileName
+)
+from common_gdal import (
+ gdalGetMetadataItem,
+ getSRS,
+ getExtent,
+ parseGeomType,
+ parseFieldType,
+ parseSubFieldType,
+ parseTimeZone
+)
+from import_source import (
+ openOutputDS,
+ createOutputLayer,
+ validateOutputLayer,
+ importSources,
+ ImportStatus
+)
+from export_mvt import exportMVT
+from export_raster import processRaster
+
+def setFieldIf(cond : bool,
+ attrName : str,
+ val : Any,
+ data : dict[str, Any],
+ fldName : str,
+ drvName : str,
+ log = logging.warning) -> None:
+ """Conditionally set a field"""
+ if cond:
+ data[attrName] = val
+ else:
+ if isinstance(val, str):
+ val2 = '"' + val + '"'
+ else:
+ val2 = str(val)
+ log('Ignoring %s=%s on field "%s" (not supported by %s driver)',
+ attrName, val2, fldName, drvName)
+
+# pylint: disable-next=too-many-branches
+def validate_schema(layers : dict[str, Any],
+ drvo : Optional[gdal.Driver] = None,
+ lco_defaults : Optional[dict[str, str]] = None) -> None:
+ """Validate layer creation options and schema. The schema is
+ modified in place with the parsed result.
+ (We need the driver of the output dataset to determine capability on
+ constraints.)"""
+
+ # list of capability flags supported by the CreateField() API
+ drvoFieldDefnFlags = drvo.GetMetadataItem(gdalconst.DMD_CREATION_FIELD_DEFN_FLAGS)
+ drvoFieldDefnFlags = drvoFieldDefnFlags.split(' ') if drvoFieldDefnFlags is not None else []
+ drvoSupportsFieldComment = 'Comment' in drvoFieldDefnFlags
+
+ # cache driver capabilities
+ drvoSupportsFieldWidthPrecision = 'WidthPrecision' in drvoFieldDefnFlags
+ drvoSupportsFieldNullable = ('Nullable' in drvoFieldDefnFlags and
+ gdalGetMetadataItem(drvo, GDAL_DCAP_NOTNULL_FIELDS))
+ drvoSupportsFieldUnique = ('Unique' in drvoFieldDefnFlags and
+ gdalGetMetadataItem(drvo, GDAL_DCAP_UNIQUE_FIELDS))
+ drvoSupportsFieldDefault = ('Default' in drvoFieldDefnFlags and
+ gdalGetMetadataItem(drvo, GDAL_DCAP_DEFAULT_FIELDS))
+ drvoSupportsFieldAlternativeName = 'AlternativeName' in drvoFieldDefnFlags
+
+ for layername, layerdef in layers.items():
+ create = layerdef.get('create', None)
+ if create is None or len(create) < 1:
+ logging.warning('Layer "%s" has no creation schema', layername)
+ continue
+
+ # prepend global layer creation options (dataset:create-layer-options)
+ # and build the option=value list
+ lco = create.get('options', None)
+ if lco_defaults is not None or lco is not None:
+ options = []
+ if lco_defaults is not None:
+ options += [ k + '=' + str(v) for k, v in lco_defaults.items() ]
+ if lco is not None:
+ options += [ k + '=' + str(v) for k, v in lco.items() ]
+ create['options'] = options
+
+ # parse geometry type
+ create['geometry-type'] = parseGeomType(create.get('geometry-type', None))
+
+ fields = create.get('fields', None)
+ if fields is None:
+ create['fields'] = []
+ else:
+ fields_set = set()
+ for idx, fld_def in enumerate(fields):
+ fld_name = fld_def.get('name', None)
+ if fld_name is None or fld_name == '':
+ raise BadConfiguration(f'Field #{idx} has no name')
+ if fld_name in fields_set:
+ raise BadConfiguration(f'Duplicate field "{fld_name}"')
+ fields_set.add(fld_name)
+
+ fld_def2 = { 'Name': fld_name }
+ for k, v in fld_def.items():
+ k2 = k.lower()
+ if k2 == 'name':
+ pass
+ elif k2 in ('alternativename', 'alias'):
+ setFieldIf(drvoSupportsFieldAlternativeName,
+ 'AlternativeName', v, fld_def2, fld_name, drvo.ShortName,
+ log=logging.debug)
+ elif k2 == 'comment':
+ setFieldIf(drvoSupportsFieldComment,
+ 'Comment', v, fld_def2, fld_name, drvo.ShortName,
+ log=logging.debug)
+
+ elif k2 == 'type':
+ fld_def2['Type'] = parseFieldType(v)
+ elif k2 == 'subtype':
+ fld_def2['SubType'] = parseSubFieldType(v)
+ elif k2 == 'tz':
+ fld_def2['TZFlag'] = parseTimeZone(v)
+ elif k2 == 'width' and v is not None and isinstance(v, int):
+ setFieldIf(drvoSupportsFieldWidthPrecision,
+ 'Width', v, fld_def2, fld_name, drvo.ShortName)
+ elif k2 == 'precision' and v is not None and isinstance(v, int):
+ setFieldIf(drvoSupportsFieldWidthPrecision,
+ 'Precision', v, fld_def2, fld_name, drvo.ShortName)
+
+ # constraints
+ elif k2 == 'default':
+ setFieldIf(drvoSupportsFieldDefault,
+ 'Default', v, fld_def2, fld_name, drvo.ShortName)
+ elif k2 == 'nullable' and v is not None and isinstance(v, bool):
+ setFieldIf(drvoSupportsFieldNullable,
+ 'Nullable', v, fld_def2, fld_name, drvo.ShortName)
+ elif k2 == 'unique' and v is not None and isinstance(v, bool):
+ setFieldIf(drvoSupportsFieldUnique,
+ 'Unique', v, fld_def2, fld_name, drvo.ShortName)
+ else:
+ raise BadConfiguration(f'Field "{fld_name}" has unknown key "{k}"')
+
+ fields[idx] = fld_def2
+
+def setOutputFieldMap(defn : ogr.FeatureDefn, sources : dict[str, Any]):
+ """Setup output field mapping, modifying the sources dictionary in place."""
+ fieldMap = {}
+ n = defn.GetFieldCount()
+ for i in range(n):
+ fld = defn.GetFieldDefn(i)
+ fldName = fld.GetName()
+ fieldMap[fldName] = i
+
+ for source in sources:
+ source_import = source['import']
+
+ fieldMap2 = source_import.get('field-map', None)
+ if fieldMap2 is None:
+ fieldMap2 = fieldMap
+ else:
+ if isinstance(fieldMap2, list):
+ # convert list to identity dictionary
+ fieldMap2 = { fld: fld for fld in fieldMap2 }
+
+ for ifld, ofld in fieldMap2.items():
+ i = fieldMap.get(ofld, None)
+ if i is None:
+ raise RuntimeError(f'Ouput layer has no field named "{ofld}"')
+ fieldMap2[ifld] = i
+ source_import['field-map'] = fieldMap2
+
+ # validate field value mapping
+ valueMap = source_import.get('value-map', None)
+ if valueMap is not None:
+ for fldName, rules in valueMap.items():
+ if rules is None:
+ continue
+ if not isinstance(rules, list):
+ rules = [rules]
+ for idx, rule in enumerate(rules):
+ if rule is None or not isinstance(rule, dict):
+ raise RuntimeError(f'Field "{fldName}" has invalid rule #{idx}: {rule}')
+ if 'type' not in rule:
+ ruleType = rule['type'] = 'literal'
+ else:
+ ruleType = rule['type']
+ if ('replace' not in rule or 'with' not in rule or len(rule) != 3 or
+ ruleType is None or ruleType not in ('literal', 'regex')):
+ raise RuntimeError(f'Field "{fldName}" has invalid rule #{idx}: {rule}')
+ if ruleType == 'regex':
+ rule['replace'] = re.compile(rule['replace'])
+ rules[idx] = ( rule['replace'], rule['with'] )
+
+def processOutputLayer(ds : gdal.Dataset,
+ layername : str,
+ layerdef : dict[str,Any],
+ srs : Optional[osr.SpatialReference] = None,
+ cachedir : Path|None = None,
+ extent : ogr.Geometry|None = None,
+ dsTransaction : bool = False,
+ lyrcache : ogr.Layer|None = None,
+ force : bool = False) -> ImportStatus:
+ """Process an output layer."""
+
+ logging.info('Processing output layer "%s"', layername)
+ lyr = ds.GetLayerByName(layername)
+ if lyr is None:
+ raise RuntimeError(f'Failed to create output layer "{layername}"??')
+ if not lyr.TestCapability(ogr.OLCSequentialWrite):
+ raise RuntimeError(f'Output layer "{layername}" has no working '
+ 'CreateFeature() method')
+
+ sources = layerdef['sources']
+ if not (lyrcache is None or force or
+ areSourceFilesNewer(layername, sources=sources,
+ lyrcache=lyrcache,
+ cachedir=cachedir)):
+ logging.info('Output layer "%s" is up to date, skipping', layername)
+ return ImportStatus.IMPORT_NOCHANGE
+
+ validateOutputLayer(lyr, srs=srs, options=layerdef['create'])
+
+ description = layerdef.get('description', None)
+ if (description is not None and
+ lyr.SetMetadataItem('DESCRIPTION', description) != GDAL_CE_None):
+ logging.warning('Could not set description metadata')
+
+ # setup output field mapping in the sources dictionary
+ setOutputFieldMap(lyr.GetLayerDefn(), sources)
+
+ return importSources(lyr=lyr, sources=sources,
+ cachedir=cachedir, extent=extent,
+ dsoTransaction=dsTransaction,
+ lyrcache=lyrcache,
+ force=force,
+ cluster_geometry=layerdef.get('cluster-geometry', False))
+
+def validate_sources(layers : dict[str, Any]) -> None:
+ """Mangle and validate layer sources and import definitions"""
+ toremove = set()
+ for layername, layerdefs in layers.items():
+ sources = layerdefs.get('sources', None)
+ if sources is None or len(sources) < 1:
+ logging.warning('Output layer "%s" has no definition, skipping', layername)
+ toremove.add(layername)
+ continue
+
+ for idx, layerdef in enumerate(sources):
+ importdef = layerdef.get('import', None)
+ if importdef is None:
+ raise BadConfiguration(f'Source #{idx} of output layer "{layername}" '
+ 'has no import definition')
+
+ sourcedef = layerdef.get('source', None)
+ unar = None if sourcedef is None else sourcedef.get('unar', None)
+ src = None if sourcedef is None else sourcedef.get('path', None)
+
+ ds_srcpath = importdef.get('path', None)
+ if src is None and unar is None and ds_srcpath is not None:
+ # fallback to importe:path if there is no unarchiving recipe
+ src = ds_srcpath
+ if unar is not None and ds_srcpath is None:
+ raise BadConfiguration(f'Source #{idx} of output layer "{layername}" '
+ 'has no import source path')
+ if src is None:
+ raise BadConfiguration(f'Source #{idx} of output layer "{layername}" '
+ 'has no source path')
+ layerdef['source'] = { 'path': src, 'unar': unar }
+
+ for layername in toremove:
+ layers.pop(layername)
+
+def validateLayerCacheField(defn : ogr.FeatureDefn, idx : int,
+ name : str,
+ typ : int,
+ subtyp : int = ogr.OFSTNone,
+ width : int = 0,
+ unique : Optional[bool] = None,
+ nullable : Optional[bool] = None) -> bool:
+ """Validate field #idx from the layer cache table."""
+ n = defn.GetFieldCount()
+ if idx >= n:
+ return False
+ defn = defn.GetFieldDefn(idx)
+
+ b = True
+ name2 = defn.GetName()
+ if name2 != name:
+ logging.warning('Layer cache\'s field #%d has name "%s" != "%s"', idx, name2, name)
+ b = False
+
+ if nullable is not None and defn.IsNullable() != nullable:
+ # non-fatal
+ logging.warning('Layer cache\'s field #%d ("%s") %s nullable',
+ idx, name2, 'is' if defn.IsNullable() else 'isn\'t')
+
+ if unique is not None and defn.IsUnique() != unique:
+ # non-fatal
+ logging.warning('Layer cache\'s field #%d ("%s") %s unique',
+ idx, name2, 'is' if defn.IsUnique() else 'isn\'t')
+
+ typ2 = defn.GetType()
+ if typ2 != typ:
+ logging.warning('Layer cache\'s field #%d ("%s") has type %s != %s', idx, name2,
+ ogr.GetFieldTypeName(typ2), ogr.GetFieldTypeName(typ))
+ b = False
+
+ subtyp2 = defn.GetSubType()
+ if subtyp2 != subtyp:
+ logging.warning('Layer cache\'s field #%d ("%s") has subtype %s != %s', idx, name2,
+ ogr.GetFieldSubTypeName(subtyp2), ogr.GetFieldSubTypeName(subtyp))
+ b = False
+
+ width2 = defn.GetWidth()
+ if width2 != 0 and (width == 0 or width2 < width):
+ # non-fatal
+ logging.warning('Layer cache\'s field #%d ("%s") is too small (width %d < %d)',
+ idx, name2, width2, width)
+ return b
+
+def validateCacheLayer(ds : gdal.Dataset, name : str) -> bool:
+ """Validate layer cache table."""
+ drvName = ds.GetDriver().ShortName
+ if drvName != 'PostgreSQL': # we need hash_record_extended(), sha256() and ST_AsEWKB()
+ logging.warning('Unsupported cache layer for output driver %s', drvName)
+ return False
+ lyr = ds.GetLayerByName(name)
+ if lyr is None:
+ logging.warning('Table "%s" does not exist', name)
+ return False
+
+ if not (lyr.TestCapability(ogr.OLCRandomWrite) and lyr.TestCapability(ogr.OLCUpdateFeature)):
+ logging.warning('Layer "%s" does not support OLCUpdateFeature capability, '
+ 'ignoring cache', name)
+ return False
+
+ defn = lyr.GetLayerDefn()
+ fields = [
+ { 'name': 'layername', 'typ': ogr.OFTString,
+ 'nullable': False, 'unique': True, 'width': 255 },
+ { 'name': 'last_updated', 'typ': ogr.OFTDateTime,
+ 'nullable': False },
+ { 'name': 'fingerprint', 'typ': ogr.OFTBinary,
+ 'nullable': False, 'width': 32 },
+ ]
+ m = len(fields)
+ n = defn.GetFieldCount()
+ if n < m:
+ # this is fatal, and `all(bs)` is False so we return False below
+ logging.warning('Layer cache "%s" has %d < %d fields', name, n, m)
+ elif n != m:
+ logging.warning('Layer cache "%s" has %d != %d fields', name, n, m)
+ bs = [ validateLayerCacheField(defn, i, **fld) for i,fld in enumerate(fields) ]
+ if not all(bs):
+ return False
+
+ n = defn.GetGeomFieldCount()
+ if n > 0:
+ geomFieldNames = [ escape_identifier(defn.GetGeomFieldDefn(i).GetName())
+ for i in range(n) ]
+ logging.warning('Layer cache "%s" has %d > 0 geometry field(s): %s',
+ name, n, ', '.join(geomFieldNames))
+
+ style = lyr.GetStyleTable()
+ if style is not None:
+ logging.warning('Layer cache "%s" has a style table "%s"',
+ name, style.GetLastStyleName())
+ return True
+
+def areSourceFilesNewer(layername : str,
+ sources : dict[str,Any],
+ lyrcache : ogr.Layer,
+ cachedir : Optional[Path] = None) -> bool:
+ """Return a boolean indicating whether the layer cache is up to date with
+ respect to the source files found on disk. That is, the last modification
+ and last changed time of each source file needs to be equal or lower than
+ the `last_updated` value found in the layer cache."""
+
+ source_paths = set()
+ for source in sources:
+ # the same source_path can be used multiple times, stat(2) only once
+ source_path = source['source']['path']
+ source_paths.add(source_path)
+ if len(source_paths) == 0:
+ return False
+
+ t = None
+ mtimes_ns = {}
+ for source_path in source_paths:
+ path = source_path if cachedir is None else str(cachedir.joinpath(source_path))
+ try:
+ st = os.stat(path)
+ if not S_ISREG(st.st_mode):
+ raise FileNotFoundError
+ mtimes_ns[source_path] = st.st_mtime_ns
+ # take max(mtime, ctime): if we lock source paths any update after
+ # aquiring the lock will yield a value larger than time.time_ns()
+ t2 = max(st.st_mtime_ns, st.st_ctime_ns)
+ if t is None or t < t2:
+ t = t2
+ except (OSError, ValueError):
+ #logging.warning('Could not stat(%s)', path)
+ return True
+ assert t is not None
+
+ attributeFilter = 'layername = ' + escape_literal_str(layername)
+ logging.debug('SetAttributeFilter("%s", "%s")', lyrcache.GetName(), attributeFilter)
+ lyrcache.SetAttributeFilter(attributeFilter)
+
+ feature = lyrcache.GetNextFeature()
+ if feature is None:
+ # not in cache
+ return True
+
+ if not feature.IsFieldSetAndNotNull(1):
+ ret = True
+ else:
+ # https://gdal.org/en/stable/api/python/vector_api.html#osgeo.ogr.Feature.GetFieldAsDateTime
+ # [ year, month, day, hour, minute, second, timezone flag ]
+ dt = feature.GetFieldAsDateTime(1)
+ if dt[6] == ogr.TZFLAG_UNKNOWN:
+ logging.warning('Datetime specified with unknown timezone in layer cache\'s '
+ 'field #%d "%s", assuming local time', 1,
+ feature.GetDefnRef().GetFieldDefn(1).GetName())
+ tz = None
+ elif dt[6] == ogr.TZFLAG_LOCALTIME:
+ tz = None
+ elif dt[6] == ogr.TZFLAG_UTC:
+ tz = UTC
+ else:
+ tz = timezone(offset=timedelta(seconds=(dt[6] - ogr.TZFLAG_UTC) * 900))
+ ms, s = modf(dt[5])
+ dt = datetime(
+ year=dt[0], # including century
+ month=dt[1], # 01 ≤ year ≤ 12
+ day=dt[2], # 01 ≤ day ≤ 31
+ hour=dt[3], # 00 ≤ hour ≤ 23
+ minute=dt[4], # 00 ≤ minute ≤ 59
+ second=int(s), # 00 ≤ second ≤ 59
+ microsecond=round(ms*1000000),
+ tzinfo=tz
+ )
+ fpr = feature.GetFieldAsBinary(2) if feature.IsFieldSetAndNotNull(2) else None
+ logging.debug('Found entry in layer cache for "%s", last_updated=%s, fingerprint=%s',
+ layername,
+ dt.isoformat(timespec='microseconds'),
+ fpr.hex() if fpr is not None else 'NULL')
+ ret = int(dt.timestamp() * 1000000.) * 1000 < t
+
+ if lyrcache.GetNextFeature() is not None:
+ raise RuntimeError(f'Duplicate key {layername}')
+
+ if not ret:
+ for source_path, mtime_ns in sorted(mtimes_ns.items()):
+ # XXX datetime.fromtimestamp() doesn't support nanosecond input
+ # https://github.com/python/cpython/issues/59648
+ mtime = (mtime_ns // 1000) / 1000000.
+ dt = datetime.fromtimestamp(mtime)
+ logging.info('Source file %s is unchanged (last modification time %s)',
+ source_path, dt.astimezone().isoformat(timespec='seconds'))
+ return ret
+
+def getLastMTimes(layerdefs : dict[str,Any], basedir : Optional[Path] = None) -> dict[str,int]:
+ """Return a directing mapping source paths to their last modification time
+ (as a timestamp in milliseconds)."""
+ ret = {}
+ for layerdef in layerdefs:
+ for source in layerdef['sources']:
+ source_path = source['source']['path']
+ if source_path in ret:
+ continue
+ path = source_path if basedir is None else str(basedir.joinpath(source_path))
+ try:
+ st = os.stat(path)
+ if not S_ISREG(st.st_mode):
+ raise FileNotFoundError
+ ret[source_path] = st.st_mtime_ns // 1000000
+ except (OSError, ValueError):
+ #logging.warning('Could not stat(%s)', path)
+ pass
+ return ret
+
+def lockSourcePaths(layerdefs : dict[str,Any], lockdir: str) -> dict[str,int]:
+ """Place shared locks on each source path and return their respective file
+ descriptors. We could do that one layerdef at a time (one output layer at a
+ time) to reduce the time during which the sources prevented from being
+ updated/downloaded, but their is some value in having consistency across the
+ whole import process."""
+ umask = os.umask(0o002)
+ lockdir_fd = os.open(lockdir, O_RDONLY|O_CLOEXEC|O_PATH|O_DIRECTORY)
+ try:
+ ret = {}
+ for layerdef in layerdefs:
+ for source in layerdef['sources']:
+ source_path = source['source']['path']
+ if source_path in ret:
+ continue
+ lockfile = getSourcePathLockFileName(source_path)
+ lock_fd = os.open(lockfile, O_WRONLY|O_CREAT|O_CLOEXEC, mode=0o664,
+ dir_fd=lockdir_fd)
+ logging.debug('Acquiring shared lock for %s: flock("%s", LOCK_SH)',
+ source_path, lockfile)
+ flock(lock_fd, LOCK_SH)
+ ret[source_path] = lock_fd
+ return ret
+ finally:
+ try:
+ os.close(lockdir_fd)
+ except (OSError, ValueError):
+ logging.exception('Could not close lockdir')
+ os.umask(umask)
+
+def releaseSourcePathLocks(lock_fds : dict[str,int]) -> None:
+ """Release shared locks on the source paths. Closed FDs are removed from
+ the dictionary in place."""
+ toremove = set()
+ for path, lock_fd in lock_fds.items():
+ try:
+ os.close(lock_fd)
+ except (OSError, ValueError):
+ logging.exception('Could not release lock for %s', path)
+ else:
+ logging.debug('Released lock for %s', path)
+ toremove.add(path)
+ for path in toremove:
+ lock_fds.pop(path)
+
+# pylint: disable-next=missing-function-docstring, too-many-branches, too-many-statements
+def main() -> NoReturn:
+ common.init_logger(app=os.path.basename(__file__), level=logging.INFO)
+
+ parser = argparse.ArgumentParser(description='Extract and import GIS layers.')
+ parser.add_argument('--cachedir', default=None,
+ help=f'cache directory (default: {os.curdir})')
+ parser.add_argument('--debug', action='count', default=0,
+ help=argparse.SUPPRESS)
+ parser.add_argument('--lockfile', default=None,
+ help='obtain an exclusive lock before processing')
+ parser.add_argument('--lockdir-sources', default=None,
+ help='optional directory for lock files to source paths')
+ parser.add_argument('--mvtdir', default=None,
+ help='optional directory for Mapbox Vector Tiles (MVT)')
+ parser.add_argument('--mvt-compress', default=False, action='store_true',
+ help='whether to compress Mapbox Vector Tiles (MVT) files')
+ parser.add_argument('--rasterdir', default=None,
+ help='optional directory for raster files')
+ parser.add_argument('--metadata-compress', default=False, action='store_true',
+ help='whether to compress metadata.json files')
+ parser.add_argument('--force', default=False, action='store_true',
+ help='import even if no new changes were detected')
+ parser.add_argument('groupname', nargs='*', help='group layer name(s) to process')
+ args = parser.parse_args()
+
+ if args.debug > 0: # pylint: disable=duplicate-code
+ logging.getLogger().setLevel(logging.DEBUG)
+ if args.debug > 1:
+ gdal.ConfigurePythonLogging(enable_debug=True)
+
+ config = common.parse_config(groupnames=None if args.groupname == [] else args.groupname)
+
+ # validate configuration
+ if 'dataset' not in config:
+ raise BadConfiguration('Configuration does not specify output dataset')
+
+ layers = config.get('layers', {})
+ validate_sources(layers)
+
+ # set global GDAL/OGR configuration options
+ for pszKey, pszValue in config.get('GDALconfig', {}).items():
+ logging.debug('gdal.SetConfigOption(%s, %s)', pszKey, pszValue)
+ gdal.SetConfigOption(pszKey, pszValue)
+
+ # get configured Spatial Reference System and extent
+ srs = getSRS(config.get('SRS', None))
+ extent = getExtent(config.get('extent', None), srs=srs)
+
+ if args.lockfile is not None:
+ # obtain an exclusive lock and don't release it until exiting the program
+ lock_fd = os.open(args.lockfile, O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, mode=0o644)
+ logging.debug('flock("%s", LOCK_EX)', args.lockfile)
+ flock(lock_fd, LOCK_EX)
+
+ if args.mvtdir is not None:
+ args.mvtdir = Path(args.mvtdir)
+ if args.mvtdir == Path(): # make sure it's not curdir as we don't want to exchange it
+ raise RuntimeError('Invalid value for --mvtdir')
+ args.mvtdir.parent.mkdir(parents=True, exist_ok=True)
+
+ if args.cachedir is not None:
+ args.cachedir = Path(args.cachedir)
+ if args.lockdir_sources is None:
+ sourcePathLocks = None
+ else:
+ sourcePathLocks = lockSourcePaths(layerdefs=layers.values(),
+ lockdir=args.lockdir_sources)
+
+ # special handling for raster layers
+ if any(l.get('type') == 'raster' for l in layers.values()):
+ if not all(l.get('type') == 'raster' for l in layers.values()):
+ raise NotImplementedError('Mix of raster and vector layers is not supported')
+ if args.rasterdir is None:
+ raise RuntimeError('Missing required value for --rasterdir')
+ if len(layers) != 1:
+ raise RuntimeError('Raster layers need to be processed one at a time')
+ args.rasterdir = Path(args.rasterdir)
+ if args.rasterdir == Path(): # make sure it's not curdir as we don't want to exchange it
+ raise RuntimeError('Invalid value for --rasterdir')
+ args.rasterdir.parent.mkdir(parents=True, exist_ok=True)
+ last_modified = getLastMTimes(layerdefs=layers.values(), basedir=args.cachedir)
+ rv = 0
+ for layername, layerdef in layers.items():
+ try:
+ processRaster(layername, layerdef,
+ sources=parse_config_dl(config.get('downloads', [])),
+ license_info=config.get('license-info', {}),
+ last_modified=last_modified,
+ dst=args.rasterdir,
+ cachedir=args.cachedir,
+ extent=extent,
+ compress_metadata=args.metadata_compress)
+ except Exception: # pylint: disable=broad-exception-caught
+ rv = 1
+ traceback.print_exc()
+ sys.exit(rv)
+
+ # open output dataset (possibly create it first)
+ dso = openOutputDS(config['dataset'])
+
+ validate_schema(layers,
+ drvo=dso.GetDriver(),
+ lco_defaults=config['dataset'].get('create-layer-options', None))
+
+ # create all output layers before starting the transaction
+ for layername, layerdef in layers.items():
+ lyr = dso.GetLayerByName(layername)
+ if lyr is not None:
+ # TODO dso.DeleteLayer(layername) if --overwrite and
+ # dso.TestCapability(ogr.ODsCDeleteLayer)
+ # (Sets OVERWRITE=YES for PostgreSQL and GPKG.)
+ continue
+ if not dso.TestCapability(ogr.ODsCCreateLayer):
+ raise RuntimeError(f'Output driver {dso.GetDriver().ShortName} does not '
+ 'support layer creation')
+ createOutputLayer(dso, layername, srs=srs, options=layerdef.get('create', None))
+
+ if (dso.TestCapability(ogr.ODsCTransactions) and
+ # we need SAVEPOINT support
+ dso.GetDriver().ShortName in ('PostgreSQL', 'SQLite', 'GPKG')):
+ logging.debug('Starting transaction')
+ dsoTransaction = dso.StartTransaction() == ogr.OGRERR_NONE
+ else:
+ logging.warning('Output driver %s does not support dataset transactions or SQL SAVEPOINTs',
+ dso.GetDriver().ShortName)
+ dsoTransaction = False
+
+ # validate layer cache
+ lyr_cache = config['dataset'].get('layercache', None)
+ if lyr_cache is None:
+ pass
+ elif validateCacheLayer(dso, lyr_cache):
+ lyr_cache = dso.GetLayerByName(lyr_cache)
+ else:
+ if not args.force:
+ logging.warning('Ignoring invalid layer cache "%s" (implying --force)', lyr_cache)
+ args.force = True
+ lyr_cache = None
+
+ rv = 0
+ try:
+ r = {}
+ n = 0
+ start = time_monotonic()
+ for layername, layerdef in layers.items():
+ r[layername] = r0 = processOutputLayer(dso, layername, layerdef,
+ srs=srs,
+ cachedir=args.cachedir,
+ extent=extent,
+ dsTransaction=dsoTransaction,
+ lyrcache=lyr_cache,
+ force=args.force)
+ n += 1
+ logging.info('Import result status for layer "%s": %s', layername, str(r0))
+ if r0 == ImportStatus.IMPORT_ERROR:
+ rv = 1
+ if dsoTransaction:
+ dsoTransaction = False
+ logging.debug('Rolling back transaction')
+ # no need to catch the exception here
+ if dso.CommitTransaction() != ogr.OGRERR_NONE:
+ logging.error('Could not rollback transaction')
+ break
+ elapsed = time_monotonic() - start
+ logging.info('Processed %d destination layers in %s', n, common.format_time(elapsed))
+
+ # get mtimes before releasing the source locks
+ last_modified = getLastMTimes(layerdefs=layers.values(), basedir=args.cachedir)
+
+ if sourcePathLocks is not None:
+ releaseSourcePathLocks(sourcePathLocks)
+
+ export_layers = { l:d for l,d in layers.items() if d.get('publish', None) is not None }
+ if args.mvtdir is None or any(r0 == ImportStatus.IMPORT_ERROR for r0 in r.values()):
+ pass
+ elif len(export_layers) == 0:
+ logging.warning('--mvtdir option used but no layer has a publication definition')
+ elif (all(r0 == ImportStatus.IMPORT_NOCHANGE for l,r0 in r.items() if l in export_layers)
+ and args.mvtdir.is_dir()):
+ logging.info('Skipping MVT export for group %s (no changes)',
+ ', '.join(args.groupname) if args.groupname is not None else '*')
+ else:
+ exportMVT(dso,
+ layers=export_layers,
+ sources=parse_config_dl(config.get('downloads', [])),
+ license_info=config.get('license-info', {}),
+ last_modified=last_modified,
+ dst=args.mvtdir,
+ default_options=config.get('vector-tiles', None),
+ compress=args.mvt_compress,
+ compress_metadata=args.metadata_compress)
+
+ if dsoTransaction:
+ dsoTransaction = False
+ logging.debug('Committing transaction')
+ if dso.CommitTransaction() != ogr.OGRERR_NONE:
+ logging.error('Could not commit transaction')
+ rv = 1
+
+ except Exception: # pylint: disable=broad-exception-caught
+ if dsoTransaction:
+ logging.exception('Exception occured within transaction, rolling back')
+ try:
+ if dso.RollbackTransaction() != ogr.OGRERR_NONE:
+ logging.error('Could not rollback transaction')
+ except Exception: # pylint: disable=broad-exception-caught
+ logging.exception('Could not rollback transaction')
+ else:
+ traceback.print_exc()
+ sys.exit(1)
+
+ finally:
+ lyr_cache = None
+ dso = None
+ extent = None
+ srs = None
+ sys.exit(rv)
+
+gdal.UseExceptions()
+main()
diff --git a/geodata-import-topo b/geodata-import-topo
new file mode 100755
index 0000000..e58a701
--- /dev/null
+++ b/geodata-import-topo
@@ -0,0 +1,350 @@
+#!/usr/bin/python3
+
+#----------------------------------------------------------------------
+# Import Lantmäteriet's Topografi Vektor products.
+# Copyright © 2026 Guilhem Moulin <guilhem@fripost.org>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+#----------------------------------------------------------------------
+
+# pylint: disable=invalid-name, missing-module-docstring, fixme
+
+from os import O_RDONLY, O_WRONLY, O_CREAT, O_TRUNC, O_CLOEXEC, O_PATH, O_DIRECTORY
+import os
+from fcntl import flock, LOCK_EX, LOCK_SH
+import logging
+import argparse
+import zipfile
+import tempfile
+from typing import Any, Final, NoReturn, Optional
+from pathlib import Path
+import sys
+import traceback
+from time import monotonic as time_monotonic
+
+from osgeo import gdal, ogr, osr
+from osgeo.gdalconst import (
+ CE_None as GDAL_CE_None,
+ OF_READONLY as GDAL_OF_READONLY,
+ OF_VECTOR as GDAL_OF_VECTOR,
+ OF_VERBOSE_ERROR as GDAL_OF_VERBOSE_ERROR,
+)
+
+import common
+from common import BadConfiguration, getSourcePathLockFileName
+from common_gdal import getSRS, getExtent, gdalSetOpenExArgs
+from import_source import (
+ openOutputDS,
+ createOutputLayer,
+ validateOutputLayer,
+ importLayer,
+ clearLayer,
+ clusterLayer,
+)
+
+def get_layer_schema(layer : ogr.Layer) -> dict[str, Any]:
+ """Return the layer definition dictionary for the given OGR layer."""
+ schema = {}
+ layer_name = layer.GetName()
+ defn = layer.GetLayerDefn()
+ n = defn.GetGeomFieldCount()
+ if n != 1:
+ raise NotImplementedError(f'Layer "{layer_name}" has geometry field count {n} != 1')
+ geom_fld = defn.GetGeomFieldDefn(0)
+ if geom_fld.IsIgnored():
+ raise NotImplementedError(f'Geometry field #0 in layer "{layer_name}" is ignored')
+ schema['geometry-type'] = geom_fld.GetType()
+
+ layer_name_lower = layer_name.lower()
+ fields = schema['fields'] = []
+ for i in range(defn.GetFieldCount()):
+ fld = defn.GetFieldDefn(i)
+ fld_name = fld.GetName()
+ fld_name_lower = fld_name.lower()
+ if fld.IsIgnored():
+ logging.warning('Field #%d "%s" in source layer "%s" is ignored',
+ i, fld_name, layer_name)
+ continue
+ field = { 'Name': fld_name }
+ fields.append(field)
+
+ if fld_name_lower in ('objektidentitet', 'skapad', 'objekttypnr', 'objekttyp'):
+ field['Nullable'] = False
+ else:
+ field['Nullable'] = fld.IsNullable()
+ field['Unique'] = fld.IsUnique()
+
+ field['AlternativeName'] = fld.GetAlternativeName()
+ field['Comment'] = fld.GetComment()
+
+ fld_type = field['Type'] = fld.GetType()
+ if (layer_name_lower, fld_name_lower) in (('lansyta', 'lanskod'),
+ ('kommunyta', 'kommunkod')):
+ fld_type = field['Type'] = ogr.OFTInteger
+ field['SubType'] = ogr.OFSTInt16
+ field['Nullable'] = False
+ field['Unique'] = True
+ elif fld_type == ogr.OFTString and fld_name_lower == 'objektidentitet':
+ field['SubType'] = ogr.OFSTUUID
+ else:
+ field['SubType'] = fld.GetSubType()
+ field['Width'] = fld.GetWidth()
+ field['Precision'] = fld.GetPrecision()
+ field['Justify'] = fld.GetJustify()
+ if fld_type in (ogr.OFTTime, ogr.OFTDate, ogr.OFTDateTime):
+ field['TZFlag'] = fld.GetTZFlag()
+
+ # TODO fail if generated or has default
+ #print(fld.GetDefault(), fld.IsDefaultDriverSpecific())
+ #print(fld.GetDomainName())
+ #print(fld.IsGenerated())
+
+ return schema
+
+
+def get_output_layer(layer_src : ogr.Layer, dso : gdal.Dataset,
+ layername_dst : str,
+ srs : Optional[osr.SpatialReference] = None,
+ create_layer_options : Optional[dict[str,Any]] = None) -> ogr.Layer:
+ """Get the destination layer to mirror the source to. It is
+ automatically created if needs be."""
+ layer_dst = dso.GetLayerByName(layername_dst)
+ schema = get_layer_schema(layer_src)
+ if layer_dst is None:
+ schema['options'] = options = []
+ if create_layer_options is not None:
+ options += [ k + '=' + str(v) for k, v in create_layer_options.items() ]
+ layer_dst = createOutputLayer(dso, layername_dst, srs=srs, options=schema)
+
+ validateOutputLayer(layer_dst, srs=srs, options=schema)
+
+ return layer_dst
+
+
+LAYER_NAMES : Final[set[tuple[str|None,str]]] = set()
+def import_layer(layer : ogr.Layer, dso : gdal.Dataset, filename : str,
+ srs : Optional[osr.SpatialReference] = None,
+ schema : Optional[str] = None,
+ create_layer_options : Optional[dict[str,Any]] = None) -> None:
+ """Import a give layer to PostGIS"""
+ layer_name = layer.GetName()
+ k = (schema, layer_name)
+ if k in LAYER_NAMES:
+ raise RuntimeError(f'Duplicate layer "{layer_name}" in schema {schema}')
+ LAYER_NAMES.add(k)
+ logging.info('Importing layer %s from %s to schema %s', layer_name, filename, schema)
+
+ layer_dst = get_output_layer(layer, dso=dso,
+ layername_dst=layer_name if schema is None else
+ schema + '.' + layer_name,
+ srs=srs,
+ create_layer_options=create_layer_options)
+
+ description = layer.GetMetadataItem('DESCRIPTION')
+ if (description is not None and
+ layer_dst.SetMetadataItem('DESCRIPTION', description) != GDAL_CE_None):
+ logging.warning('Could not set description metadata')
+
+ clearLayer(layer_dst, identity='RESTART IDENTITY')
+ defn_dst = layer_dst.GetLayerDefn()
+ field_map = { defn_dst.GetFieldDefn(i).GetName() : i for i in range(defn_dst.GetFieldCount()) }
+ importLayer(layer_dst, layer, args={'field-map': field_map}, extent=None)
+
+ if layer_dst.GetLayerDefn().GetGeomType() != ogr.wkbNone:
+ clusterLayer(layer_dst, column_name=layer_dst.GetGeometryColumn())
+
+def guess_schema_from_file(path : str) -> str:
+ """Infer PostgreSQL schema name from the filename of the .zip source."""
+ stem = Path(path).stem
+ topomap = { 'topo1m': 'topo1000' }
+ for l in (1000, 250, 100, 50, 10):
+ l = 'topo' + str(l)
+ topomap[l] = l
+ try:
+ return 'lm_' + topomap[stem.lower()]
+ except KeyError as e:
+ raise RuntimeError(f'Could not guess schema name from input filename {path}') from e
+
+def import_source(path : str, dso : gdal.Dataset,
+ srs : Optional[osr.SpatialReference] = None,
+ schema : Optional[str] = None,
+ create_layer_options : Optional[dict[str,Any]] = None,
+ lockdir_fd: int|None = None) -> tuple[bool,int]:
+ """Import a single topo$FOO.zip source to PostGIS transactionally"""
+ if schema is None:
+ schema = guess_schema_from_file(path)
+ if lockdir_fd is None:
+ lock_fd = None
+ else:
+ lockfile = getSourcePathLockFileName(path)
+ lock_fd = os.open(lockfile, O_WRONLY|O_CREAT|O_CLOEXEC, mode=0o664,
+ dir_fd=lockdir_fd)
+ dso_transaction = False
+ n = 0
+ try:
+ if lock_fd is not None:
+ logging.debug('Acquiring shared lock for %s: flock("%s", LOCK_SH)',
+ path, lockfile)
+ flock(lock_fd, LOCK_SH)
+ if dso.TestCapability(ogr.ODsCTransactions):
+ logging.debug('Starting transaction')
+ dso_transaction = dso.StartTransaction() == ogr.OGRERR_NONE
+ n = import_source2(path, dso, srs=srs, schema=schema,
+ create_layer_options=create_layer_options)
+ if dso_transaction:
+ logging.debug('Committing transaction')
+ dso_transaction = False
+ if dso.CommitTransaction() != ogr.OGRERR_NONE:
+ logging.error('Could not commit transaction')
+ return True, n
+ except Exception: # pylint: disable=broad-exception-caught
+ traceback.print_exc()
+ if dso_transaction:
+ logging.debug('Rolling back transaction')
+ # no need to catch the exception here
+ if dso.CommitTransaction() != ogr.OGRERR_NONE:
+ logging.error('Could not rollback transaction')
+ finally:
+ if lock_fd is not None:
+ try:
+ os.close(lock_fd)
+ except (OSError, ValueError):
+ logging.exception('Could not close lockfile for %s', path)
+ return False, n
+
+def import_source2(path : str, dso : gdal.Dataset,
+ srs : Optional[osr.SpatialReference] = None,
+ schema : Optional[str] = None,
+ create_layer_options : Optional[dict[str,Any]] = None) -> int:
+ """Import a single shape file, or recursively all shape files
+ containing in a .zip file, to PostGIS."""
+ n = 0
+ if path.lower().endswith('.zip') and zipfile.is_zipfile(path):
+ logging.debug('Opening %s as ZipFile', path)
+ with zipfile.ZipFile(path, mode='r') as z:
+ for zi in z.infolist():
+ if zi.is_dir():
+ raise NotImplementedError(f'{zi.filename}: Zipped directories are '
+ 'not supported')
+ if zi.filename == 'uttag.json':
+ continue
+ with tempfile.TemporaryDirectory() as tmpdir:
+ if logging.getLogger().getEffectiveLevel() == logging.DEBUG:
+ logging.debug('Extracting %s from %s into %s/',
+ zi.filename, path, tmpdir.removesuffix('/'))
+ elif not zi.filename.lower().endswith('.zip'):
+ logging.info('Extracting %s', zi.filename)
+ p = z.extract(zi, path=tmpdir)
+ n += import_source2(p, dso=dso, srs=srs, schema=schema,
+ create_layer_options=create_layer_options)
+ return n
+
+ kwargs, _ = gdalSetOpenExArgs({}, flags=GDAL_OF_VECTOR|GDAL_OF_READONLY|GDAL_OF_VERBOSE_ERROR)
+ logging.debug('OpenEx(%s, %s)', path, str(kwargs))
+ ds = gdal.OpenEx(path, **kwargs)
+ if ds is None:
+ raise RuntimeError(f'Could not open {path}')
+
+ n = ds.GetLayerCount()
+ logging.debug('Opened %s (driver %s, %d layers)', path, ds.GetDriver().ShortName, n)
+ filename = Path(path).name
+ for i in range(n):
+ import_layer(layer=ds.GetLayerByIndex(i), dso=dso, filename=filename,
+ srs=srs, schema=schema,
+ create_layer_options=create_layer_options)
+ return n
+
+
+# pylint: disable-next=missing-function-docstring
+def main() -> NoReturn:
+ common.init_logger(app=os.path.basename(__file__), level=logging.INFO)
+
+ parser = argparse.ArgumentParser(description='Import Lantmäteriets Topografi products.')
+ parser.add_argument('--cachedir', default=None,
+ help=f'cache directory (default: {os.curdir})')
+ parser.add_argument('--debug', action='count', default=0,
+ help=argparse.SUPPRESS)
+ parser.add_argument('--schema', default=None, help='PostgreSQL schema name')
+ parser.add_argument('--lockfile', default=None,
+ help='obtain an exclusive lock before processing')
+ parser.add_argument('--lockdir-sources', default=None,
+ help='optional directory for lock files to source paths')
+ parser.add_argument('input', nargs='+', metavar='topo.zip', help='zipfile(s) to process')
+ args = parser.parse_args()
+
+ if args.debug > 0: # pylint: disable=duplicate-code
+ logging.getLogger().setLevel(logging.DEBUG)
+ if args.debug > 1:
+ gdal.ConfigurePythonLogging(enable_debug=True)
+
+ config = common.parse_config()
+
+ # validate configuration
+ if 'dataset' not in config:
+ raise BadConfiguration('Configuration does not specify output dataset')
+
+ # set global GDAL/OGR configuration options
+ # pylint: disable=duplicate-code
+ for pszKey, pszValue in config.get('GDALconfig', {}).items():
+ logging.debug('gdal.SetConfigOption(%s, %s)', pszKey, pszValue)
+ gdal.SetConfigOption(pszKey, pszValue)
+
+ # get configured Spatial Reference System and extent
+ srs = getSRS(config.get('SRS', None))
+ _extent = getExtent(config.get('extent', None), srs=srs)
+
+ if args.lockfile is not None:
+ # obtain an exclusive lock and don't release it until exiting the program
+ lock_fd = os.open(args.lockfile, O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, mode=0o644)
+ logging.debug('flock("%s", LOCK_EX)', args.lockfile)
+ flock(lock_fd, LOCK_EX)
+ # pylint: enable=duplicate-code
+
+ # open output dataset (possibly create it first)
+ dso = openOutputDS(config['dataset'])
+
+ if args.cachedir is not None:
+ args.cachedir = Path(args.cachedir)
+
+ if args.lockdir_sources is None:
+ umask = lockdir_fd = None
+ else:
+ umask = os.umask(0o002)
+ lockdir_fd = os.open(args.lockdir_sources, O_RDONLY|O_CLOEXEC|O_PATH|O_DIRECTORY)
+ rv = 0
+ try:
+ for path in args.input:
+ start = time_monotonic()
+ b, n = import_source(path if args.cachedir is None
+ else str(args.cachedir.joinpath(path)),
+ dso, srs=srs, lockdir_fd=lockdir_fd,
+ schema=args.schema,
+ create_layer_options=config['dataset'].get('create-layer-options',
+ None))
+ if not b:
+ rv = 1
+ logging.info('Imported %d layers from %s in %s', n, path,
+ common.format_time(time_monotonic() - start))
+ finally:
+ if lockdir_fd is not None:
+ try:
+ os.close(lockdir_fd)
+ except (OSError, ValueError):
+ logging.exception('Could not close lockdir')
+ if umask is not None:
+ os.umask(umask)
+ sys.exit(rv)
+
+gdal.UseExceptions()
+main()
diff --git a/import_source.py b/import_source.py
new file mode 100644
index 0000000..f802a57
--- /dev/null
+++ b/import_source.py
@@ -0,0 +1,1153 @@
+#!/usr/bin/python3
+
+#----------------------------------------------------------------------
+# Backend utilities for the Klimatanalys Norr project (import source layers)
+# Copyright © 2024-2025 Guilhem Moulin <info@guilhem.se>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+#----------------------------------------------------------------------
+
+# pylint: disable=invalid-name, missing-module-docstring, fixme
+
+import logging
+import tempfile
+import re
+from fnmatch import fnmatchcase
+from pathlib import Path
+from datetime import datetime, timedelta, UTC
+from typing import Any, Callable, Final, Iterator, Optional
+import traceback
+from enum import Enum, unique as enum_unique
+from hashlib import sha256
+import struct
+
+from osgeo import gdal, ogr, osr
+from osgeo.gdalconst import (
+ OF_ALL as GDAL_OF_ALL,
+ OF_READONLY as GDAL_OF_READONLY,
+ OF_UPDATE as GDAL_OF_UPDATE,
+ OF_VECTOR as GDAL_OF_VECTOR,
+ OF_VERBOSE_ERROR as GDAL_OF_VERBOSE_ERROR,
+ DCAP_CREATE as GDAL_DCAP_CREATE,
+)
+from osgeo import gdalconst
+
+from common import BadConfiguration, escape_identifier, escape_literal_str
+from common_gdal import (
+ gdalSetOpenExArgs,
+ gdalGetMetadataItem,
+ formatTZFlag,
+ getSpatialFilterFromGeometry,
+ getEscapedTableName,
+ executeSQL,
+)
+
+def openOutputDS(def_dict : dict[str, Any]) -> gdal.Dataset:
+ """Open and return the output DS. It is created if create=False or
+ create-options is a non-empty dictionary."""
+
+ path = def_dict['path']
+ kwargs, drv = gdalSetOpenExArgs(def_dict,
+ flags=GDAL_OF_VECTOR|GDAL_OF_UPDATE|GDAL_OF_VERBOSE_ERROR)
+ try:
+ logging.debug('OpenEx(%s, %s)', path, str(kwargs))
+ return gdal.OpenEx(path, **kwargs)
+ except RuntimeError as e:
+ if not (gdal.GetLastErrorType() >= gdalconst.CE_Failure and
+ gdal.GetLastErrorNo() == gdalconst.CPLE_OpenFailed):
+ # not an open error
+ raise e
+
+ dso2 = None
+ try:
+ dso2 = gdal.OpenEx(path, nOpenFlags=GDAL_OF_ALL | GDAL_OF_UPDATE)
+ except RuntimeError:
+ pass
+ if dso2 is not None:
+ # path exists but can't be open with OpenEx(path, **kwargs)
+ raise e
+
+ try:
+ dso2 = gdal.OpenEx(path, nOpenFlags=GDAL_OF_ALL)
+ except RuntimeError:
+ pass
+ if dso2 is not None:
+ # path exists but can't be open with OpenEx(path, **kwargs)
+ raise e
+
+ dsco = def_dict.get('create-options', None)
+ if not def_dict.get('create', False) and dsco is None:
+ # not configured for creation
+ raise e
+ if drv is None or not gdalGetMetadataItem(drv, GDAL_DCAP_CREATE):
+ # not capable of creation
+ raise e
+
+ if 'open_options' in kwargs:
+ # like ogr2ogr(1)
+ logging.warning('Destination\'s open options ignored '
+ 'when creating the output datasource')
+
+ kwargs2 = { 'eType': gdalconst.GDT_Unknown }
+ if dsco is not None:
+ kwargs2['options'] = [ k + '=' + str(v) for k, v in dsco.items() ]
+
+ logging.debug('Create(%s, %s, eType=%s%s)', drv.ShortName, path, kwargs2['eType'],
+ ', options=' + str(kwargs2['options']) if 'options' in kwargs2 else '')
+ # XXX racy, a GDAL equivalent of O_EXCL would be nice
+ return drv.Create(path, 0, 0, 0, **kwargs2)
+
+def createOutputLayer(ds : gdal.Dataset,
+ layername : str,
+ srs : Optional[osr.SpatialReference] = None,
+ options : dict[str, Any]|None = None) -> ogr.Layer:
+ """Create output layer."""
+
+ if options is None or len(options) < 1:
+ raise BadConfiguration(f'Missing schema for new output layer "{layername}"')
+
+ logging.info('Creating new destination layer "%s"', layername)
+ geom_type = options['geometry-type']
+ lco = options.get('options', None)
+
+ drv = ds.GetDriver()
+ if geom_type != ogr.wkbNone and drv.ShortName == 'PostgreSQL':
+ # “Important to set to 2 for 2D layers as it has constraints on the geometry
+ # dimension during loading.”
+ # — https://gdal.org/drivers/vector/pg.html#layer-creation-options
+ if ogr.GT_HasM(geom_type):
+ if ogr.GT_HasZ(geom_type):
+ dim = 'XYZM'
+ else:
+ dim = 'XYM'
+ elif ogr.GT_HasZ(geom_type):
+ dim = '3'
+ else:
+ dim = '2'
+ if lco is None:
+ lco = []
+ lco = ['DIM=' + dim] + lco # prepend DIM=
+
+ kwargs = { 'geom_type': geom_type }
+ if srs is not None:
+ kwargs['srs'] = srs
+ if lco is not None:
+ kwargs['options'] = lco
+ logging.debug('CreateLayer(%s, geom_type="%s"%s%s)', layername,
+ ogr.GeometryTypeToName(geom_type),
+ ', srs="' + kwargs['srs'].GetName() + '"' if 'srs' in kwargs else '',
+ ', options=' + str(kwargs['options']) if 'options' in kwargs else '')
+ lyr = ds.CreateLayer(layername, **kwargs)
+ if lyr is None:
+ raise RuntimeError(f'Could not create destination layer "{layername}"')
+
+ fields = options['fields']
+ if len(fields) > 0 and not lyr.TestCapability(ogr.OLCCreateField):
+ raise RuntimeError(f'Destination layer "{layername}" lacks field creation capability')
+
+ # set up output schema
+ for fld in fields:
+ fldName = fld['Name']
+ defn = ogr.FieldDefn()
+ defn.SetName(fldName)
+
+ if 'AlternativeName' in fld:
+ v = fld['AlternativeName']
+ logging.debug('Set AlternativeName="%s" on output field "%s"', str(v), fldName)
+ defn.SetAlternativeName(v)
+
+ if 'Comment' in fld:
+ v = fld['Comment']
+ logging.debug('Set Comment="%s" on output field "%s"', str(v), fldName)
+ defn.SetComment(v)
+
+ if 'Type' in fld:
+ v = fld['Type']
+ logging.debug('Set Type=%d (%s) on output field "%s"',
+ v, ogr.GetFieldTypeName(v), fldName)
+ defn.SetType(v)
+
+ if 'SubType' in fld:
+ v = fld['SubType']
+ logging.debug('Set SubType=%d (%s) on output field "%s"',
+ v, ogr.GetFieldSubTypeName(v), fldName)
+ defn.SetSubType(v)
+
+ if 'TZFlag' in fld:
+ v = fld['TZFlag']
+ logging.debug('Set TZFlag=%d (%s) on output field "%s"',
+ v, formatTZFlag(v), fldName)
+ defn.SetTZFlag(v)
+
+ if 'Precision' in fld:
+ v = fld['Precision']
+ logging.debug('Set Precision=%d on output field "%s"', v, fldName)
+ defn.SetPrecision(v)
+
+ if 'Width' in fld:
+ v = fld['Width']
+ logging.debug('Set Width=%d on output field "%s"', v, fldName)
+ defn.SetWidth(v)
+
+ if 'Default' in fld:
+ v = fld['Default']
+ logging.debug('Set Default=%s on output field "%s"', v, fldName)
+ defn.SetDefault(v)
+
+ if 'Nullable' in fld:
+ v = fld['Nullable']
+ logging.debug('Set Nullable=%s on output field "%s"', v, fldName)
+ defn.SetNullable(v)
+
+ if 'Unique' in fld:
+ v = fld['Unique']
+ logging.debug('Set Unique=%s on output field "%s"', v, fldName)
+ defn.SetUnique(v)
+
+ if lyr.CreateField(defn, approx_ok=False) != gdalconst.CE_None:
+ raise RuntimeError(f'Could not create field "{fldName}"')
+ logging.debug('Added field "%s" to output layer "%s"', fldName, layername)
+
+ if lyr.TestCapability(ogr.OLCAlterGeomFieldDefn):
+ # it appears using .CreateLayerFromGeomFieldDefn() on a a non-nullable
+ # GeomFieldDefn doesn't do anything, so we alter it after the fact instead
+ # (GPKG doesn't support this, use GEOMETRY_NULLABLE=NO in layer creation
+ # options instead)
+ flags = drv.GetMetadataItem(gdal.DMD_ALTER_GEOM_FIELD_DEFN_FLAGS)
+ if flags is not None and 'nullable' in flags.lower().split(' '):
+ geom_field = ogr.GeomFieldDefn(None, geom_type)
+ geom_field.SetNullable(False)
+ lyr.AlterGeomFieldDefn(0, geom_field, ogr.ALTER_GEOM_FIELD_DEFN_NULLABLE_FLAG)
+
+ # TODO evaluate use external storage not main storage for geometries
+ # https://blog.cleverelephant.ca/2018/09/postgis-external-storage.html
+
+ # sync before calling StartTransaction() so we're not trying to rollback changes
+ # on a non-existing table
+ lyr.SyncToDisk()
+ return lyr
+
+def clusterLayer(lyr : ogr.Layer,
+ index_name : Optional[str] = None,
+ column_name : Optional[str] = None,
+ analyze : bool = True) -> bool:
+ """Cluster a table according to an index. If no index name is given and a column name is
+ given instead, then the index involving the least number of columns (including the given
+ column) is chosen. If neither index name or column name is given, then recluster the table
+ using the same index as before. An optional boolean (default value: True) indicates whether
+ to ANALYZE the table after clustering. See
+ https://www.postgresql.org/docs/current/sql-cluster.html .
+ Requires that the dataset driver is PostgreSQL."""
+ ds = lyr.GetDataset()
+ if ds.GetDriver().ShortName != 'PostgreSQL':
+ logging.warning('clusterLayer() called on a non-PostgreSQL dataset, ignoring')
+ return False
+
+ layername_esc = getEscapedTableName(lyr)
+ if index_name is None and column_name is not None:
+ # find out which indices involve lyr's column_name
+ with executeSQL(ds, statement='WITH indices AS ('
+ 'SELECT i.relname AS index, array_agg(a.attname) AS columns '
+ 'FROM pg_class t, pg_class i, pg_index ix, pg_attribute a '
+ 'WHERE t.oid = ix.indrelid '
+ 'AND i.oid = ix.indexrelid '
+ 'AND a.attrelid = t.oid '
+ 'AND a.attnum = ANY(ix.indkey) '
+ 'AND t.relkind = \'r\' '
+ 'AND ix.indrelid = ' + escape_literal_str(layername_esc) + '::regclass '
+ 'GROUP BY 1) '
+ 'SELECT index, array_length(columns, 1) AS len '
+ 'FROM indices '
+ 'WHERE ' + escape_literal_str(column_name) + ' = ANY(columns)'
+ # pick the index involving the least number of columns
+ 'ORDER BY 2,1 LIMIT 1') as res:
+ defn = res.GetLayerDefn()
+ i = defn.GetFieldIndex('index')
+ row = res.GetNextFeature()
+ if row is not None and row.IsFieldSetAndNotNull(i):
+ index_name = row.GetFieldAsString(i)
+
+ if index_name is None:
+ logging.warning('Layer %s has no index on column %s, cannot CLUSTER',
+ lyr.GetName(), column_name)
+ return False
+
+ statement = 'CLUSTER ' + layername_esc
+ if index_name is not None:
+ statement += ' USING ' + escape_identifier(index_name)
+ executeSQL(ds, statement=statement)
+
+ if analyze:
+ # "Because the planner records statistics about the ordering of tables, it is
+ # advisable to run ANALYZE on the newly clustered table. Otherwise, the planner
+ # might make poor choices of query plans."
+ executeSQL(ds, statement='ANALYZE ' + layername_esc)
+
+ return True
+
+# pylint: disable-next=too-many-branches
+def validateOutputLayer(lyr : ogr.Layer,
+ srs : Optional[osr.SpatialReference] = None,
+ options : Optional[dict[str, Any]] = None) -> bool:
+ """Validate the output layer against the provided SRS and creation options."""
+ ok = True
+
+ # ensure the output SRS is equivalent
+ if srs is not None:
+ srs2 = lyr.GetSpatialRef()
+ # cf. apps/ogr2ogr_lib.cpp
+ srs_options = [
+ 'IGNORE_DATA_AXIS_TO_SRS_AXIS_MAPPING=YES',
+ 'CRITERION=EQUIVALENT'
+ ]
+ if not srs.IsSame(srs2, srs_options):
+ logging.warning('Output layer "%s" has SRS %s,\nexpected %s',
+ lyr.GetName(),
+ srs2.ExportToPrettyWkt(),
+ srs.ExportToPrettyWkt())
+ ok = False
+
+ if options is None:
+ return ok
+
+ layerDefn = lyr.GetLayerDefn()
+ n = layerDefn.GetGeomFieldCount()
+ if n != 1:
+ if n == 0:
+ raise RuntimeError(f'Output layer "{lyr.GetName()}" has no geometry fields')
+ logging.warning('Output layer "%s" has %d != 1 geometry fields', lyr.GetName(), n)
+
+ iGeomField = 0
+ geomField = layerDefn.GetGeomFieldDefn(iGeomField)
+ geomType = geomField.GetType()
+ logging.debug('Geometry column #%d: name="%s\", type="%s", srs=%s, nullable=%s',
+ iGeomField, geomField.GetName(),
+ ogr.GeometryTypeToName(geomType),
+ '-' if geomField.GetSpatialRef() is None
+ else '"' + geomField.GetSpatialRef().GetName() + '"',
+ bool(geomField.IsNullable()))
+ if geomField.IsNullable():
+ logging.warning('Geometry column #%d "%s" of output layer "%s" is nullable',
+ iGeomField, geomField.GetName(), lyr.GetName())
+
+ geomType2 = options['geometry-type']
+ if geomType != geomType2:
+ logging.warning('Output layer "%s" has geometry type #%d (%s), expected #%d (%s)',
+ lyr.GetName(),
+ geomType, ogr.GeometryTypeToName(geomType),
+ geomType2, ogr.GeometryTypeToName(geomType2))
+ ok = False
+
+ fields = options.get('fields', None)
+ if fields is not None:
+ for fld in fields:
+ fldName = fld['Name']
+
+ idx = layerDefn.GetFieldIndex(fldName)
+ if idx < 0:
+ logging.warning('Output layer "%s" has no field named "%s"',
+ lyr.GetName(), fldName)
+ ok = False
+ continue
+ defn = layerDefn.GetFieldDefn(idx)
+
+ if 'AlternativeName' in fld:
+ v1 = defn.GetAlternativeName()
+ v2 = fld['AlternativeName']
+ if v1 != v2:
+ logging.warning('Field "%s" has AlternativeName="%s", expected "%s"',
+ fldName, v1, v2)
+ ok = False
+
+ if 'Comment' in fld:
+ v1 = defn.GetComment()
+ v2 = fld['Comment']
+ if v1 != v2:
+ logging.warning('Field "%s" has Comment="%s", expected "%s"',
+ fldName, v1, v2)
+ ok = False
+
+ if 'Type' in fld:
+ v1 = defn.GetType()
+ v2 = fld['Type']
+ if v1 != v2:
+ logging.warning('Field "%s" has Type=%d (%s), expected %d (%s)',
+ fldName,
+ v1, ogr.GetFieldTypeName(v1),
+ v2, ogr.GetFieldTypeName(v2))
+ ok = False
+
+ if 'SubType' in fld:
+ v1 = defn.GetSubType()
+ v2 = fld['SubType']
+ if v1 != v2:
+ logging.warning('Field "%s" has SubType=%d (%s), expected %d (%s)',
+ fldName,
+ v1, ogr.GetFieldSubTypeName(v1),
+ v2, ogr.GetFieldSubTypeName(v2))
+ ok = False
+
+ if 'TZFlag' in fld:
+ v1 = defn.GetTZFlag()
+ v2 = fld['TZFlag']
+ if v1 != v2:
+ logging.warning('Field "%s" has TZFlag=%d (%s), expected %d (%s)',
+ fldName, v1, formatTZFlag(v1), v2, formatTZFlag(v2))
+ ok = False
+
+ if 'Precision' in fld:
+ v1 = defn.GetPrecision()
+ v2 = fld['Precision']
+ if v1 != v2:
+ logging.warning('Field "%s" has Precision=%d, expected %d',
+ fldName, v1, v2)
+ ok = False
+
+ if 'Width' in fld:
+ v1 = defn.GetWidth()
+ v2 = fld['Width']
+ if v1 != v2:
+ logging.warning('Field "%s" has Width=%d, expected %d',
+ fldName, v1, v2)
+ ok = False
+
+ if 'Default' in fld:
+ v1 = defn.GetDefault()
+ v2 = fld['Default']
+ if v1 != v2:
+ logging.warning('Field "%s" has Default="%s", expected "%s"',
+ fldName, v1, v2)
+ ok = False
+
+ if 'Nullable' in fld:
+ v1 = bool(defn.IsNullable())
+ v2 = fld['Nullable']
+ if v1 != v2:
+ logging.warning('Field "%s" has Nullable=%s, expected %s',
+ fldName, v1, v2)
+ ok = False
+
+ if 'Unique' in fld:
+ v1 = bool(defn.IsUnique())
+ v2 = fld['Unique']
+ if v1 != v2:
+ logging.warning('Field "%s" has Unique=%s, expected %s',
+ fldName, v1, v2)
+ ok = False
+
+ return ok
+
+def clearLayer(lyr : ogr.Layer, identity : str = 'CONTINUE IDENTITY') -> None:
+ """Clear the given layer (wipe all its features)"""
+ n = -1
+ if lyr.TestCapability(ogr.OLCFastFeatureCount):
+ n = lyr.GetFeatureCount(force=0)
+ if n == 0:
+ # nothing to clear, we're good
+ return
+
+ ds = lyr.GetDataset()
+ if ds.GetDriver().ShortName == 'PostgreSQL':
+ # https://www.postgresql.org/docs/15/sql-truncate.html
+ statement = 'TRUNCATE TABLE {table} ' + identity + ' CASCADE'
+ op = 'Truncating'
+ else:
+ statement = 'DELETE FROM {table}'
+ op = 'Clearing'
+ logging.info('%s table %s (former feature count: %s)', op,
+ lyr.GetName(), str(n) if n >= 0 else 'unknown')
+ executeSQL(ds, statement=statement.format(table=getEscapedTableName(lyr)))
+
+def extractArchive(path : Path, destdir : str,
+ fmt : str|None = None,
+ patterns : list[str]|None = None,
+ exact_matches : list[str]|None = None) -> None:
+ """Extract an archive file into the given destination directory."""
+ if fmt is None:
+ suffix = path.suffix
+ if suffix is None or suffix == '' or not suffix.startswith('.'):
+ raise RuntimeError(f'Could not infer archive format from "{path}"')
+ fmt = suffix.removeprefix('.')
+
+ fmt = fmt.lower()
+ logging.debug('Unpacking %s archive %s into %s', fmt, path, destdir)
+
+ if fmt == 'zip':
+ import zipfile # pylint: disable=import-outside-toplevel
+ logging.debug('Opening %s as ZipFile', path)
+ with zipfile.ZipFile(path, mode='r') as z:
+ namelist = listArchiveMembers(z.namelist(),
+ patterns=patterns,
+ exact_matches=exact_matches)
+ z.extractall(path=destdir, members=namelist)
+ else:
+ raise RuntimeError(f'Unknown archive format "{fmt}"')
+
+def listArchiveMembers(namelist : list[str],
+ patterns : list[str]|None = None,
+ exact_matches : list[str]|None = None) -> list[str]:
+ """List archive members matching the given parterns and/or exact matches."""
+ if patterns is None and exact_matches is None:
+ # if neither patterns nor exact_matches are given we'll extract the entire archive
+ return namelist
+ if patterns is None:
+ patterns = []
+ if exact_matches is None:
+ exact_matches = []
+
+ members = []
+ for name in namelist:
+ ok = False
+ if name in exact_matches:
+ # try exact matches first
+ logging.debug('Listed archive member %s (exact match)', name)
+ members.append(name)
+ ok = True
+ continue
+ # if there are no exact matches, try patterns one by one in the supplied order
+ for pat in patterns:
+ if fnmatchcase(name, pat):
+ logging.debug('Listed archive member %s (matching pattern "%s")', name, pat)
+ members.append(name)
+ ok = True
+ break
+ if not ok:
+ logging.debug('Ignoring archive member %s', name)
+ return members
+
+@enum_unique
+class ImportStatus(Enum):
+ """Return value for importSources(): success, error, or no-change."""
+ IMPORT_SUCCESS = 0
+ IMPORT_ERROR = 1
+ IMPORT_NOCHANGE = 255
+
+ def __str__(self):
+ return self.name.removeprefix('IMPORT_')
+
+# pylint: disable-next=dangerous-default-value
+def importSources(lyr : ogr.Layer,
+ sources : dict[str,Any] = {},
+ cachedir : Path|None = None,
+ extent : ogr.Geometry|None = None,
+ dsoTransaction : bool = False,
+ lyrcache : ogr.Layer|None = None,
+ force : bool = False,
+ cluster_geometry : bool = False) -> ImportStatus:
+ """Clear lyr and import source layers to it."""
+
+ dso = lyr.GetDataset()
+ layername = lyr.GetName()
+ if dsoTransaction:
+ # declare a SAVEPOINT (nested transaction) within the DS-level transaction
+ lyrTransaction = 'SAVEPOINT ' + escape_identifier('savept_' + layername)
+ executeSQL(dso, lyrTransaction)
+ elif lyr.TestCapability(ogr.OLCTransactions):
+ # try to start transaction on the layer
+ logging.debug('Starting transaction on output layer "%s"', layername)
+ lyrTransaction = lyr.StartTransaction() == ogr.OGRERR_NONE
+ if not lyrTransaction:
+ logging.warning('Couldn\'t start transaction on output layer "%s"', layername)
+ else:
+ logging.warning('Unsafe update, output layer "%s" doesn\'t support transactions',
+ layername)
+ lyrTransaction = False
+
+ rv = ImportStatus.IMPORT_NOCHANGE
+ now = datetime.now().astimezone()
+ try:
+ clearLayer(lyr) # TODO conditional (only if not new)?
+
+ for source in sources:
+ importSource0(lyr, **source['source'],
+ args=source['import'],
+ cachedir=cachedir,
+ extent=extent,
+ callback=_importSource2)
+
+ # force the PG driver to call EndCopy() to detect errors and trigger a
+ # rollback if needed
+ dso.FlushCache()
+
+ if lyrcache is None:
+ rv = ImportStatus.IMPORT_SUCCESS
+ elif updateLayerCache(cache=lyrcache,
+ lyr=lyr,
+ force=force,
+ lyrTransaction=lyrTransaction,
+ last_updated=now):
+ rv = ImportStatus.IMPORT_SUCCESS
+ else:
+ rv = ImportStatus.IMPORT_NOCHANGE
+ if isinstance(lyrTransaction, bool):
+ # the transaction on lyr was already rolled back
+ lyrTransaction = False
+
+ if (rv == ImportStatus.IMPORT_SUCCESS and cluster_geometry
+ and lyr.GetLayerDefn().GetGeomType() != ogr.wkbNone):
+ clusterLayer(lyr, column_name=lyr.GetGeometryColumn())
+
+ except Exception: # pylint: disable=broad-exception-caught
+ rv = ImportStatus.IMPORT_ERROR
+ if isinstance(lyrTransaction, str):
+ statement = 'ROLLBACK TO ' + lyrTransaction
+ logging.exception('Exception occured within transaction')
+ # don't unset lyrTransaction here as we want to RELEASE SAVEPOINT
+ try:
+ executeSQL(dso, statement=statement)
+ except Exception: # pylint: disable=broad-exception-caught
+ logging.exception('Could not execute SQL: %s', statement)
+ elif isinstance(lyrTransaction, bool) and lyrTransaction:
+ logging.exception('Exception occured within transaction on output '
+ 'layer "%s": ROLLBACK', layername)
+ lyrTransaction = None
+ try:
+ if lyr.RollbackTransaction() != ogr.OGRERR_NONE:
+ logging.error('Could not rollback transaction on layer "%s"', layername)
+ except Exception: # pylint: disable=broad-exception-caught
+ logging.exception('Could not rollback transaction on layer "%s"', layername)
+ else:
+ traceback.print_exc()
+
+ finally:
+ if isinstance(lyrTransaction, str):
+ statement = 'RELEASE ' + lyrTransaction
+ try:
+ executeSQL(dso, statement)
+ except Exception: # pylint: disable=broad-exception-caught
+ rv = ImportStatus.IMPORT_ERROR
+ logging.exception('Could not execute SQL: %s', statement)
+ elif isinstance(lyrTransaction, bool) and lyrTransaction:
+ try:
+ if lyr.CommitTransaction() != ogr.OGRERR_NONE:
+ rv = ImportStatus.IMPORT_ERROR
+ logging.error('Could not commit transaction')
+ except Exception: # pylint: disable=broad-exception-caught
+ rv = ImportStatus.IMPORT_ERROR
+ logging.exception('Could not commit transaction on layer "%s"', layername)
+ return rv
+
+# pylint: disable-next=dangerous-default-value
+def importSource0(lyr : ogr.Layer|None = None,
+ path : str = '/nonexistent',
+ unar : dict[str,Any]|None = None,
+ args : dict[str,Any] = {},
+ cachedir : Path|None = None,
+ extent : ogr.Geometry|None = None,
+ callback : Callable[[ogr.Layer|None, str, dict[str,Any], Path|None,
+ ogr.Geometry|None], None]|None = None) -> None:
+ """Import a source layer"""
+ if unar is None:
+ return callback(lyr, path, args=args, basedir=cachedir, extent=extent)
+
+ ds_srcpath = Path(args['path'])
+ if ds_srcpath.is_absolute():
+ # treat absolute paths as relative to the archive root
+ logging.warning('%s is absolute, removing leading anchor', ds_srcpath)
+ ds_srcpath = ds_srcpath.relative_to(ds_srcpath.anchor)
+
+ ds_srcpath = str(ds_srcpath)
+ with tempfile.TemporaryDirectory() as tmpdir:
+ logging.debug('Created temporary directory %s', tmpdir)
+ extractArchive(Path(path) if cachedir is None else cachedir.joinpath(path),
+ tmpdir,
+ fmt=unar.get('format', None),
+ patterns=unar.get('patterns', None),
+ exact_matches=[ds_srcpath])
+ return callback(lyr, ds_srcpath, args=args, basedir=Path(tmpdir), extent=extent)
+
+def setFieldMapValue(fld : ogr.FieldDefn,
+ idx : int,
+ val : None|int|str|bytes|float) -> None|int|str|bytes|float:
+ """Validate field value mapping."""
+ if val is None:
+ if not fld.IsNullable():
+ logging.warning('Field "%s" is not NULLable but remaps NULL', fld.GetName())
+ return None
+
+ fldType = fld.GetType()
+ if fldType in (ogr.OFTInteger, ogr.OFTInteger64):
+ if isinstance(val, int):
+ return val
+ elif fldType == ogr.OFTString:
+ if isinstance(val, str):
+ return val
+ elif fldType == ogr.OFTBinary:
+ if isinstance(val, bytes):
+ return val
+ elif fldType == ogr.OFTReal:
+ if isinstance(val, int):
+ return float(val)
+ if isinstance(val, float):
+ return val
+
+ raise RuntimeError(f'Field "{fld.GetName()}" mapping #{idx} has incompatible type '
+ f'for {ogr.GetFieldTypeName(fldType)}')
+
+def _importSource2(lyr_dst : ogr.Layer, path : str, args : dict[str,Any],
+ basedir : Path|None, extent : ogr.Geometry|None) -> None:
+ """Import a source layer (already extracted)
+ This is more or less like ogr2ogr/GDALVectorTranslate() but we roll
+ out our own (slower) version because GDALVectorTranslate() insists in
+ calling StartTransaction() https://github.com/OSGeo/gdal/issues/3403
+ while we want a single transaction for the entire desination layer,
+ including truncation, source imports, and metadata changes."""
+ kwargs, _ = gdalSetOpenExArgs(args, flags=GDAL_OF_VECTOR|GDAL_OF_READONLY|GDAL_OF_VERBOSE_ERROR)
+ path2 = path if basedir is None else str(basedir.joinpath(path))
+
+ logging.debug('OpenEx(%s, %s)', path2, str(kwargs))
+ ds = gdal.OpenEx(path2, **kwargs)
+ if ds is None:
+ raise RuntimeError(f'Could not open {path2}')
+
+ layername = args.get('layername', None)
+ if layername is None:
+ idx = 0
+ lyr = ds.GetLayerByIndex(idx)
+ msg = '#' + str(idx)
+ if lyr is not None:
+ layername = lyr.GetName()
+ msg += ' ("' + layername + '")'
+ else:
+ lyr = ds.GetLayerByName(layername)
+ msg = '"' + layername + '"'
+ if lyr is None:
+ raise RuntimeError(f'Could not get requested layer {msg} from {path2}')
+
+ logging.info('Importing layer %s from "%s"', msg, path)
+ importLayer(lyr_dst, lyr, args=args, extent=extent)
+
+# pylint: disable-next=too-many-branches, too-many-statements, dangerous-default-value
+def importLayer(lyr_dst : ogr.Layer, lyr : ogr.Layer,
+ args : dict[str,Any] = {},
+ extent : Optional[ogr.Geometry] = None) -> None:
+ """Import a source layer (already opened)."""
+ layername = lyr.GetName()
+ srs = lyr.GetSpatialRef()
+ if srs is None:
+ raise RuntimeError(f'Source layer {layername} has no SRS')
+
+ srs_dst = lyr_dst.GetSpatialRef()
+ if srs_dst is None:
+ logging.warning('Destination has no SRS, skipping coordinate transformation')
+ ct = None
+ elif srs_dst.IsSame(srs):
+ logging.debug('Both source and destination have the same SRS (%s), '
+ 'skipping coordinate transformation',
+ srs_dst.GetName())
+ ct = None
+ else:
+ # TODO Use GetSupportedSRSList() and SetActiveSRS() with GDAL ≥3.7.0
+ # when possible, see apps/ogr2ogr_lib.cpp
+ # pylint: disable=duplicate-code
+ logging.debug('Creating transforming from source SRS (%s) to destination SRS (%s)',
+ srs.GetName(), srs_dst.GetName())
+ ct = osr.CoordinateTransformation(srs, srs_dst)
+ if ct is None:
+ raise RuntimeError(f'Could not create transformation from source SRS ({srs.GetName()}) '
+ f'to destination SRS ({srs_dst.GetName()})')
+
+ defn = lyr.GetLayerDefn()
+ geomFieldCount = defn.GetGeomFieldCount()
+ if geomFieldCount != 1:
+ # TODO Add support for multiple geometry fields (also in the fingerprinting logic below)
+ logging.warning('Source layer "%s" has %d != 1 geometry fields', layername, geomFieldCount)
+
+ fieldCount = defn.GetFieldCount()
+ fieldMap = [-1] * fieldCount
+ fields = args['field-map']
+ fieldSet = set()
+
+ canIgnoreFields = lyr.TestCapability(ogr.OLCIgnoreFields)
+ ignoredFieldNames = []
+ for i in range(fieldCount):
+ fld = defn.GetFieldDefn(i)
+ fldName = fld.GetName()
+ fieldMap[i] = v = fields.get(fldName, -1)
+ fieldSet.add(fldName)
+
+ if v < 0 and canIgnoreFields:
+ # call SetIgnored() on unwanted source fields
+ logging.debug('Set Ignored=True on output field "%s"', fldName)
+ fld.SetIgnored(True)
+ ignoredFieldNames.append(fldName)
+
+ count0 = -1
+ if lyr.TestCapability(ogr.OLCFastFeatureCount):
+ count0 = lyr.GetFeatureCount(force=0)
+
+ if count0 == 0 and len(fieldSet) == 0:
+ # skip the below warning in some cases (e.g., GeoJSON source)
+ logging.info('Source layer "%s" has no fields nor features, skipping', layername)
+ return
+
+ logging.debug('Field map: %s', str(fieldMap))
+ for fld in fields:
+ if not fld in fieldSet:
+ logging.warning('Source layer "%s" has no field named "%s", ignoring', layername, fld)
+
+ count1 = -1
+ if args.get('spatial-filter', True) and extent is not None:
+ spatialFilter = getSpatialFilterFromGeometry(extent, srs)
+ logging.debug('Setting spatial filter to %s', spatialFilter.ExportToWkt())
+ lyr.SetSpatialFilter(spatialFilter)
+
+ if lyr.TestCapability(ogr.OLCFastFeatureCount):
+ count1 = lyr.GetFeatureCount(force=0)
+
+ if count0 >= 0:
+ if count1 >= 0:
+ logging.info('Source layer "%s" has %d features (%d of which intersecting extent)',
+ layername, count0, count1)
+ else:
+ logging.info('Source layer "%s" has %d features', layername, count0)
+
+ logging.info('Ignored fields from source layer: %s',
+ '-' if len(ignoredFieldNames) == 0 else ', '.join(ignoredFieldNames))
+
+ # build a list of triplets (field index, replacement_for_null, [(from_value, to_value), …])
+ valueMap = []
+ for fldName, rules in args.get('value-map', {}).items():
+ i = defn.GetFieldIndex(fldName)
+ if i < 0:
+ raise RuntimeError(f'Source layer "{layername}" has no field named "{fldName}"')
+ if fieldMap[i] < 0:
+ logging.warning('Ignored source field "%s" has value map', fldName)
+ continue
+
+ hasNullReplacement = False
+ nullReplacement = None
+ mapping = []
+ fld = defn.GetFieldDefn(i)
+ for idx, (rFrom, rTo) in enumerate(rules):
+ # use fld for both 'from' and 'to' (the types must match, casting is not
+ # allowed in the mapping)
+ if rFrom is None:
+ if hasNullReplacement:
+ logging.warning('Field "%s" has duplicate NULL replacement',
+ fld.GetName())
+ else:
+ setFieldMapValue(fld, idx, None) # validate NULL
+ rTo = setFieldMapValue(fld, idx, rTo)
+ hasNullReplacement = True
+ nullReplacement = rTo
+ elif isinstance(rFrom, re.Pattern):
+ # validate but keep the rFrom regex
+ setFieldMapValue(fld, idx, str(rFrom))
+ rTo = setFieldMapValue(fld, idx, rTo)
+ mapping.append( (rFrom, rTo, 1) )
+ else:
+ rFrom = setFieldMapValue(fld, idx, rFrom)
+ rTo = setFieldMapValue(fld, idx, rTo)
+ mapping.append( (rFrom, rTo, 0) )
+
+ if nullReplacement is not None or len(mapping) > 0:
+ valueMap.append( (i, nullReplacement, mapping) )
+
+ if args.get('rstrip-strings', False):
+ stringFieldsIdx = [ i for i in range(fieldCount)
+ if defn.GetFieldDefn(i).GetType() == ogr.OFTString and
+ fieldMap[i] >= 0 ]
+ logging.debug('Source field indices to rstrip: %s', str(stringFieldsIdx))
+ bStringFields = len(stringFieldsIdx) > 0
+ else:
+ bStringFields = False
+
+ bValueMap = len(valueMap) > 0
+ defn = None
+
+ defn_dst = lyr_dst.GetLayerDefn()
+ eGType_dst = defn_dst.GetGeomType()
+ eGType_dst_HasZ = ogr.GT_HasZ(eGType_dst)
+ eGType_dst_HasM = ogr.GT_HasM(eGType_dst)
+ dGeomIsUnknown = ogr.GT_Flatten(eGType_dst) == ogr.wkbUnknown
+
+ if bValueMap:
+ valueMapCounts = [0] * fieldCount
+
+ featureCount = 0
+ mismatch = {}
+ feature = lyr.GetNextFeature()
+ while feature is not None:
+ if bStringFields:
+ for i in stringFieldsIdx:
+ if feature.IsFieldSetAndNotNull(i):
+ v = feature.GetField(i)
+ feature.SetField(i, v.rstrip())
+
+ if bValueMap:
+ for i, nullReplacement, mapping in valueMap:
+ if not feature.IsFieldSet(i):
+ continue
+ if feature.IsFieldNull(i):
+ if nullReplacement is not None:
+ # replace NULL with non-NULL value
+ feature.SetField(i, nullReplacement)
+ valueMapCounts[i] += 1
+ continue
+
+ v = feature.GetField(i)
+ for rFrom, rTo, rType in mapping:
+ if rType == 0:
+ # literal
+ if v != rFrom:
+ continue
+ elif rType == 1:
+ # regex
+ m = rFrom.fullmatch(v)
+ if m is None:
+ continue
+ if rTo is not None:
+ rTo = rTo.format(*m.groups())
+ else:
+ raise RuntimeError(str(rType))
+
+ if rTo is None:
+ # replace non-NULL value with NULL
+ feature.SetFieldNull(i)
+ else:
+ # replace non-NULL value with non-NULL value
+ feature.SetField(i, rTo)
+ valueMapCounts[i] += 1
+ break
+
+ feature2 = ogr.Feature(defn_dst)
+ feature2.SetFromWithMap(feature, False, fieldMap)
+
+ geom = feature2.GetGeometryRef()
+ if geom is None:
+ if eGType_dst != ogr.wkbNone:
+ logging.warning('Source feature #%d has no geometry, trying to transfer anyway',
+ feature.GetFID())
+ else:
+ if ct is not None and geom.Transform(ct) != ogr.OGRERR_NONE:
+ raise RuntimeError('Could not apply coordinate transformation')
+
+ eGType = geom.GetGeometryType()
+ if eGType != eGType_dst and not dGeomIsUnknown:
+ # Promote to multi, cf. apps/ogr2ogr_lib.cpp:ConvertType()
+ eGType2 = eGType
+ if eGType in (ogr.wkbTriangle, ogr.wkbTIN, ogr.wkbPolyhedralSurface):
+ eGType2 = ogr.wkbMultiPolygon
+ elif not ogr.GT_IsSubClassOf(eGType, ogr.wkbGeometryCollection):
+ eGType2 = ogr.GT_GetCollection(eGType)
+
+ eGType2 = ogr.GT_SetModifier(eGType2, eGType_dst_HasZ, eGType_dst_HasM)
+ if eGType2 == eGType_dst:
+ mismatch[eGType] = mismatch.get(eGType, 0) + 1
+ geom = ogr.ForceTo(geom, eGType_dst)
+ # TODO call MakeValid()?
+ else:
+ raise RuntimeError(f'Conversion from {ogr.GeometryTypeToName(eGType)} '
+ f'to {ogr.GeometryTypeToName(eGType_dst)} not implemented')
+ feature2.SetGeometryDirectly(geom)
+
+ if lyr_dst.CreateFeature(feature2) != ogr.OGRERR_NONE:
+ raise RuntimeError(f'Could not transfer source feature #{feature.GetFID()}')
+
+ featureCount += 1
+ feature = lyr.GetNextFeature()
+
+ if bValueMap:
+ valueMapCounts = [ (lyr.GetLayerDefn().GetFieldDefn(i).GetName(), k)
+ for i,k in enumerate(valueMapCounts) if k > 0 ]
+
+ lyr = None
+ logging.info('Imported %d features from source layer "%s"', featureCount, layername)
+
+ if bValueMap:
+ if len(valueMapCounts) > 0:
+ valueMapCounts = ', '.join([ str(k) + '× "' + n + '"' for n,k in valueMapCounts ])
+ else:
+ valueMapCounts = '-'
+ logging.info('Field substitutions: %s', valueMapCounts)
+
+ if len(mismatch) > 0:
+ mismatches = [ str(n) + '× ' + ogr.GeometryTypeToName(t)
+ for t,n in sorted(mismatch.items(), key=lambda x: x[1]) ]
+ logging.info('Forced conversion to %s: %s',
+ ogr.GeometryTypeToName(eGType_dst), ', '.join(mismatches))
+
+def listFieldsOrderBy(defn : ogr.FeatureDefn,
+ unique : bool|None = None,
+ nullable : bool|None = None) -> Iterator[str]:
+ """Return an iterator of column names suitable for ORDER BY."""
+ fields_str = {}
+ for i in range(defn.GetFieldCount()):
+ fld = defn.GetFieldDefn(i)
+ if (fld.IsIgnored() or
+ # if 'unique' or 'unable' is not None then skip the field
+ # unless the boolean matches .IsUnique() resp. .IsNullable()
+ not (unique is None or fld.IsUnique() == unique) or
+ not (nullable is None or fld.IsNullable() == nullable)):
+ continue
+ if fld.GetType() in (ogr.OFTInteger, ogr.OFTInteger64):
+ # list integers first
+ yield fld.GetName()
+ elif fld.GetType() == ogr.OFTString:
+ w = fld.GetWidth()
+ if 0 < w < 256:
+ # only consider short-ish strings
+ fields_str[fld.GetName()] = w
+ # order string columns by width
+ for c,_ in sorted(fields_str.items(), key=lambda x:x[1]):
+ yield c
+
+# pylint: disable-next=too-many-branches, too-many-statements
+def updateLayerCache(lyr : ogr.Layer, cache : ogr.Layer,
+ last_updated : datetime,
+ lyrTransaction : str|bool|None = None,
+ force : bool = False) -> bool:
+ """Update attributes in the layer cache for the given layer name.
+ Return a boolean indicating whether changes to layername were *not*
+ rolled back (hence might still be outstanding in the transaction)."""
+ layername = lyr.GetName()
+
+ dgst = sha256()
+ defn = lyr.GetLayerDefn()
+ fields = []
+ for i in range(defn.GetFieldCount()):
+ fields.append('t.' + escape_identifier(defn.GetFieldDefn(i).GetName()))
+ if len(fields) == 0:
+ fields = ['0 AS hash_properties']
+ else:
+ fields = [ 'hash_record_extended(ROW(' + ','.join(fields) + '),0) AS hash_properties' ]
+
+ fidColumn = lyr.GetFIDColumn()
+ if fidColumn is None or fidColumn == '':
+ raise RuntimeError(f'Couldn\'t find FID column for "{layername}"')
+ # defn.GetGeomFieldCount() != 1 is not supported and yields a warning in _importSource2()
+ geometryColumn = lyr.GetGeometryColumn()
+ if geometryColumn is None or geometryColumn == '':
+ raise RuntimeError(f'Couldn\'t find geometry column for "{layername}"')
+
+ fields.append('sha256(COALESCE(' +
+ 'ST_AsEWKB(t.' + escape_identifier(geometryColumn) + '),' +
+ '\'\')) AS hash_geom')
+ if len(fields) == 0:
+ raise RuntimeError('Empty field list in SELECT')
+ query = 'SELECT ' + ','.join(fields) + ' FROM ' + getEscapedTableName(lyr) + ' t'
+
+ sort_by = next(listFieldsOrderBy(defn, unique=True, nullable=False), None)
+ if sort_by is not None:
+ sort_by = [ sort_by ]
+ else:
+ count = lyr.GetFeatureCount(force=0)
+ if count is None or count < 0 or count > 5000:
+ logging.warning('Layer "%s" has many (%s) features but no UNIQUE NOT NULL constraint, '
+ 'sorting might be unstable and slow', layername,
+ str(count) if (count is not None and count >= 0) else 'N/A')
+ sort_by = list(listFieldsOrderBy(defn)) + [ geometryColumn, fidColumn ]
+ query += ' ORDER BY ' + ','.join(['t.' + escape_identifier(c) for c in sort_by])
+
+ struct_dgst : Final = struct.Struct('@qq').pack
+ ds = lyr.GetDataset()
+ with executeSQL(ds, query) as lyr2:
+ defn2 = lyr2.GetLayerDefn()
+ assert defn2.GetFieldDefn(0).GetName() == 'hash_properties'
+ assert defn2.GetFieldDefn(1).GetName() == 'hash_geom'
+ feature = lyr2.GetNextFeature()
+ while feature is not None:
+ dgst.update(struct_dgst(feature.GetFID(), feature.GetFieldAsInteger64(0)))
+ dgst.update(feature.GetFieldAsBinary(1))
+ feature = lyr2.GetNextFeature()
+ fingerprint = dgst.digest()
+
+ attributeFilter = 'layername = ' + escape_literal_str(layername)
+ logging.debug('SetAttributeFilter("%s", "%s")', cache.GetName(), attributeFilter)
+ cache.SetAttributeFilter(attributeFilter)
+
+ feature = cache.GetNextFeature()
+ if feature is None:
+ # not in cache
+ logging.debug('Creating new feature in layer cache for %s', attributeFilter)
+ update = False
+ feature = ogr.Feature(cache.GetLayerDefn())
+ feature.SetFieldString(0, layername)
+ fingerprint_old = None
+ else:
+ logging.debug('Updating existing feature in layer cache for %s', attributeFilter)
+ update = True
+ fingerprint_old = feature.GetFieldAsBinary(2) if feature.IsFieldSetAndNotNull(2) else None
+ assert cache.GetNextFeature() is None
+
+ if last_updated.tzinfo == UTC:
+ tzFlag = ogr.TZFLAG_UTC
+ else:
+ td = last_updated.utcoffset()
+ # 15min increments/decrements per unit above/below UTC, cf.
+ # https://gdal.org/en/stable/api/vector_c_api.html#c.OGR_TZFLAG_UTC
+ tzFlag = td.days * 96 + td.seconds // 900
+ if timedelta(seconds=tzFlag*900) != td or abs(tzFlag) > 56: # max ±14:00
+ raise RuntimeError(f'Invalid UTC offset {td}')
+ tzFlag += ogr.TZFLAG_UTC
+
+ feature.SetField(1, last_updated.year,
+ last_updated.month,
+ last_updated.day,
+ last_updated.hour,
+ last_updated.minute,
+ float(last_updated.second) + float(last_updated.microsecond)/1000000.,
+ tzFlag)
+ if fingerprint is None:
+ feature.SetFieldNull(2)
+ else:
+ # https://lists.osgeo.org/pipermail/gdal-dev/2020-December/053170.html
+ feature.SetFieldBinaryFromHexString(2, fingerprint.hex())
+
+ ret = True
+ if update:
+ if (fingerprint is None or fingerprint_old is None or fingerprint != fingerprint_old):
+ logging.info('Updated layer "%s" has new fingerprint %s', layername,
+ fingerprint.hex()[:8] if fingerprint is not None else 'N/A')
+ elif force:
+ logging.info('Updated layer "%s" has identical fingerprint %s',
+ layername, fingerprint.hex()[:8])
+ else:
+ # no change: rollback (*before* updating the cache) if possible to retain FID values
+ if isinstance(lyrTransaction, str):
+ logging.info('Updated layer "%s" has identical fingerprint %s, rolling back',
+ layername, fingerprint.hex()[:8])
+ try:
+ executeSQL(ds, 'ROLLBACK TO ' + lyrTransaction)
+ except Exception: # pylint: disable=broad-exception-caught
+ logging.exception('Could not execute SQL: %s', query)
+ else:
+ ret = False
+ elif isinstance(lyrTransaction, bool) and lyrTransaction:
+ logging.info('Updated layer "%s" has identical fingerprint %s, rolling back',
+ layername, fingerprint.hex()[:8])
+ try:
+ if lyr.RollbackTransaction() == ogr.OGRERR_NONE:
+ ret = False
+ else:
+ logging.error('Could not rollback transaction on layer "%s"',
+ layername)
+ except Exception: # pylint: disable=broad-exception-caught
+ logging.exception('Could not rollback transaction on layer "%s"',
+ layername)
+ else:
+ logging.info('Updated layer "%s" has identical fingerprint %s',
+ layername, fingerprint.hex()[:8])
+
+ if cache.UpdateFeature(feature, [1,2], [], False) != ogr.OGRERR_NONE:
+ raise RuntimeError('Could not update feature in layer cache')
+ else:
+ if cache.CreateFeature(feature) != ogr.OGRERR_NONE:
+ raise RuntimeError('Could not create new feature in layer cache')
+
+ # force the PG driver to call EndCopy() to detect errors and trigger a
+ # rollback if needed
+ ds.FlushCache()
+ return ret
diff --git a/layers/.gitignore b/layers/.gitignore
new file mode 100644
index 0000000..b86e025
--- /dev/null
+++ b/layers/.gitignore
@@ -0,0 +1,3 @@
+!/custom/
+/*.zip
+/*/
diff --git a/layers/custom/gigafactories.geojson b/layers/custom/gigafactories.geojson
new file mode 100644
index 0000000..d30282e
--- /dev/null
+++ b/layers/custom/gigafactories.geojson
@@ -0,0 +1,454 @@
+{
+ "type": "FeatureCollection",
+ "name": "Gigafactories",
+ "crs": {
+ "type": "name",
+ "properties": {
+ "name": "urn:ogc:def:crs:EPSG::3006"
+ }
+ },
+ "features": [
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "H₂GS",
+ "url": "https://www.h2greensteel.com/boden"
+ },
+ "geometry": {
+ "type": "Polygon",
+ "coordinates": [
+ [
+ [
+ 811010.34,
+ 7316409.28
+ ],
+ [
+ 811200.84,
+ 7316636.82
+ ],
+ [
+ 812116.3,
+ 7315520.28
+ ],
+ [
+ 811899.34,
+ 7315340.36
+ ],
+ [
+ 812174.51,
+ 7314869.4
+ ],
+ [
+ 812026.34,
+ 7314790.03
+ ],
+ [
+ 812042.22,
+ 7314430.19
+ ],
+ [
+ 812412.63,
+ 7314387.86
+ ],
+ [
+ 812433.8,
+ 7314144.44
+ ],
+ [
+ 811909.92,
+ 7313387.74
+ ],
+ [
+ 810560.55,
+ 7314123.28
+ ],
+ [
+ 808406.84,
+ 7313160.19
+ ],
+ [
+ 807999.38,
+ 7313033.19
+ ],
+ [
+ 807909.42,
+ 7312842.69
+ ],
+ [
+ 807925.3,
+ 7312657.49
+ ],
+ [
+ 807845.92,
+ 7312625.74
+ ],
+ [
+ 807803.59,
+ 7312821.53
+ ],
+ [
+ 807687.17,
+ 7313313.65
+ ],
+ [
+ 807729.51,
+ 7313361.28
+ ],
+ [
+ 807888.26,
+ 7313117.86
+ ],
+ [
+ 808105.22,
+ 7313202.53
+ ],
+ [
+ 808121.09,
+ 7313276.61
+ ],
+ [
+ 808179.3,
+ 7313303.07
+ ],
+ [
+ 808237.51,
+ 7313313.65
+ ],
+ [
+ 808322.17,
+ 7313361.28
+ ],
+ [
+ 808459.76,
+ 7313541.19
+ ],
+ [
+ 808602.63,
+ 7313721.11
+ ],
+ [
+ 808708.47,
+ 7313996.28
+ ],
+ [
+ 808809.01,
+ 7313959.24
+ ],
+ [
+ 808655.55,
+ 7313557.07
+ ],
+ [
+ 808787.84,
+ 7313498.86
+ ],
+ [
+ 808941.3,
+ 7313488.28
+ ],
+ [
+ 809227.05,
+ 7313583.53
+ ],
+ [
+ 809528.67,
+ 7313736.99
+ ],
+ [
+ 809761.51,
+ 7313953.94
+ ],
+ [
+ 809877.92,
+ 7314155.03
+ ],
+ [
+ 809856.76,
+ 7314223.82
+ ],
+ [
+ 809946.72,
+ 7314282.03
+ ],
+ [
+ 810004.92,
+ 7314239.69
+ ],
+ [
+ 810137.22,
+ 7314340.24
+ ],
+ [
+ 809586.88,
+ 7315112.82
+ ],
+ [
+ 809629.22,
+ 7315160.44
+ ],
+ [
+ 809555.13,
+ 7315340.36
+ ],
+ [
+ 809375.22,
+ 7315557.32
+ ],
+ [
+ 809073.59,
+ 7315901.28
+ ],
+ [
+ 809787.97,
+ 7316732.07
+ ],
+ [
+ 810126.63,
+ 7315906.57
+ ],
+ [
+ 810084.3,
+ 7315869.53
+ ],
+ [
+ 810211.3,
+ 7315811.32
+ ],
+ [
+ 810809.26,
+ 7316271.69
+ ],
+ [
+ 810698.13,
+ 7316398.69
+ ],
+ [
+ 810915.09,
+ 7316525.69
+ ],
+ [
+ 811010.34,
+ 7316409.28
+ ]
+ ]
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "LKAB Vitåfors",
+ "url": "https://www.hybritdevelopment.se/media/lkab-vitafors/"
+ },
+ "geometry": {
+ "type": "Polygon",
+ "coordinates": [
+ [
+ [
+ 745818.77,
+ 7466085.83
+ ],
+ [
+ 746369.11,
+ 7465890.04
+ ],
+ [
+ 746416.73,
+ 7465456.12
+ ],
+ [
+ 746676.02,
+ 7465614.87
+ ],
+ [
+ 746829.48,
+ 7465561.96
+ ],
+ [
+ 746914.15,
+ 7465450.83
+ ],
+ [
+ 746803.02,
+ 7465397.92
+ ],
+ [
+ 746638.98,
+ 7465392.62
+ ],
+ [
+ 746474.94,
+ 7465350.29
+ ],
+ [
+ 746829.48,
+ 7465053.96
+ ],
+ [
+ 746967.06,
+ 7465159.79
+ ],
+ [
+ 747146.98,
+ 7465059.25
+ ],
+ [
+ 747094.06,
+ 7464916.37
+ ],
+ [
+ 747258.11,
+ 7464762.92
+ ],
+ [
+ 747422.15,
+ 7464630.62
+ ],
+ [
+ 747649.69,
+ 7464186.12
+ ],
+ [
+ 747109.94,
+ 7463948.0
+ ],
+ [
+ 746670.73,
+ 7464424.25
+ ],
+ [
+ 746744.81,
+ 7464657.08
+ ],
+ [
+ 746443.19,
+ 7464815.83
+ ],
+ [
+ 746157.44,
+ 7465064.54
+ ],
+ [
+ 746093.94,
+ 7464979.87
+ ],
+ [
+ 745945.77,
+ 7465122.75
+ ],
+ [
+ 746003.98,
+ 7465239.17
+ ],
+ [
+ 745744.69,
+ 7465540.79
+ ],
+ [
+ 745474.81,
+ 7465249.75
+ ],
+ [
+ 745633.56,
+ 7465096.29
+ ],
+ [
+ 745633.56,
+ 7464979.87
+ ],
+ [
+ 745543.61,
+ 7464942.83
+ ],
+ [
+ 745411.31,
+ 7464937.54
+ ],
+ [
+ 745136.15,
+ 7464964.0
+ ],
+ [
+ 744892.73,
+ 7464863.46
+ ],
+ [
+ 744765.73,
+ 7465069.83
+ ],
+ [
+ 745279.02,
+ 7465419.08
+ ],
+ [
+ 745321.36,
+ 7465313.25
+ ],
+ [
+ 745818.77,
+ 7466085.83
+ ]
+ ]
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "Northvolt",
+ "url": "https://northvolt.com/career/locations/skelleftea/"
+ },
+ "geometry": {
+ "type": "Polygon",
+ "coordinates": [
+ [
+ [
+ 788969.67,
+ 7193414.19
+ ],
+ [
+ 790274.06,
+ 7192948.52
+ ],
+ [
+ 790414.29,
+ 7192816.23
+ ],
+ [
+ 790467.21,
+ 7192713.04
+ ],
+ [
+ 790464.56,
+ 7192260.6
+ ],
+ [
+ 790334.92,
+ 7192255.31
+ ],
+ [
+ 790340.21,
+ 7192567.52
+ ],
+ [
+ 790141.77,
+ 7192662.77
+ ],
+ [
+ 789932.75,
+ 7192088.62
+ ],
+ [
+ 788657.46,
+ 7192612.5
+ ],
+ [
+ 788969.67,
+ 7193414.19
+ ]
+ ]
+ ]
+ }
+ }
+ ]
+}
diff --git a/layers/custom/svk/transmissionsnatsprojekt.geojson b/layers/custom/svk/transmissionsnatsprojekt.geojson
new file mode 100644
index 0000000..b0cee50
--- /dev/null
+++ b/layers/custom/svk/transmissionsnatsprojekt.geojson
@@ -0,0 +1,1797 @@
+{
+ "type": "FeatureCollection",
+ "name": "Transmissionsnätsprojekt",
+ "crs": {
+ "type": "name",
+ "properties": {
+ "name": "urn:ogc:def:crs:EPSG::3006"
+ }
+ },
+ "features": [
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "Aurora Line",
+ "voltage": 400,
+ "url": "https://www.svk.se/utveckling-av-kraftsystemet/transmissionsnatet/transmissionsnatsprojekt/aurora-line/"
+ },
+ "geometry": {
+ "type": "MultiLineString",
+ "coordinates": [
+ [
+ [
+ 735379.35,
+ 7405916.15
+ ],
+ [
+ 735417.71,
+ 7405943.93
+ ],
+ [
+ 736428.42,
+ 7405666.12
+ ],
+ [
+ 739150.98,
+ 7401022.68
+ ],
+ [
+ 743016.55,
+ 7396794.64
+ ],
+ [
+ 747728.78,
+ 7394254.64
+ ],
+ [
+ 748238.57,
+ 7393821.85
+ ],
+ [
+ 748847.11,
+ 7392705.3
+ ],
+ [
+ 754540.95,
+ 7382465.93
+ ],
+ [
+ 754707.63,
+ 7382315.12
+ ],
+ [
+ 767185.38,
+ 7380470.97
+ ],
+ [
+ 771905.55,
+ 7379309.45
+ ],
+ [
+ 772731.05,
+ 7379087.2
+ ],
+ [
+ 772979.76,
+ 7379050.16
+ ],
+ [
+ 776675.99,
+ 7378883.47
+ ],
+ [
+ 777512.07,
+ 7378804.1
+ ],
+ [
+ 777893.07,
+ 7378743.24
+ ],
+ [
+ 780591.82,
+ 7378097.66
+ ],
+ [
+ 784682.28,
+ 7377751.05
+ ],
+ [
+ 789913.09,
+ 7376793.26
+ ],
+ [
+ 790362.88,
+ 7376748.28
+ ],
+ [
+ 792905.53,
+ 7376716.53
+ ],
+ [
+ 795837.11,
+ 7375488.87
+ ],
+ [
+ 799091.49,
+ 7375345.99
+ ],
+ [
+ 803200.47,
+ 7374319.41
+ ],
+ [
+ 807841.26,
+ 7374663.37
+ ],
+ [
+ 812209.53,
+ 7374708.35
+ ],
+ [
+ 825070.93,
+ 7371853.49
+ ],
+ [
+ 830923.51,
+ 7371358.72
+ ],
+ [
+ 834154.07,
+ 7370713.14
+ ],
+ [
+ 835555.75,
+ 7370931.77
+ ],
+ [
+ 836733.43,
+ 7370995.54
+ ],
+ [
+ 836826.96,
+ 7370961.53
+ ],
+ [
+ 836963.01,
+ 7370668.17
+ ],
+ [
+ 837090.56,
+ 7370506.61
+ ],
+ [
+ 837715.53,
+ 7370260.02
+ ],
+ [
+ 840660.18,
+ 7369858.53
+ ],
+ [
+ 841284.59,
+ 7369961.72
+ ],
+ [
+ 841681.47,
+ 7369948.49
+ ],
+ [
+ 842067.76,
+ 7369797.68
+ ],
+ [
+ 850148.13,
+ 7369543.68
+ ],
+ [
+ 850410.07,
+ 7369556.91
+ ],
+ [
+ 852471.18,
+ 7369324.07
+ ],
+ [
+ 856529.88,
+ 7367180.95
+ ],
+ [
+ 862599.43,
+ 7367538.14
+ ],
+ [
+ 864798.11,
+ 7367979.99
+ ],
+ [
+ 865148.21,
+ 7368247.42
+ ],
+ [
+ 865437.93,
+ 7368342.67
+ ],
+ [
+ 865842.74,
+ 7368295.04
+ ],
+ [
+ 866203.05,
+ 7368260.45
+ ],
+ [
+ 868340.88,
+ 7368697.01
+ ],
+ [
+ 871566.16,
+ 7369252.64
+ ],
+ [
+ 871899.53,
+ 7369451.07
+ ],
+ [
+ 872209.09,
+ 7369525.16
+ ],
+ [
+ 872573.74,
+ 7369501.54
+ ],
+ [
+ 872833.51,
+ 7369466.95
+ ],
+ [
+ 876339.24,
+ 7370078.14
+ ],
+ [
+ 881110.53,
+ 7369513.45
+ ]
+ ],
+ [
+ [
+ 881181.77,
+ 7369503.0
+ ],
+ [
+ 883850.76,
+ 7369189.14
+ ],
+ [
+ 886967.55,
+ 7368443.01
+ ],
+ [
+ 890659.34,
+ 7367564.79
+ ],
+ [
+ 895637.95,
+ 7366781.43
+ ],
+ [
+ 895981.43,
+ 7366806.76
+ ],
+ [
+ 896779.15,
+ 7367136.17
+ ]
+ ]
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "Letsi–Svartbyn",
+ "voltage": 400,
+ "url": "https://www.svk.se/utveckling-av-kraftsystemet/transmissionsnatet/transmissionsnatsprojekt/letsisvartbyn/"
+ },
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ 739618.45,
+ 7386746.89
+ ],
+ [
+ 739605.88,
+ 7386843.79
+ ],
+ [
+ 739910.15,
+ 7386870.25
+ ],
+ [
+ 740330.84,
+ 7386798.81
+ ],
+ [
+ 740666.86,
+ 7386677.1
+ ],
+ [
+ 743063.98,
+ 7385637.29
+ ],
+ [
+ 746096.11,
+ 7384420.21
+ ],
+ [
+ 750488.19,
+ 7382520.5
+ ],
+ [
+ 751363.96,
+ 7383094.64
+ ],
+ [
+ 751729.09,
+ 7383142.27
+ ],
+ [
+ 752078.34,
+ 7383060.25
+ ],
+ [
+ 754017.73,
+ 7382427.89
+ ],
+ [
+ 754576.0,
+ 7382319.42
+ ],
+ [
+ 759063.34,
+ 7378072.85
+ ],
+ [
+ 761616.57,
+ 7374987.81
+ ],
+ [
+ 766233.55,
+ 7369431.56
+ ],
+ [
+ 768511.61,
+ 7366690.48
+ ],
+ [
+ 770956.36,
+ 7363729.79
+ ],
+ [
+ 773409.05,
+ 7359597.0
+ ],
+ [
+ 774181.63,
+ 7358567.77
+ ],
+ [
+ 775239.96,
+ 7357228.98
+ ],
+ [
+ 775374.9,
+ 7357022.6
+ ],
+ [
+ 777028.55,
+ 7354485.25
+ ],
+ [
+ 779468.0,
+ 7350738.75
+ ],
+ [
+ 779621.46,
+ 7350606.46
+ ],
+ [
+ 780333.19,
+ 7350336.58
+ ],
+ [
+ 781997.42,
+ 7349622.21
+ ],
+ [
+ 783365.32,
+ 7348550.64
+ ],
+ [
+ 784997.8,
+ 7347262.12
+ ],
+ [
+ 786913.38,
+ 7345931.27
+ ],
+ [
+ 787095.94,
+ 7345777.81
+ ],
+ [
+ 787810.32,
+ 7344690.37
+ ],
+ [
+ 788434.73,
+ 7342610.75
+ ],
+ [
+ 792014.55,
+ 7338422.39
+ ],
+ [
+ 792162.71,
+ 7338287.46
+ ],
+ [
+ 794237.05,
+ 7336930.14
+ ],
+ [
+ 796306.09,
+ 7335967.06
+ ],
+ [
+ 797464.96,
+ 7334802.89
+ ],
+ [
+ 799203.27,
+ 7332281.42
+ ],
+ [
+ 800573.82,
+ 7330918.81
+ ],
+ [
+ 801912.61,
+ 7329894.87
+ ],
+ [
+ 803182.61,
+ 7329058.79
+ ],
+ [
+ 803838.77,
+ 7328175.08
+ ],
+ [
+ 804383.82,
+ 7326312.42
+ ],
+ [
+ 805942.21,
+ 7324037.0
+ ],
+ [
+ 808019.19,
+ 7321708.67
+ ],
+ [
+ 811016.92,
+ 7316972.62
+ ],
+ [
+ 812398.05,
+ 7315395.71
+ ]
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "Naalojärvi–Messaure",
+ "voltage": 400,
+ "url": "https://www.svk.se/utveckling-av-kraftsystemet/transmissionsnatet/transmissionsnatsprojekt/naalojarvimessaure/"
+ },
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ 735364.93,
+ 7405933.67
+ ],
+ [
+ 735409.57,
+ 7405968.74
+ ],
+ [
+ 735658.28,
+ 7405906.03
+ ],
+ [
+ 735896.37,
+ 7406357.76
+ ],
+ [
+ 736209.39,
+ 7406819.58
+ ],
+ [
+ 736497.43,
+ 7407426.49
+ ],
+ [
+ 737096.37,
+ 7408013.73
+ ],
+ [
+ 743143.13,
+ 7464295.67
+ ]
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "Porjusberget–Naalojärvi (Vitåfors)",
+ "voltage": 400,
+ "url": "https://www.svk.se/utveckling-av-kraftsystemet/transmissionsnatet/transmissionsnatsprojekt/porjusberget-naalojarvi-vitafors/"
+ },
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ 743103.45,
+ 7464377.87
+ ],
+ [
+ 742615.94,
+ 7464230.48
+ ],
+ [
+ 742366.51,
+ 7463524.73
+ ],
+ [
+ 741567.22,
+ 7463040.05
+ ],
+ [
+ 741082.55,
+ 7462433.5
+ ],
+ [
+ 739529.32,
+ 7460429.6
+ ],
+ [
+ 738731.8,
+ 7459407.45
+ ],
+ [
+ 738268.78,
+ 7458626.93
+ ],
+ [
+ 737072.86,
+ 7456309.18
+ ],
+ [
+ 736509.3,
+ 7455332.86
+ ],
+ [
+ 735429.8,
+ 7453483.43
+ ],
+ [
+ 734768.34,
+ 7452348.36
+ ],
+ [
+ 734630.76,
+ 7452213.43
+ ],
+ [
+ 732813.07,
+ 7450975.18
+ ],
+ [
+ 732225.69,
+ 7450607.41
+ ],
+ [
+ 729624.84,
+ 7448945.82
+ ],
+ [
+ 728828.44,
+ 7448551.59
+ ],
+ [
+ 728547.98,
+ 7448466.93
+ ],
+ [
+ 721883.13,
+ 7447157.24
+ ],
+ [
+ 720242.71,
+ 7446162.41
+ ],
+ [
+ 719136.76,
+ 7445220.49
+ ],
+ [
+ 717874.69,
+ 7443326.07
+ ],
+ [
+ 716176.07,
+ 7441399.91
+ ],
+ [
+ 714837.28,
+ 7439881.2
+ ],
+ [
+ 712543.34,
+ 7436039.45
+ ],
+ [
+ 711403.19,
+ 7434742.25
+ ],
+ [
+ 711474.42,
+ 7434118.57
+ ],
+ [
+ 711197.45,
+ 7434117.11
+ ]
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "Svartbyn–Hällmyran",
+ "voltage": 400,
+ "url": "https://www.svk.se/utveckling-av-kraftsystemet/transmissionsnatet/transmissionsnatsprojekt/svartbyn-hallmyran/"
+ },
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ 812586.71,
+ 7315147.79
+ ],
+ [
+ 812658.14,
+ 7315026.09
+ ],
+ [
+ 812779.85,
+ 7314224.4
+ ],
+ [
+ 812867.17,
+ 7313891.02
+ ],
+ [
+ 815100.25,
+ 7309303.15
+ ],
+ [
+ 816637.48,
+ 7306821.36
+ ],
+ [
+ 816830.62,
+ 7306509.15
+ ],
+ [
+ 817613.79,
+ 7305030.13
+ ],
+ [
+ 819460.58,
+ 7303130.42
+ ],
+ [
+ 821593.12,
+ 7303225.67
+ ],
+ [
+ 823723.02,
+ 7300892.04
+ ],
+ [
+ 825839.69,
+ 7299346.88
+ ],
+ [
+ 828895.62,
+ 7300439.61
+ ],
+ [
+ 829998.94,
+ 7299778.15
+ ],
+ [
+ 830912.0,
+ 7298910.61
+ ]
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "Svartbyn–Keminmaa",
+ "voltage": 400,
+ "url": "https://www.svk.se/utveckling-av-kraftsystemet/transmissionsnatet/transmissionsnatsprojekt/svartbynkeminmaa/"
+ },
+ "geometry": {
+ "type": "MultiLineString",
+ "coordinates": [
+ [
+ [
+ 812567.92,
+ 7315225.09
+ ],
+ [
+ 812605.26,
+ 7315194.93
+ ],
+ [
+ 812858.05,
+ 7315355.8
+ ],
+ [
+ 813034.72,
+ 7315480.04
+ ],
+ [
+ 813165.42,
+ 7315573.4
+ ],
+ [
+ 813566.86,
+ 7315859.22
+ ],
+ [
+ 813768.66,
+ 7315968.38
+ ],
+ [
+ 814079.62,
+ 7316135.71
+ ],
+ [
+ 814778.88,
+ 7316512.21
+ ],
+ [
+ 816162.65,
+ 7317213.35
+ ],
+ [
+ 816904.8,
+ 7317585.09
+ ],
+ [
+ 817936.68,
+ 7318101.03
+ ],
+ [
+ 818877.27,
+ 7318578.6
+ ],
+ [
+ 819541.38,
+ 7318795.56
+ ],
+ [
+ 821155.33,
+ 7319332.67
+ ],
+ [
+ 822880.42,
+ 7319901.52
+ ],
+ [
+ 824318.43,
+ 7320376.45
+ ],
+ [
+ 824792.03,
+ 7320537.84
+ ],
+ [
+ 826794.93,
+ 7321195.33
+ ],
+ [
+ 827310.87,
+ 7321364.67
+ ],
+ [
+ 829395.78,
+ 7323872.92
+ ],
+ [
+ 830507.03,
+ 7325206.42
+ ],
+ [
+ 830929.04,
+ 7325481.58
+ ],
+ [
+ 832077.33,
+ 7325783.21
+ ],
+ [
+ 833994.24,
+ 7325947.25
+ ],
+ [
+ 835900.56,
+ 7326106.0
+ ],
+ [
+ 838026.49,
+ 7326284.59
+ ],
+ [
+ 839435.4,
+ 7326403.66
+ ],
+ [
+ 840170.94,
+ 7326747.61
+ ],
+ [
+ 840796.68,
+ 7327079.67
+ ],
+ [
+ 841184.29,
+ 7327278.1
+ ],
+ [
+ 841775.64,
+ 7327573.11
+ ],
+ [
+ 842277.02,
+ 7327828.44
+ ],
+ [
+ 842619.66,
+ 7328226.63
+ ],
+ [
+ 843638.3,
+ 7330244.08
+ ],
+ [
+ 845228.45,
+ 7332023.41
+ ],
+ [
+ 846294.72,
+ 7333215.35
+ ],
+ [
+ 847285.58,
+ 7333446.86
+ ],
+ [
+ 848219.56,
+ 7333464.06
+ ],
+ [
+ 849287.16,
+ 7333654.56
+ ],
+ [
+ 850865.4,
+ 7333940.31
+ ],
+ [
+ 855557.78,
+ 7333879.46
+ ],
+ [
+ 856440.17,
+ 7333867.55
+ ],
+ [
+ 858126.89,
+ 7333039.41
+ ],
+ [
+ 860422.15,
+ 7332622.69
+ ],
+ [
+ 860647.04,
+ 7332584.32
+ ],
+ [
+ 861477.83,
+ 7331582.87
+ ],
+ [
+ 862029.49,
+ 7330921.42
+ ],
+ [
+ 862743.87,
+ 7330818.23
+ ],
+ [
+ 862997.87,
+ 7330822.2
+ ],
+ [
+ 863312.72,
+ 7330852.62
+ ],
+ [
+ 864597.27,
+ 7331031.22
+ ],
+ [
+ 867748.46,
+ 7330840.72
+ ],
+ [
+ 870346.67,
+ 7330685.94
+ ],
+ [
+ 871529.36,
+ 7330613.18
+ ],
+ [
+ 871549.2,
+ 7330540.42
+ ]
+ ],
+ [
+ [
+ 871627.25,
+ 7330553.65
+ ],
+ [
+ 871643.13,
+ 7330606.56
+ ],
+ [
+ 872784.8,
+ 7330537.77
+ ],
+ [
+ 874914.7,
+ 7331256.11
+ ],
+ [
+ 875232.2,
+ 7331367.24
+ ],
+ [
+ 876294.5,
+ 7331543.19
+ ],
+ [
+ 877925.66,
+ 7331814.38
+ ],
+ [
+ 878122.77,
+ 7331843.49
+ ],
+ [
+ 879288.26,
+ 7332191.42
+ ],
+ [
+ 881362.6,
+ 7332799.96
+ ],
+ [
+ 883460.74,
+ 7333423.05
+ ],
+ [
+ 885355.16,
+ 7333976.03
+ ],
+ [
+ 885971.64,
+ 7334161.24
+ ],
+ [
+ 888113.44,
+ 7334204.9
+ ],
+ [
+ 889056.68,
+ 7334038.21
+ ],
+ [
+ 890800.28,
+ 7334588.54
+ ],
+ [
+ 893225.19,
+ 7335738.16
+ ],
+ [
+ 893852.25,
+ 7336068.88
+ ],
+ [
+ 894905.29,
+ 7336627.16
+ ],
+ [
+ 896193.81,
+ 7337315.07
+ ],
+ [
+ 897082.81,
+ 7337788.68
+ ],
+ [
+ 898498.33,
+ 7338542.74
+ ],
+ [
+ 899991.91,
+ 7339337.81
+ ],
+ [
+ 900334.54,
+ 7339519.05
+ ],
+ [
+ 900494.62,
+ 7339615.62
+ ],
+ [
+ 902056.98,
+ 7340557.54
+ ],
+ [
+ 903788.68,
+ 7341602.65
+ ],
+ [
+ 905171.13,
+ 7342434.76
+ ],
+ [
+ 907155.5,
+ 7343635.97
+ ],
+ [
+ 909487.8,
+ 7344460.15
+ ],
+ [
+ 910362.25,
+ 7345091.18
+ ]
+ ]
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "Malånäset–Högnäs",
+ "voltage": 400,
+ "url": "https://www.svk.se/utveckling-av-kraftsystemet/transmissionsnatet/transmissionsnatsprojekt/malanaset-hognas/"
+ },
+ "geometry": {
+ "type": "MultiLineString",
+ "coordinates": [
+ [
+ [
+ 720662.85,
+ 7218641.46
+ ],
+ [
+ 720466.34,
+ 7218380.7
+ ],
+ [
+ 720375.64,
+ 7217995.23
+ ],
+ [
+ 720005.28,
+ 7215357.38
+ ],
+ [
+ 721698.34,
+ 7214473.06
+ ],
+ [
+ 724132.11,
+ 7213191.93
+ ],
+ [
+ 727094.97,
+ 7211623.58
+ ],
+ [
+ 728459.24,
+ 7210901.76
+ ],
+ [
+ 729566.53,
+ 7210822.4
+ ],
+ [
+ 730190.09,
+ 7210444.49
+ ],
+ [
+ 733013.12,
+ 7208774.1
+ ],
+ [
+ 736550.4,
+ 7205879.27
+ ],
+ [
+ 739721.11,
+ 7203921.67
+ ],
+ [
+ 741701.38,
+ 7203511.64
+ ],
+ [
+ 742245.58,
+ 7203300.0
+ ],
+ [
+ 744475.28,
+ 7200004.59
+ ],
+ [
+ 746281.71,
+ 7199025.79
+ ],
+ [
+ 748791.07,
+ 7197105.98
+ ],
+ [
+ 750892.28,
+ 7195594.32
+ ],
+ [
+ 751995.79,
+ 7193795.44
+ ],
+ [
+ 753628.38,
+ 7192586.11
+ ],
+ [
+ 758193.59,
+ 7191920.98
+ ]
+ ]
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "Betåsen–Nässe",
+ "voltage": 400,
+ "url": "https://www.svk.se/utveckling-av-kraftsystemet/transmissionsnatet/transmissionsnatsprojekt/betasen--nasse/"
+ },
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ 588903.66,
+ 7047292.75
+ ],
+ [
+ 588828.25,
+ 7047255.71
+ ],
+ [
+ 588637.75,
+ 7046234.42
+ ],
+ [
+ 587952.48,
+ 7045853.42
+ ],
+ [
+ 587978.94,
+ 7045570.31
+ ],
+ [
+ 589495.0,
+ 7042696.94
+ ],
+ [
+ 590743.83,
+ 7040384.48
+ ],
+ [
+ 591577.27,
+ 7038320.73
+ ],
+ [
+ 591577.27,
+ 7038042.92
+ ],
+ [
+ 591844.5,
+ 7037347.06
+ ],
+ [
+ 591751.9,
+ 7036651.21
+ ],
+ [
+ 592386.9,
+ 7035965.94
+ ],
+ [
+ 593688.65,
+ 7035317.71
+ ],
+ [
+ 594122.56,
+ 7034886.44
+ ],
+ [
+ 595088.29,
+ 7033608.5
+ ],
+ [
+ 595270.85,
+ 7033320.1
+ ],
+ [
+ 595887.33,
+ 7032137.42
+ ],
+ [
+ 597202.31,
+ 7029666.21
+ ],
+ [
+ 597874.35,
+ 7028359.17
+ ],
+ [
+ 598824.21,
+ 7027070.65
+ ],
+ [
+ 599123.19,
+ 7026665.83
+ ],
+ [
+ 599401.0,
+ 7025602.21
+ ],
+ [
+ 599631.19,
+ 7025043.94
+ ],
+ [
+ 599922.23,
+ 7024673.52
+ ],
+ [
+ 600218.56,
+ 7023964.44
+ ],
+ [
+ 601213.4,
+ 7021554.08
+ ],
+ [
+ 602517.79,
+ 7018453.17
+ ],
+ [
+ 604097.36,
+ 7014815.15
+ ],
+ [
+ 605356.77,
+ 7011902.08
+ ],
+ [
+ 605555.21,
+ 7011439.06
+ ],
+ [
+ 605613.42,
+ 7011171.83
+ ],
+ [
+ 606343.67,
+ 7010391.31
+ ],
+ [
+ 606600.31,
+ 7010147.9
+ ],
+ [
+ 606894.0,
+ 7009708.69
+ ],
+ [
+ 607219.44,
+ 7008412.23
+ ],
+ [
+ 606682.33,
+ 7007621.12
+ ],
+ [
+ 606333.08,
+ 7007086.67
+ ],
+ [
+ 606049.98,
+ 7007094.6
+ ]
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "Nässe–Vattjom",
+ "voltage": 400,
+ "url": "https://www.svk.se/utveckling-av-kraftsystemet/transmissionsnatet/transmissionsnatsprojekt/nasse-vattjom/"
+ },
+ "geometry": {
+ "type": "MultiLineString",
+ "coordinates": [
+ [
+ [
+ 606044.69,
+ 7006864.42
+ ],
+ [
+ 606174.33,
+ 7006864.42
+ ],
+ [
+ 606282.81,
+ 7006684.5
+ ],
+ [
+ 606169.04,
+ 7005803.44
+ ],
+ [
+ 605761.58,
+ 7004940.9
+ ],
+ [
+ 604433.38,
+ 7002170.71
+ ],
+ [
+ 604211.13,
+ 7001392.83
+ ],
+ [
+ 603615.81,
+ 6999180.92
+ ],
+ [
+ 602975.52,
+ 6996826.12
+ ],
+ [
+ 602478.11,
+ 6995008.44
+ ],
+ [
+ 602369.63,
+ 6994587.75
+ ],
+ [
+ 602383.01,
+ 6994207.18
+ ],
+ [
+ 602881.86,
+ 6993912.41
+ ],
+ [
+ 603055.7,
+ 6993579.85
+ ],
+ [
+ 604000.49,
+ 6992718.2
+ ],
+ [
+ 604756.32,
+ 6992393.19
+ ],
+ [
+ 605716.22,
+ 6991380.38
+ ],
+ [
+ 608422.09,
+ 6987695.71
+ ],
+ [
+ 610039.57,
+ 6986607.31
+ ],
+ [
+ 611052.38,
+ 6985337.52
+ ],
+ [
+ 611203.55,
+ 6983890.1
+ ],
+ [
+ 610432.6,
+ 6983784.29
+ ],
+ [
+ 607311.02,
+ 6982567.4
+ ],
+ [
+ 603970.25,
+ 6982068.55
+ ],
+ [
+ 601846.37,
+ 6981713.31
+ ],
+ [
+ 601504.44,
+ 6981083.42
+ ],
+ [
+ 600882.67,
+ 6976014.0
+ ],
+ [
+ 600469.92,
+ 6972807.25
+ ],
+ [
+ 600747.73,
+ 6970415.42
+ ],
+ [
+ 601075.81,
+ 6967597.6
+ ],
+ [
+ 601340.4,
+ 6965277.21
+ ],
+ [
+ 601099.63,
+ 6963515.08
+ ],
+ [
+ 600692.17,
+ 6960422.1
+ ],
+ [
+ 600668.36,
+ 6959620.42
+ ],
+ [
+ 600700.11,
+ 6959517.23
+ ],
+ [
+ 600692.17,
+ 6959178.56
+ ],
+ [
+ 600652.48,
+ 6959160.04
+ ],
+ [
+ 600536.06,
+ 6955162.19
+ ],
+ [
+ 600591.63,
+ 6955151.6
+ ],
+ [
+ 600549.29,
+ 6953431.81
+ ],
+ [
+ 600602.21,
+ 6953323.33
+ ],
+ [
+ 600522.83,
+ 6953278.35
+ ],
+ [
+ 600472.56,
+ 6951211.96
+ ],
+ [
+ 600583.69,
+ 6947060.65
+ ],
+ [
+ 600620.73,
+ 6945925.58
+ ],
+ [
+ 600385.25,
+ 6944258.71
+ ],
+ [
+ 600051.88,
+ 6941438.25
+ ],
+ [
+ 599636.48,
+ 6938038.35
+ ],
+ [
+ 599655.0,
+ 6937853.15
+ ],
+ [
+ 599580.92,
+ 6937625.6
+ ],
+ [
+ 599475.08,
+ 6936678.4
+ ],
+ [
+ 599615.31,
+ 6936141.29
+ ],
+ [
+ 599588.85,
+ 6936117.48
+ ]
+ ],
+ [
+ [
+ 599371.9,
+ 6935921.69
+ ],
+ [
+ 598975.02,
+ 6932789.02
+ ],
+ [
+ 599112.6,
+ 6931190.94
+ ],
+ [
+ 599107.31,
+ 6930227.85
+ ],
+ [
+ 599123.19,
+ 6928471.02
+ ],
+ [
+ 599162.88,
+ 6927420.62
+ ],
+ [
+ 599305.75,
+ 6923623.85
+ ],
+ [
+ 599350.73,
+ 6923467.75
+ ],
+ [
+ 599464.5,
+ 6920951.56
+ ],
+ [
+ 599840.21,
+ 6918795.21
+ ],
+ [
+ 600067.75,
+ 6917519.92
+ ]
+ ]
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "Ramsele–Kilforsen",
+ "voltage": 400,
+ "url": "https://www.svk.se/utveckling-av-kraftsystemet/transmissionsnatet/transmissionsnatsprojekt/ramsele-kilforsen/"
+ },
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ 565961.45,
+ 7051614.37
+ ],
+ [
+ 566006.8,
+ 7052067.86
+ ],
+ [
+ 566921.36,
+ 7051848.67
+ ],
+ [
+ 571222.03,
+ 7051115.52
+ ],
+ [
+ 574638.38,
+ 7050397.48
+ ],
+ [
+ 581644.93,
+ 7048980.3
+ ],
+ [
+ 582400.76,
+ 7048836.69
+ ],
+ [
+ 584622.9,
+ 7048526.8
+ ],
+ [
+ 586682.53,
+ 7047362.82
+ ],
+ [
+ 587272.08,
+ 7046841.3
+ ],
+ [
+ 587411.91,
+ 7046935.78
+ ]
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "name": "Indalsringen Ragunda",
+ "voltage": 400,
+ "url": "https://www.svk.se/utveckling-av-kraftsystemet/transmissionsnatet/transmissionsnatsprojekt/indalsringen-ragunda/"
+ },
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ 554072.25,
+ 7002389.99
+ ],
+ [
+ 554136.49,
+ 7002114.11
+ ],
+ [
+ 555863.56,
+ 7001528.34
+ ],
+ [
+ 556929.28,
+ 7001271.36
+ ],
+ [
+ 557764.48,
+ 7001203.34
+ ],
+ [
+ 561250.74,
+ 7000439.95
+ ],
+ [
+ 566244.89,
+ 6999353.44
+ ],
+ [
+ 567526.02,
+ 6998986.86
+ ],
+ [
+ 567510.9,
+ 6998506.91
+ ],
+ [
+ 567699.86,
+ 6997325.93
+ ],
+ [
+ 567983.3,
+ 6996683.47
+ ],
+ [
+ 568603.08,
+ 6995264.4
+ ],
+ [
+ 568901.63,
+ 6994625.73
+ ],
+ [
+ 569294.66,
+ 6994225.14
+ ],
+ [
+ 573776.73,
+ 6991700.66
+ ],
+ [
+ 575870.38,
+ 6990166.33
+ ],
+ [
+ 579037.31,
+ 6987713.66
+ ],
+ [
+ 580435.6,
+ 6986678.17
+ ],
+ [
+ 583028.09,
+ 6985022.91
+ ],
+ [
+ 583829.27,
+ 6983911.84
+ ],
+ [
+ 584003.12,
+ 6983926.95
+ ]
+ ]
+ }
+ }
+ ]
+}
diff --git a/rename_exchange.py b/rename_exchange.py
new file mode 100644
index 0000000..b1b02cb
--- /dev/null
+++ b/rename_exchange.py
@@ -0,0 +1,48 @@
+# © 2022 Nicko van Someren
+# License: MIT
+
+# pylint: disable=missing-module-docstring
+
+from ctypes import CDLL, get_errno
+from os import strerror, PathLike, fsencode
+from platform import machine
+from typing import Optional
+
+SYSCALL_ARCH_MAP = {
+ 'x86_64': 316,
+ 'armv6l': 382,
+ 'armv7l': 382,
+ 'aarch64': 276,
+ 'i386': 353,
+}
+
+libc = CDLL('libc.so.6', use_errno=True)
+syscall_function = libc.syscall
+ARCH = machine()
+RENAME_EXCHANGE = 2
+AT_FDCWD = -100
+
+if ARCH not in SYSCALL_ARCH_MAP:
+ raise NotImplementedError(f'Unsupported architecture: {ARCH}')
+
+SYSCALL_RENAMEAT2 = SYSCALL_ARCH_MAP[ARCH]
+
+def rename_exchange(oldpath : PathLike,
+ newpath : PathLike,
+ olddirfd : Optional[int] = None,
+ newdirfd : Optional[int] = None) -> None:
+ """Atomically exchange oldpath and newpath. Both pathnames must
+ exist but may be of different types (e.g., one could be a non-empty
+ directory and the other a symbolic link)."""
+
+ result = syscall_function(
+ SYSCALL_RENAMEAT2,
+ olddirfd if olddirfd is not None else AT_FDCWD,
+ fsencode(oldpath),
+ newdirfd if newdirfd is not None else AT_FDCWD,
+ fsencode(newpath),
+ RENAME_EXCHANGE,
+ )
+ if result != 0:
+ errno = get_errno()
+ raise OSError(errno, strerror(errno))
diff --git a/schema.sql b/schema.sql
index f4f90df..768f50b 100644
--- a/schema.sql
+++ b/schema.sql
@@ -2,12 +2,15 @@
-- PostgreSQL database dump
--
--- Dumped from database version 15.6 (Debian 15.6-0+deb12u1)
--- Dumped by pg_dump version 15.6 (Debian 15.6-0+deb12u1)
+\restrict XTQKLfyJjEgwGyWj4y8ogFznWaICeqXkLOw7GUT2TnBjUqJHf8BrjygbLvfZun2
+
+-- Dumped from database version 17.8 (Debian 17.8-0+deb13u1)
+-- Dumped by pg_dump version 17.8 (Debian 17.8-0+deb13u1)
SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
+SET transaction_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
@@ -16,21 +19,24 @@ SET xmloption = content;
SET client_min_messages = warning;
SET row_security = off;
-DROP DATABASE webmap;
+DROP DATABASE geodata;
--
--- Name: webmap; Type: DATABASE; Schema: -; Owner: postgres
+-- Name: geodata; Type: DATABASE; Schema: -; Owner: postgres
--
-CREATE DATABASE webmap WITH TEMPLATE = template0 ENCODING = 'UTF8' LOCALE_PROVIDER = icu LOCALE = 'sv_SE.UTF-8' ICU_LOCALE = 'sv-SE-x-icu';
+CREATE DATABASE geodata WITH TEMPLATE = template0 ENCODING = 'UTF8' LOCALE_PROVIDER = icu LOCALE = 'sv_SE.UTF-8' ICU_LOCALE = 'sv-SE-x-icu';
-ALTER DATABASE webmap OWNER TO postgres;
+ALTER DATABASE geodata OWNER TO postgres;
-\connect webmap
+\unrestrict XTQKLfyJjEgwGyWj4y8ogFznWaICeqXkLOw7GUT2TnBjUqJHf8BrjygbLvfZun2
+\connect geodata
+\restrict XTQKLfyJjEgwGyWj4y8ogFznWaICeqXkLOw7GUT2TnBjUqJHf8BrjygbLvfZun2
SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
+SET transaction_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
@@ -40,26 +46,193 @@ SET client_min_messages = warning;
SET row_security = off;
--
--- Name: DATABASE webmap; Type: COMMENT; Schema: -; Owner: postgres
+-- Name: DATABASE geodata; Type: COMMENT; Schema: -; Owner: postgres
+--
+
+COMMENT ON DATABASE geodata IS 'Backend PostGIS database for KlimatanalysNorr tooling';
+
+
+--
+-- Name: lm_topo250; Type: SCHEMA; Schema: -; Owner: postgres
+--
+
+CREATE SCHEMA lm_topo250;
+
+
+ALTER SCHEMA lm_topo250 OWNER TO postgres;
+
+--
+-- Name: SCHEMA lm_topo250; Type: COMMENT; Schema: -; Owner: postgres
+--
+
+COMMENT ON SCHEMA lm_topo250 IS 'Lantmäteriets Topografi 250 (vektor)';
+
+
+--
+-- Name: lst; Type: SCHEMA; Schema: -; Owner: postgres
+--
+
+CREATE SCHEMA lst;
+
+
+ALTER SCHEMA lst OWNER TO postgres;
+
+--
+-- Name: SCHEMA lst; Type: COMMENT; Schema: -; Owner: postgres
+--
+
+COMMENT ON SCHEMA lst IS 'Länsstyrelserna';
+
+
+--
+-- Name: misc; Type: SCHEMA; Schema: -; Owner: postgres
+--
+
+CREATE SCHEMA misc;
+
+
+ALTER SCHEMA misc OWNER TO postgres;
+
+--
+-- Name: SCHEMA misc; Type: COMMENT; Schema: -; Owner: postgres
+--
+
+COMMENT ON SCHEMA misc IS 'Övriga skikt';
+
+
+--
+-- Name: mrr; Type: SCHEMA; Schema: -; Owner: postgres
+--
+
+CREATE SCHEMA mrr;
+
+
+ALTER SCHEMA mrr OWNER TO postgres;
+
+--
+-- Name: SCHEMA mrr; Type: COMMENT; Schema: -; Owner: postgres
+--
+
+COMMENT ON SCHEMA mrr IS 'Mineralrättigheter och prospektering';
+
+
+--
+-- Name: nvk; Type: SCHEMA; Schema: -; Owner: postgres
+--
+
+CREATE SCHEMA nvk;
+
+
+ALTER SCHEMA nvk OWNER TO postgres;
+
+--
+-- Name: SCHEMA nvk; Type: COMMENT; Schema: -; Owner: postgres
+--
+
+COMMENT ON SCHEMA nvk IS 'Naturvårdsverket';
+
+
+--
+-- Name: nvr; Type: SCHEMA; Schema: -; Owner: postgres
+--
+
+CREATE SCHEMA nvr;
+
+
+ALTER SCHEMA nvr OWNER TO postgres;
+
+--
+-- Name: SCHEMA nvr; Type: COMMENT; Schema: -; Owner: postgres
+--
+
+COMMENT ON SCHEMA nvr IS 'Naturvårdsregistret';
+
+
+--
+-- Name: ogr_system_tables; Type: SCHEMA; Schema: -; Owner: postgres
+--
+
+CREATE SCHEMA ogr_system_tables;
+
+
+ALTER SCHEMA ogr_system_tables OWNER TO postgres;
+
+--
+-- Name: SCHEMA ogr_system_tables; Type: COMMENT; Schema: -; Owner: postgres
+--
+
+COMMENT ON SCHEMA ogr_system_tables IS 'OGR metadata';
+
+
+--
+-- Name: sametinget; Type: SCHEMA; Schema: -; Owner: postgres
+--
+
+CREATE SCHEMA sametinget;
+
+
+ALTER SCHEMA sametinget OWNER TO postgres;
+
+--
+-- Name: SCHEMA sametinget; Type: COMMENT; Schema: -; Owner: postgres
--
-COMMENT ON DATABASE webmap IS 'Backend PostGIS database for KlimatanalysNorr tooling';
+COMMENT ON SCHEMA sametinget IS 'Sametinget';
--
--- Name: postgis; Type: SCHEMA; Schema: -; Owner: postgres
+-- Name: sks; Type: SCHEMA; Schema: -; Owner: postgres
--
-CREATE SCHEMA postgis;
+CREATE SCHEMA sks;
-ALTER SCHEMA postgis OWNER TO postgres;
+ALTER SCHEMA sks OWNER TO postgres;
+
+--
+-- Name: SCHEMA sks; Type: COMMENT; Schema: -; Owner: postgres
+--
+
+COMMENT ON SCHEMA sks IS 'Skogsstyrelsen';
+
+
+--
+-- Name: svk; Type: SCHEMA; Schema: -; Owner: postgres
+--
+
+CREATE SCHEMA svk;
+
+
+ALTER SCHEMA svk OWNER TO postgres;
+
+--
+-- Name: SCHEMA svk; Type: COMMENT; Schema: -; Owner: postgres
+--
+
+COMMENT ON SCHEMA svk IS 'Svenska kraftnät';
+
+
+--
+-- Name: vbk; Type: SCHEMA; Schema: -; Owner: postgres
+--
+
+CREATE SCHEMA vbk;
+
+
+ALTER SCHEMA vbk OWNER TO postgres;
+
+--
+-- Name: SCHEMA vbk; Type: COMMENT; Schema: -; Owner: postgres
+--
+
+COMMENT ON SCHEMA vbk IS 'Vindbrukskollen';
+
--
-- Name: postgis; Type: EXTENSION; Schema: -; Owner: -
--
-CREATE EXTENSION IF NOT EXISTS postgis WITH SCHEMA postgis;
+CREATE EXTENSION IF NOT EXISTS postgis WITH SCHEMA public;
--
@@ -69,37 +242,272 @@ CREATE EXTENSION IF NOT EXISTS postgis WITH SCHEMA postgis;
COMMENT ON EXTENSION postgis IS 'Geographic objects support for PostgreSQL';
+--
+-- Name: kommunyta_subdivide_func(); Type: FUNCTION; Schema: lm_topo250; Owner: geodata
+--
+
+CREATE FUNCTION lm_topo250.kommunyta_subdivide_func() RETURNS trigger
+ LANGUAGE plpgsql
+ AS $$
+ BEGIN
+ -- Propagate changes to lm_topo250.kommunyta to lm_topo250.kommunyta_sub
+ IF (TG_OP = 'DELETE' OR TG_OP = 'UPDATE') THEN
+ DELETE FROM lm_topo250.kommunyta_sub WHERE kommunkod = OLD.kommunkod;
+ END IF;
+ IF (TG_OP = 'UPDATE' OR TG_OP = 'INSERT') THEN
+ INSERT INTO lm_topo250.kommunyta_sub(kommunkod, wkb_geometry) VALUES
+ (NEW.kommunkod, ST_Subdivide(NEW.wkb_geometry, 10));
+ END IF;
+ RETURN NULL;
+ END;
+ $$;
+
+
+ALTER FUNCTION lm_topo250.kommunyta_subdivide_func() OWNER TO geodata;
+
+--
+-- Name: lansyta_subdivide_func(); Type: FUNCTION; Schema: lm_topo250; Owner: geodata
+--
+
+CREATE FUNCTION lm_topo250.lansyta_subdivide_func() RETURNS trigger
+ LANGUAGE plpgsql
+ AS $$
+ BEGIN
+ -- Propagate changes to lm_topo250.lansyta to lm_topo250.lansyta_sub
+ IF (TG_OP = 'DELETE' OR TG_OP = 'UPDATE') THEN
+ DELETE FROM lm_topo250.lansyta_sub WHERE lanskod = OLD.lanskod;
+ END IF;
+ IF (TG_OP = 'UPDATE' OR TG_OP = 'INSERT') THEN
+ INSERT INTO lm_topo250.lansyta_sub(lanskod, wkb_geometry) VALUES
+ (NEW.lanskod, ST_Subdivide(NEW.wkb_geometry, 10));
+ END IF;
+ RETURN NULL;
+ END;
+ $$;
+
+
+ALTER FUNCTION lm_topo250.lansyta_subdivide_func() OWNER TO geodata;
+
+--
+-- Name: event_trigger_function_for_metadata(); Type: FUNCTION; Schema: ogr_system_tables; Owner: geodata
+--
+
+CREATE FUNCTION ogr_system_tables.event_trigger_function_for_metadata() RETURNS event_trigger
+ LANGUAGE plpgsql
+ AS $$
+DECLARE
+ obj record;
+BEGIN
+ IF has_schema_privilege('ogr_system_tables', 'USAGE') THEN
+ IF has_table_privilege('ogr_system_tables.metadata', 'DELETE') THEN
+ FOR obj IN SELECT * FROM pg_event_trigger_dropped_objects()
+ LOOP
+ IF obj.object_type = 'table' THEN
+ DELETE FROM ogr_system_tables.metadata m WHERE m.schema_name = obj.schema_name AND m.table_name = obj.object_name;
+ END IF;
+ END LOOP;
+ END IF;
+ END IF;
+END;
+$$;
+
+
+ALTER FUNCTION ogr_system_tables.event_trigger_function_for_metadata() OWNER TO geodata;
+
+--
+-- Name: get_counties(public.geometry); Type: FUNCTION; Schema: public; Owner: postgres
+--
+
+CREATE FUNCTION public.get_counties(public.geometry) RETURNS smallint[]
+ LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE
+ AS $_$
+ SELECT array_agg(DISTINCT t.lanskod ORDER BY t.lanskod)
+ FROM lm_topo250.lansyta_sub t
+ -- Make use of spatial indices: filter out non-overlapping envelopes first.
+ -- This function works for curves and points too, as the interior of a curve
+ -- is the set of points between its endpoints, and the interior of a point is
+ -- the point itself. It also works for 3D input geometries (in that case the
+ -- Z component is dropped).
+ -- TODO we might want to check '*T*******' too (so a line exactly on a
+ -- boundary segment would belong to both counties)
+ WHERE t.wkb_geometry && $1 AND ST_Relate(t.wkb_geometry, $1, 'T********')
+ $_$;
+
+
+ALTER FUNCTION public.get_counties(public.geometry) OWNER TO postgres;
+
+--
+-- Name: get_municipalities(public.geometry); Type: FUNCTION; Schema: public; Owner: postgres
+--
+
+CREATE FUNCTION public.get_municipalities(public.geometry) RETURNS smallint[]
+ LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE
+ AS $_$
+ SELECT array_agg(DISTINCT t.kommunkod ORDER BY t.kommunkod)
+ FROM lm_topo250.kommunyta_sub t
+ -- Make use of spatial indices: filter out non-overlapping envelopes first.
+ -- This function works for curves and points too, as the interior of a curve
+ -- is the set of points between its endpoints, and the interior of a point is
+ -- the point itself. It also works for 3D input geometries (in that case the
+ -- Z component is dropped).
+ -- TODO we might want to check '*T*******' too (so a line exactly on a
+ -- boundary segment would belong to both municipalities)
+ WHERE t.wkb_geometry && $1 AND ST_Relate(t.wkb_geometry, $1, 'T********')
+ $_$;
+
+
+ALTER FUNCTION public.get_municipalities(public.geometry) OWNER TO postgres;
+
SET default_tablespace = '';
SET default_table_access_method = heap;
--
--- Name: kommunyta; Type: TABLE; Schema: postgis; Owner: webmap_import
+-- Name: kommunyta; Type: TABLE; Schema: lm_topo250; Owner: geodata
+--
+
+CREATE TABLE lm_topo250.kommunyta (
+ ogc_fid bigint NOT NULL,
+ objektidentitet uuid NOT NULL,
+ skapad timestamp without time zone NOT NULL,
+ kommunkod smallint NOT NULL,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE lm_topo250.kommunyta OWNER TO geodata;
+
+--
+-- Name: TABLE kommunyta; Type: COMMENT; Schema: lm_topo250; Owner: geodata
+--
+
+COMMENT ON TABLE lm_topo250.kommunyta IS 'Sveriges kommuner (Lantmäteriet)';
+
+
+--
+-- Name: COLUMN kommunyta.objektidentitet; Type: COMMENT; Schema: lm_topo250; Owner: geodata
+--
+
+COMMENT ON COLUMN lm_topo250.kommunyta.objektidentitet IS 'Globalt unik identitet för generaliserat objekt';
+
+
+--
+-- Name: COLUMN kommunyta.skapad; Type: COMMENT; Schema: lm_topo250; Owner: geodata
+--
+
+COMMENT ON COLUMN lm_topo250.kommunyta.skapad IS 'Tidpunkt när objektet ändrades';
+
+
+--
+-- Name: COLUMN kommunyta.kommunkod; Type: COMMENT; Schema: lm_topo250; Owner: geodata
+--
+
+COMMENT ON COLUMN lm_topo250.kommunyta.kommunkod IS 'Fyrsiffrig kod för kommun';
+
+
+--
+-- Name: kommunyta_ogc_fid_seq; Type: SEQUENCE; Schema: lm_topo250; Owner: geodata
+--
+
+CREATE SEQUENCE lm_topo250.kommunyta_ogc_fid_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE lm_topo250.kommunyta_ogc_fid_seq OWNER TO geodata;
+
+--
+-- Name: kommunyta_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: lm_topo250; Owner: geodata
--
-CREATE TABLE postgis.kommunyta (
+ALTER SEQUENCE lm_topo250.kommunyta_ogc_fid_seq OWNED BY lm_topo250.kommunyta.ogc_fid;
+
+
+--
+-- Name: kommunyta_sub; Type: TABLE; Schema: lm_topo250; Owner: geodata
+--
+
+CREATE TABLE lm_topo250.kommunyta_sub (
ogc_fid bigint NOT NULL,
- objektidentitet uuid,
- skapad timestamp without time zone,
kommunkod smallint NOT NULL,
- wkb_geometry postgis.geometry(MultiPolygon,3006)
+ wkb_geometry public.geometry(Polygon,3006)
);
-ALTER TABLE postgis.kommunyta OWNER TO webmap_import;
+ALTER TABLE lm_topo250.kommunyta_sub OWNER TO geodata;
--
--- Name: TABLE kommunyta; Type: COMMENT; Schema: postgis; Owner: webmap_import
+-- Name: kommunyta_sub_ogc_fid_seq; Type: SEQUENCE; Schema: lm_topo250; Owner: geodata
--
-COMMENT ON TABLE postgis.kommunyta IS 'Sveriges kommuner (Lantmäteriet)';
+CREATE SEQUENCE lm_topo250.kommunyta_sub_ogc_fid_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE lm_topo250.kommunyta_sub_ogc_fid_seq OWNER TO geodata;
--
--- Name: kommunyta_ogc_fid_seq; Type: SEQUENCE; Schema: postgis; Owner: webmap_import
+-- Name: kommunyta_sub_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: lm_topo250; Owner: geodata
--
-CREATE SEQUENCE postgis.kommunyta_ogc_fid_seq
+ALTER SEQUENCE lm_topo250.kommunyta_sub_ogc_fid_seq OWNED BY lm_topo250.kommunyta_sub.ogc_fid;
+
+
+--
+-- Name: lansyta; Type: TABLE; Schema: lm_topo250; Owner: geodata
+--
+
+CREATE TABLE lm_topo250.lansyta (
+ ogc_fid bigint NOT NULL,
+ objektidentitet uuid NOT NULL,
+ skapad timestamp without time zone NOT NULL,
+ lanskod smallint NOT NULL,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE lm_topo250.lansyta OWNER TO geodata;
+
+--
+-- Name: TABLE lansyta; Type: COMMENT; Schema: lm_topo250; Owner: geodata
+--
+
+COMMENT ON TABLE lm_topo250.lansyta IS 'Sveriges län (Lantmäteriet)';
+
+
+--
+-- Name: COLUMN lansyta.objektidentitet; Type: COMMENT; Schema: lm_topo250; Owner: geodata
+--
+
+COMMENT ON COLUMN lm_topo250.lansyta.objektidentitet IS 'Globalt unik identitet för generaliserat objekt';
+
+
+--
+-- Name: COLUMN lansyta.skapad; Type: COMMENT; Schema: lm_topo250; Owner: geodata
+--
+
+COMMENT ON COLUMN lm_topo250.lansyta.skapad IS 'Tidpunkt när objektet ändrades';
+
+
+--
+-- Name: COLUMN lansyta.lanskod; Type: COMMENT; Schema: lm_topo250; Owner: geodata
+--
+
+COMMENT ON COLUMN lm_topo250.lansyta.lanskod IS 'Tvåsiffrig kod för län';
+
+
+--
+-- Name: lansyta_ogc_fid_seq; Type: SEQUENCE; Schema: lm_topo250; Owner: geodata
+--
+
+CREATE SEQUENCE lm_topo250.lansyta_ogc_fid_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
@@ -107,42 +515,1428 @@ CREATE SEQUENCE postgis.kommunyta_ogc_fid_seq
CACHE 1;
-ALTER TABLE postgis.kommunyta_ogc_fid_seq OWNER TO webmap_import;
+ALTER SEQUENCE lm_topo250.lansyta_ogc_fid_seq OWNER TO geodata;
--
--- Name: kommunyta_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: postgis; Owner: webmap_import
+-- Name: lansyta_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: lm_topo250; Owner: geodata
--
-ALTER SEQUENCE postgis.kommunyta_ogc_fid_seq OWNED BY postgis.kommunyta.ogc_fid;
+ALTER SEQUENCE lm_topo250.lansyta_ogc_fid_seq OWNED BY lm_topo250.lansyta.ogc_fid;
--
--- Name: lansyta; Type: TABLE; Schema: postgis; Owner: webmap_import
+-- Name: lansyta_sub; Type: TABLE; Schema: lm_topo250; Owner: geodata
--
-CREATE TABLE postgis.lansyta (
+CREATE TABLE lm_topo250.lansyta_sub (
ogc_fid bigint NOT NULL,
- objektidentitet uuid,
- skapad timestamp without time zone,
lanskod smallint NOT NULL,
- wkb_geometry postgis.geometry(MultiPolygon,3006)
+ wkb_geometry public.geometry(Polygon,3006)
+);
+
+
+ALTER TABLE lm_topo250.lansyta_sub OWNER TO geodata;
+
+--
+-- Name: lansyta_sub_ogc_fid_seq; Type: SEQUENCE; Schema: lm_topo250; Owner: geodata
+--
+
+CREATE SEQUENCE lm_topo250.lansyta_sub_ogc_fid_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE lm_topo250.lansyta_sub_ogc_fid_seq OWNER TO geodata;
+
+--
+-- Name: lansyta_sub_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: lm_topo250; Owner: geodata
+--
+
+ALTER SEQUENCE lm_topo250.lansyta_sub_ogc_fid_seq OWNED BY lm_topo250.lansyta_sub.ogc_fid;
+
+
+--
+-- Name: pagaende_naturreservatsbildning; Type: TABLE; Schema: lst; Owner: geodata
+--
+
+CREATE TABLE lst.pagaende_naturreservatsbildning (
+ ogc_fid bigint NOT NULL,
+ "NAMN" character varying(62) NOT NULL,
+ "GRANSJUST" date,
+ "DOS_ID" integer,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE lst.pagaende_naturreservatsbildning OWNER TO geodata;
+
+--
+-- Name: TABLE pagaende_naturreservatsbildning; Type: COMMENT; Schema: lst; Owner: geodata
+--
+
+COMMENT ON TABLE lst.pagaende_naturreservatsbildning IS 'LstBD Pågående naturreservatsbildning';
+
+
+--
+-- Name: pagaende_naturreservatsbildning_ogc_fid_seq; Type: SEQUENCE; Schema: lst; Owner: geodata
+--
+
+CREATE SEQUENCE lst.pagaende_naturreservatsbildning_ogc_fid_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE lst.pagaende_naturreservatsbildning_ogc_fid_seq OWNER TO geodata;
+
+--
+-- Name: pagaende_naturreservatsbildning_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: lst; Owner: geodata
+--
+
+ALTER SEQUENCE lst.pagaende_naturreservatsbildning_ogc_fid_seq OWNED BY lst.pagaende_naturreservatsbildning.ogc_fid;
+
+
+--
+-- Name: riksintresse_obruten_kust; Type: TABLE; Schema: lst; Owner: geodata
+--
+
+CREATE TABLE lst.riksintresse_obruten_kust (
+ ogc_fid bigint NOT NULL,
+ "ORIGINALID" character varying(16),
+ "NAMN" character varying(64),
+ "BESKRIVNIN" character varying(254),
+ "METODBESKR" character varying(254),
+ "TILLKDATUM" date,
+ "REVDATUM" date,
+ "ANM" character varying(254),
+ "OBJTYP" character varying(254),
+ "OBJEKTLANK" character varying(254),
+ "REFERENS" character varying(254),
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE lst.riksintresse_obruten_kust OWNER TO geodata;
+
+--
+-- Name: TABLE riksintresse_obruten_kust; Type: COMMENT; Schema: lst; Owner: geodata
+--
+
+COMMENT ON TABLE lst.riksintresse_obruten_kust IS 'Obruten kust (MB 4 kap 3 §)';
+
+
+--
+-- Name: COLUMN riksintresse_obruten_kust."ANM"; Type: COMMENT; Schema: lst; Owner: geodata
+--
+
+COMMENT ON COLUMN lst.riksintresse_obruten_kust."ANM" IS 'Anmärkning';
+
+
+--
+-- Name: riksintresse_obruten_kust_ogc_fid_seq; Type: SEQUENCE; Schema: lst; Owner: geodata
+--
+
+CREATE SEQUENCE lst.riksintresse_obruten_kust_ogc_fid_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE lst.riksintresse_obruten_kust_ogc_fid_seq OWNER TO geodata;
+
+--
+-- Name: riksintresse_obruten_kust_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: lst; Owner: geodata
+--
+
+ALTER SEQUENCE lst.riksintresse_obruten_kust_ogc_fid_seq OWNED BY lst.riksintresse_obruten_kust.ogc_fid;
+
+
+--
+-- Name: riksintresse_obrutet_fjall; Type: TABLE; Schema: lst; Owner: geodata
+--
+
+CREATE TABLE lst.riksintresse_obrutet_fjall (
+ ogc_fid bigint NOT NULL,
+ "ORIGINALID" character varying(16),
+ "NAMN" character varying(64) NOT NULL,
+ "BESKRIVNIN" character varying(254),
+ "METODBESKR" character varying(254),
+ "TILLKDATUM" date,
+ "REVDATUM" date,
+ "OBJEKTLANK" character varying(254),
+ "REFERENS" character varying(254),
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE lst.riksintresse_obrutet_fjall OWNER TO geodata;
+
+--
+-- Name: TABLE riksintresse_obrutet_fjall; Type: COMMENT; Schema: lst; Owner: geodata
+--
+
+COMMENT ON TABLE lst.riksintresse_obrutet_fjall IS 'Obrutet fjäll (MB 4 kap 5 §)';
+
+
+--
+-- Name: riksintresse_obrutet_fjall_ogc_fid_seq; Type: SEQUENCE; Schema: lst; Owner: geodata
+--
+
+CREATE SEQUENCE lst.riksintresse_obrutet_fjall_ogc_fid_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE lst.riksintresse_obrutet_fjall_ogc_fid_seq OWNER TO geodata;
+
+--
+-- Name: riksintresse_obrutet_fjall_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: lst; Owner: geodata
+--
+
+ALTER SEQUENCE lst.riksintresse_obrutet_fjall_ogc_fid_seq OWNED BY lst.riksintresse_obrutet_fjall.ogc_fid;
+
+
+--
+-- Name: riksintresse_rorligt_friluftsliv; Type: TABLE; Schema: lst; Owner: geodata
+--
+
+CREATE TABLE lst.riksintresse_rorligt_friluftsliv (
+ ogc_fid bigint NOT NULL,
+ "ORIGINALID" character varying(16),
+ "NAMN" character varying(64),
+ "BESKRIVNIN" character varying(254),
+ "METODBESKR" character varying(254),
+ "TILLKDATUM" date,
+ "REVDATUM" date,
+ "ANM" character varying(254),
+ "OBJEKTLANK" character varying(254),
+ "REFERENS" character varying(254),
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE lst.riksintresse_rorligt_friluftsliv OWNER TO geodata;
+
+--
+-- Name: TABLE riksintresse_rorligt_friluftsliv; Type: COMMENT; Schema: lst; Owner: geodata
+--
+
+COMMENT ON TABLE lst.riksintresse_rorligt_friluftsliv IS 'Rörligt friluftsliv (MB 4 kap 1 och 2 §§)';
+
+
+--
+-- Name: COLUMN riksintresse_rorligt_friluftsliv."ANM"; Type: COMMENT; Schema: lst; Owner: geodata
+--
+
+COMMENT ON COLUMN lst.riksintresse_rorligt_friluftsliv."ANM" IS 'Anmärkning';
+
+
+--
+-- Name: riksintresse_rorligt_friluftsliv_ogc_fid_seq; Type: SEQUENCE; Schema: lst; Owner: geodata
+--
+
+CREATE SEQUENCE lst.riksintresse_rorligt_friluftsliv_ogc_fid_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE lst.riksintresse_rorligt_friluftsliv_ogc_fid_seq OWNER TO geodata;
+
+--
+-- Name: riksintresse_rorligt_friluftsliv_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: lst; Owner: geodata
+--
+
+ALTER SEQUENCE lst.riksintresse_rorligt_friluftsliv_ogc_fid_seq OWNED BY lst.riksintresse_rorligt_friluftsliv.ogc_fid;
+
+
+--
+-- Name: riksintresse_skyddade_vattendrag; Type: TABLE; Schema: lst; Owner: geodata
+--
+
+CREATE TABLE lst.riksintresse_skyddade_vattendrag (
+ ogc_fid bigint NOT NULL,
+ "ORIGINALID" character varying(16),
+ "NAMN" character varying(64) NOT NULL,
+ "BESKRIVNIN" character varying(254),
+ "METODBESKR" character varying(254),
+ "TILLKDATUM" date,
+ "REVDATUM" date,
+ "ANM" character varying(254),
+ "DIG_SKALA" integer,
+ "OBJEKTLANK" character varying(254),
+ "REFERENS" character varying(254),
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE lst.riksintresse_skyddade_vattendrag OWNER TO geodata;
+
+--
+-- Name: TABLE riksintresse_skyddade_vattendrag; Type: COMMENT; Schema: lst; Owner: geodata
+--
+
+COMMENT ON TABLE lst.riksintresse_skyddade_vattendrag IS 'Skyddade vattendrag (MB 4 kap 6 §)';
+
+
+--
+-- Name: COLUMN riksintresse_skyddade_vattendrag."ANM"; Type: COMMENT; Schema: lst; Owner: geodata
+--
+
+COMMENT ON COLUMN lst.riksintresse_skyddade_vattendrag."ANM" IS 'Anmärkning';
+
+
+--
+-- Name: riksintresse_skyddade_vattendrag_ogc_fid_seq; Type: SEQUENCE; Schema: lst; Owner: geodata
+--
+
+CREATE SEQUENCE lst.riksintresse_skyddade_vattendrag_ogc_fid_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE lst.riksintresse_skyddade_vattendrag_ogc_fid_seq OWNER TO geodata;
+
+--
+-- Name: riksintresse_skyddade_vattendrag_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: lst; Owner: geodata
+--
+
+ALTER SEQUENCE lst.riksintresse_skyddade_vattendrag_ogc_fid_seq OWNED BY lst.riksintresse_skyddade_vattendrag.ogc_fid;
+
+
+--
+-- Name: dammar; Type: TABLE; Schema: misc; Owner: geodata
+--
+
+CREATE TABLE misc.dammar (
+ ogc_fid bigint NOT NULL,
+ "DammID" uuid NOT NULL,
+ "LST_OBJID" character varying(32),
+ "Datum" date NOT NULL,
+ "DNamn" character varying(64),
+ "Status" smallint NOT NULL,
+ "Regleringstyp" smallint NOT NULL,
+ "Konstruktion" smallint NOT NULL,
+ "ByggAr" smallint,
+ "DammHojd" real,
+ "KronLangd" real,
+ "Fiskvag" smallint NOT NULL,
+ "FiskvagByggAr" smallint,
+ "Fiskavledare" smallint,
+ "Vandringshinder" boolean NOT NULL,
+ "HARO" integer NOT NULL,
+ "Vattendistrikt" character varying(10) NOT NULL,
+ inrapp_lst character varying(32) NOT NULL,
+ eu_cd character varying(32),
+ vf_typ character varying(1),
+ vy_eucd character varying(32),
+ vy_vf_typ character varying(1),
+ "DammanlID" character varying(64),
+ "Namn" character varying(64),
+ "Verksamhet" smallint,
+ "OmbyggAr" smallint,
+ "DG" real,
+ "SG" real,
+ "HojdSys" smallint,
+ "MY" double precision,
+ "RV" double precision,
+ "Kommentar" character varying(254),
+ "XX_Distance" double precision,
+ wkb_geometry public.geometry(Point,3006) NOT NULL
+);
+
+
+ALTER TABLE misc.dammar OWNER TO geodata;
+
+--
+-- Name: TABLE dammar; Type: COMMENT; Schema: misc; Owner: geodata
+--
+
+COMMENT ON TABLE misc.dammar IS 'Dammar';
+
+
+--
+-- Name: COLUMN dammar."DammID"; Type: COMMENT; Schema: misc; Owner: geodata
+--
+
+COMMENT ON COLUMN misc.dammar."DammID" IS 'Dammenhetens identitet';
+
+
+--
+-- Name: COLUMN dammar."LST_OBJID"; Type: COMMENT; Schema: misc; Owner: geodata
+--
+
+COMMENT ON COLUMN misc.dammar."LST_OBJID" IS 'Länsstyrelsens objektid';
+
+
+--
+-- Name: COLUMN dammar."Datum"; Type: COMMENT; Schema: misc; Owner: geodata
+--
+
+COMMENT ON COLUMN misc.dammar."Datum" IS 'Datum för registrering av dammenheten i SVAR';
+
+
+--
+-- Name: COLUMN dammar."DNamn"; Type: COMMENT; Schema: misc; Owner: geodata
+--
+
+COMMENT ON COLUMN misc.dammar."DNamn" IS 'Dammenhetens namn';
+
+
+--
+-- Name: COLUMN dammar."ByggAr"; Type: COMMENT; Schema: misc; Owner: geodata
+--
+
+COMMENT ON COLUMN misc.dammar."ByggAr" IS 'År för första byggnation av dammenheten';
+
+
+--
+-- Name: COLUMN dammar."DammHojd"; Type: COMMENT; Schema: misc; Owner: geodata
+--
+
+COMMENT ON COLUMN misc.dammar."DammHojd" IS 'Dammdelens högsta höjd (m)';
+
+
+--
+-- Name: COLUMN dammar."KronLangd"; Type: COMMENT; Schema: misc; Owner: geodata
+--
+
+COMMENT ON COLUMN misc.dammar."KronLangd" IS 'Krönlängd (m)';
+
+
+--
+-- Name: COLUMN dammar."Fiskvag"; Type: COMMENT; Schema: misc; Owner: geodata
+--
+
+COMMENT ON COLUMN misc.dammar."Fiskvag" IS 'Förekomst och typ av fiskväg vid dammenheten';
+
+
+--
+-- Name: COLUMN dammar."FiskvagByggAr"; Type: COMMENT; Schema: misc; Owner: geodata
+--
+
+COMMENT ON COLUMN misc.dammar."FiskvagByggAr" IS 'Byggår fiskväg';
+
+
+--
+-- Name: COLUMN dammar."Fiskavledare"; Type: COMMENT; Schema: misc; Owner: geodata
+--
+
+COMMENT ON COLUMN misc.dammar."Fiskavledare" IS 'Finns fiskavledare till fiskvägen';
+
+
+--
+-- Name: COLUMN dammar."Vandringshinder"; Type: COMMENT; Schema: misc; Owner: geodata
+--
+
+COMMENT ON COLUMN misc.dammar."Vandringshinder" IS 'Om dammenheten utgör ett vandringshinder';
+
+
+--
+-- Name: COLUMN dammar."HARO"; Type: COMMENT; Schema: misc; Owner: geodata
+--
+
+COMMENT ON COLUMN misc.dammar."HARO" IS 'Huvudavrinningsområdesnummer';
+
+
+--
+-- Name: COLUMN dammar."Vattendistrikt"; Type: COMMENT; Schema: misc; Owner: geodata
+--
+
+COMMENT ON COLUMN misc.dammar."Vattendistrikt" IS 'Huvudavrinningsområdesnummer';
+
+
+--
+-- Name: COLUMN dammar.inrapp_lst; Type: COMMENT; Schema: misc; Owner: geodata
+--
+
+COMMENT ON COLUMN misc.dammar.inrapp_lst IS 'Den Länsstyrelse dammenheten är inrapporterad av';
+
+
+--
+-- Name: COLUMN dammar.eu_cd; Type: COMMENT; Schema: misc; Owner: geodata
+--
+
+COMMENT ON COLUMN misc.dammar.eu_cd IS 'Vattenförekomstidentitet';
+
+
+--
+-- Name: COLUMN dammar.vf_typ; Type: COMMENT; Schema: misc; Owner: geodata
+--
+
+COMMENT ON COLUMN misc.dammar.vf_typ IS 'Typ av vattenförekomst';
+
+
+--
+-- Name: COLUMN dammar.vy_eucd; Type: COMMENT; Schema: misc; Owner: geodata
+--
+
+COMMENT ON COLUMN misc.dammar.vy_eucd IS 'Vattenförekomstidentitet för eventuell vattenyta kopplat till dammanläggning';
+
+
+--
+-- Name: COLUMN dammar.vy_vf_typ; Type: COMMENT; Schema: misc; Owner: geodata
+--
+
+COMMENT ON COLUMN misc.dammar.vy_vf_typ IS 'Typ av vattenförekomst för eventuell vattenyta kopplat till dammanläggning';
+
+
+--
+-- Name: COLUMN dammar."DammanlID"; Type: COMMENT; Schema: misc; Owner: geodata
+--
+
+COMMENT ON COLUMN misc.dammar."DammanlID" IS 'Identitet för eventuell dammanläggning dammenheten är kopplad till';
+
+
+--
+-- Name: COLUMN dammar."Namn"; Type: COMMENT; Schema: misc; Owner: geodata
+--
+
+COMMENT ON COLUMN misc.dammar."Namn" IS 'Dammanläggningens namn';
+
+
+--
+-- Name: COLUMN dammar."OmbyggAr"; Type: COMMENT; Schema: misc; Owner: geodata
+--
+
+COMMENT ON COLUMN misc.dammar."OmbyggAr" IS 'År för idrifttagande av anläggning i dess nuvarande skepnad';
+
+
+--
+-- Name: COLUMN dammar."DG"; Type: COMMENT; Schema: misc; Owner: geodata
+--
+
+COMMENT ON COLUMN misc.dammar."DG" IS 'Högsta dämningsgräns (m) enligt tillstånd';
+
+
+--
+-- Name: COLUMN dammar."SG"; Type: COMMENT; Schema: misc; Owner: geodata
+--
+
+COMMENT ON COLUMN misc.dammar."SG" IS 'Högsta dämningsgräns (m) enligt tillstånd';
+
+
+--
+-- Name: COLUMN dammar."HojdSys"; Type: COMMENT; Schema: misc; Owner: geodata
+--
+
+COMMENT ON COLUMN misc.dammar."HojdSys" IS 'Höjdsystem som DG och SG räknats i';
+
+
+--
+-- Name: COLUMN dammar."MY"; Type: COMMENT; Schema: misc; Owner: geodata
+--
+
+COMMENT ON COLUMN misc.dammar."MY" IS 'Magasinsyta (km²) vid angiven DG';
+
+
+--
+-- Name: COLUMN dammar."RV"; Type: COMMENT; Schema: misc; Owner: geodata
+--
+
+COMMENT ON COLUMN misc.dammar."RV" IS 'Reglerbar volym (milj. m³)';
+
+
+--
+-- Name: COLUMN dammar."Kommentar"; Type: COMMENT; Schema: misc; Owner: geodata
+--
+
+COMMENT ON COLUMN misc.dammar."Kommentar" IS 'Inrapporterade kommentarer från Länsstyrelserna';
+
+
+--
+-- Name: COLUMN dammar."XX_Distance"; Type: COMMENT; Schema: misc; Owner: geodata
+--
+
+COMMENT ON COLUMN misc.dammar."XX_Distance" IS 'Distance to the closest SvK station or production dam';
+
+
+--
+-- Name: dammar_ogc_fid_seq; Type: SEQUENCE; Schema: misc; Owner: geodata
+--
+
+CREATE SEQUENCE misc.dammar_ogc_fid_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE misc.dammar_ogc_fid_seq OWNER TO geodata;
+
+--
+-- Name: dammar_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: misc; Owner: geodata
+--
+
+ALTER SEQUENCE misc.dammar_ogc_fid_seq OWNED BY misc.dammar.ogc_fid;
+
+
+--
+-- Name: gigafactories; Type: TABLE; Schema: misc; Owner: geodata
+--
+
+CREATE TABLE misc.gigafactories (
+ ogc_fid bigint NOT NULL,
+ "Name" character varying(254),
+ "Url" character varying(254),
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE misc.gigafactories OWNER TO geodata;
+
+--
+-- Name: TABLE gigafactories; Type: COMMENT; Schema: misc; Owner: geodata
+--
+
+COMMENT ON TABLE misc.gigafactories IS 'Stora industrisatsningar';
+
+
+--
+-- Name: gigafactories_ogc_fid_seq; Type: SEQUENCE; Schema: misc; Owner: geodata
+--
+
+CREATE SEQUENCE misc.gigafactories_ogc_fid_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE misc.gigafactories_ogc_fid_seq OWNER TO geodata;
+
+--
+-- Name: gigafactories_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: misc; Owner: geodata
+--
+
+ALTER SEQUENCE misc.gigafactories_ogc_fid_seq OWNED BY misc.gigafactories.ogc_fid;
+
+
+--
+-- Name: bearbetningskoncessioner_ansokta; Type: TABLE; Schema: mrr; Owner: geodata
+--
+
+CREATE TABLE mrr.bearbetningskoncessioner_ansokta (
+ ogc_fid bigint NOT NULL,
+ name character varying(254) NOT NULL,
+ diarynr character varying(16) NOT NULL,
+ appl_date date NOT NULL,
+ mineral character varying(254) NOT NULL,
+ owners character varying(254) NOT NULL,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE mrr.bearbetningskoncessioner_ansokta OWNER TO geodata;
+
+--
+-- Name: TABLE bearbetningskoncessioner_ansokta; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON TABLE mrr.bearbetningskoncessioner_ansokta IS 'Bearbetningskoncessioner, ansökta (SGU)';
+
+
+--
+-- Name: COLUMN bearbetningskoncessioner_ansokta.name; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.bearbetningskoncessioner_ansokta.name IS 'Namn på ansökt bearbetningskoncession';
+
+
+--
+-- Name: COLUMN bearbetningskoncessioner_ansokta.diarynr; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.bearbetningskoncessioner_ansokta.diarynr IS 'Ärendenummer i diariet';
+
+
+--
+-- Name: COLUMN bearbetningskoncessioner_ansokta.appl_date; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.bearbetningskoncessioner_ansokta.appl_date IS 'Datum när ansökan inkom till Bergsstaten';
+
+
+--
+-- Name: COLUMN bearbetningskoncessioner_ansokta.mineral; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.bearbetningskoncessioner_ansokta.mineral IS 'Ansökta koncessionsmineraler';
+
+
+--
+-- Name: COLUMN bearbetningskoncessioner_ansokta.owners; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.bearbetningskoncessioner_ansokta.owners IS 'Sökanden av bearbetningskoncessionen';
+
+
+--
+-- Name: bearbetningskoncessioner_ansokta_ogc_fid_seq; Type: SEQUENCE; Schema: mrr; Owner: geodata
+--
+
+CREATE SEQUENCE mrr.bearbetningskoncessioner_ansokta_ogc_fid_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE mrr.bearbetningskoncessioner_ansokta_ogc_fid_seq OWNER TO geodata;
+
+--
+-- Name: bearbetningskoncessioner_ansokta_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: mrr; Owner: geodata
+--
+
+ALTER SEQUENCE mrr.bearbetningskoncessioner_ansokta_ogc_fid_seq OWNED BY mrr.bearbetningskoncessioner_ansokta.ogc_fid;
+
+
+--
+-- Name: bearbetningskoncessioner_beviljade; Type: TABLE; Schema: mrr; Owner: geodata
+--
+
+CREATE TABLE mrr.bearbetningskoncessioner_beviljade (
+ ogc_fid bigint NOT NULL,
+ name character varying(254) NOT NULL,
+ licenceid character varying(16),
+ diarynr character varying(16) NOT NULL,
+ appl_date date NOT NULL,
+ dec_date date NOT NULL,
+ validfrom date NOT NULL,
+ validto date NOT NULL,
+ mineral character varying(254) NOT NULL,
+ owners character varying(254) NOT NULL,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE mrr.bearbetningskoncessioner_beviljade OWNER TO geodata;
+
+--
+-- Name: TABLE bearbetningskoncessioner_beviljade; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON TABLE mrr.bearbetningskoncessioner_beviljade IS 'Bearbetningskoncessioner, beviljade (SGU)';
+
+
+--
+-- Name: COLUMN bearbetningskoncessioner_beviljade.name; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.bearbetningskoncessioner_beviljade.name IS 'Namn på beviljad bearbetningskoncession';
+
+
+--
+-- Name: COLUMN bearbetningskoncessioner_beviljade.licenceid; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.bearbetningskoncessioner_beviljade.licenceid IS 'Tillståndsid för bearbetningskoncessionen';
+
+
+--
+-- Name: COLUMN bearbetningskoncessioner_beviljade.diarynr; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.bearbetningskoncessioner_beviljade.diarynr IS 'Ärendenummer i diariet';
+
+
+--
+-- Name: COLUMN bearbetningskoncessioner_beviljade.appl_date; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.bearbetningskoncessioner_beviljade.appl_date IS 'Datum när ansökan inkom till Bergsstaten';
+
+
+--
+-- Name: COLUMN bearbetningskoncessioner_beviljade.dec_date; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.bearbetningskoncessioner_beviljade.dec_date IS 'Datum när bearbetningskoncessionen beviljades';
+
+
+--
+-- Name: COLUMN bearbetningskoncessioner_beviljade.validfrom; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.bearbetningskoncessioner_beviljade.validfrom IS 'Datum från och med när bearbetningskoncessionen började gälla';
+
+
+--
+-- Name: COLUMN bearbetningskoncessioner_beviljade.validto; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.bearbetningskoncessioner_beviljade.validto IS 'Sista dagen bearbetningskoncessionen gäller';
+
+
+--
+-- Name: COLUMN bearbetningskoncessioner_beviljade.mineral; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.bearbetningskoncessioner_beviljade.mineral IS 'Koncessionsmineral';
+
+
+--
+-- Name: COLUMN bearbetningskoncessioner_beviljade.owners; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.bearbetningskoncessioner_beviljade.owners IS 'Innehavare av bearbetningskoncessionen';
+
+
+--
+-- Name: bearbetningskoncessioner_beviljade_ogc_fid_seq; Type: SEQUENCE; Schema: mrr; Owner: geodata
+--
+
+CREATE SEQUENCE mrr.bearbetningskoncessioner_beviljade_ogc_fid_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE mrr.bearbetningskoncessioner_beviljade_ogc_fid_seq OWNER TO geodata;
+
+--
+-- Name: bearbetningskoncessioner_beviljade_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: mrr; Owner: geodata
+--
+
+ALTER SEQUENCE mrr.bearbetningskoncessioner_beviljade_ogc_fid_seq OWNED BY mrr.bearbetningskoncessioner_beviljade.ogc_fid;
+
+
+--
+-- Name: bearbetningskoncessioner_forfallna; Type: TABLE; Schema: mrr; Owner: geodata
+--
+
+CREATE TABLE mrr.bearbetningskoncessioner_forfallna (
+ ogc_fid bigint NOT NULL,
+ name character varying(254) NOT NULL,
+ licenceid character varying(16),
+ diarynr character varying(16) NOT NULL,
+ appl_date date,
+ mineral character varying(254) NOT NULL,
+ owners character varying(254) NOT NULL,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE mrr.bearbetningskoncessioner_forfallna OWNER TO geodata;
+
+--
+-- Name: TABLE bearbetningskoncessioner_forfallna; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON TABLE mrr.bearbetningskoncessioner_forfallna IS 'Bearbetningskoncessioner, förfallna (SGU)';
+
+
+--
+-- Name: COLUMN bearbetningskoncessioner_forfallna.name; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.bearbetningskoncessioner_forfallna.name IS 'Namn på förfallen bearbetningskoncession';
+
+
+--
+-- Name: COLUMN bearbetningskoncessioner_forfallna.licenceid; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.bearbetningskoncessioner_forfallna.licenceid IS 'Tillståndsid för undersökningstillståndet';
+
+
+--
+-- Name: COLUMN bearbetningskoncessioner_forfallna.diarynr; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.bearbetningskoncessioner_forfallna.diarynr IS 'Ärendenummer i diariet';
+
+
+--
+-- Name: COLUMN bearbetningskoncessioner_forfallna.appl_date; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.bearbetningskoncessioner_forfallna.appl_date IS 'Datum när ansökan inkom till Bergsstaten';
+
+
+--
+-- Name: COLUMN bearbetningskoncessioner_forfallna.mineral; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.bearbetningskoncessioner_forfallna.mineral IS 'Koncessionsmineral';
+
+
+--
+-- Name: COLUMN bearbetningskoncessioner_forfallna.owners; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.bearbetningskoncessioner_forfallna.owners IS 'Innehavare av bearbetningskoncessionen';
+
+
+--
+-- Name: bearbetningskoncessioner_forfallna_ogc_fid_seq; Type: SEQUENCE; Schema: mrr; Owner: geodata
+--
+
+CREATE SEQUENCE mrr.bearbetningskoncessioner_forfallna_ogc_fid_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE mrr.bearbetningskoncessioner_forfallna_ogc_fid_seq OWNER TO geodata;
+
+--
+-- Name: bearbetningskoncessioner_forfallna_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: mrr; Owner: geodata
+--
+
+ALTER SEQUENCE mrr.bearbetningskoncessioner_forfallna_ogc_fid_seq OWNED BY mrr.bearbetningskoncessioner_forfallna.ogc_fid;
+
+
+--
+-- Name: markanvisningar_bk_ansokta; Type: TABLE; Schema: mrr; Owner: geodata
+--
+
+CREATE TABLE mrr.markanvisningar_bk_ansokta (
+ ogc_fid bigint NOT NULL,
+ name character varying(254) NOT NULL,
+ diarynr character varying(16) NOT NULL,
+ conc_name character varying(254) NOT NULL,
+ appl_date date NOT NULL,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE mrr.markanvisningar_bk_ansokta OWNER TO geodata;
+
+--
+-- Name: TABLE markanvisningar_bk_ansokta; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON TABLE mrr.markanvisningar_bk_ansokta IS 'Markanvisningar till bearbetningskoncessioner, ansökta (SGU)';
+
+
+--
+-- Name: COLUMN markanvisningar_bk_ansokta.name; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.markanvisningar_bk_ansokta.name IS 'Namn på ansökt markanvisning';
+
+
+--
+-- Name: COLUMN markanvisningar_bk_ansokta.diarynr; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.markanvisningar_bk_ansokta.diarynr IS 'Ärendenummer i diariet';
+
+
+--
+-- Name: COLUMN markanvisningar_bk_ansokta.conc_name; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.markanvisningar_bk_ansokta.conc_name IS 'Bearbetningskoncession(er) som markanvisningen hör till';
+
+
+--
+-- Name: COLUMN markanvisningar_bk_ansokta.appl_date; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.markanvisningar_bk_ansokta.appl_date IS 'Datum när ansökan inkom till Bergsstaten';
+
+
+--
+-- Name: markanvisningar_bk_ansokta_ogc_fid_seq; Type: SEQUENCE; Schema: mrr; Owner: geodata
+--
+
+CREATE SEQUENCE mrr.markanvisningar_bk_ansokta_ogc_fid_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE mrr.markanvisningar_bk_ansokta_ogc_fid_seq OWNER TO geodata;
+
+--
+-- Name: markanvisningar_bk_ansokta_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: mrr; Owner: geodata
+--
+
+ALTER SEQUENCE mrr.markanvisningar_bk_ansokta_ogc_fid_seq OWNED BY mrr.markanvisningar_bk_ansokta.ogc_fid;
+
+
+--
+-- Name: markanvisningar_bk_beviljade; Type: TABLE; Schema: mrr; Owner: geodata
+--
+
+CREATE TABLE mrr.markanvisningar_bk_beviljade (
+ ogc_fid bigint NOT NULL,
+ name character varying(254) NOT NULL,
+ licenceid character varying(16),
+ diarynr character varying(16) NOT NULL,
+ conc_name character varying(254) NOT NULL,
+ appl_date date NOT NULL,
+ dec_date date NOT NULL,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE mrr.markanvisningar_bk_beviljade OWNER TO geodata;
+
+--
+-- Name: TABLE markanvisningar_bk_beviljade; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON TABLE mrr.markanvisningar_bk_beviljade IS 'Markanvisningar till bearbetningskoncessioner, beviljade (SGU)';
+
+
+--
+-- Name: COLUMN markanvisningar_bk_beviljade.name; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.markanvisningar_bk_beviljade.name IS 'Namn på beviljad markanvisning';
+
+
+--
+-- Name: COLUMN markanvisningar_bk_beviljade.licenceid; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.markanvisningar_bk_beviljade.licenceid IS 'Tillståndsid för markanvisningen';
+
+
+--
+-- Name: COLUMN markanvisningar_bk_beviljade.diarynr; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.markanvisningar_bk_beviljade.diarynr IS 'Ärendenummer i diariet';
+
+
+--
+-- Name: COLUMN markanvisningar_bk_beviljade.conc_name; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.markanvisningar_bk_beviljade.conc_name IS 'Bearbetningskoncession(er) som markanvisningen hör till';
+
+
+--
+-- Name: COLUMN markanvisningar_bk_beviljade.appl_date; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.markanvisningar_bk_beviljade.appl_date IS 'Datum när ansökan inkom till Bergsstaten';
+
+
+--
+-- Name: COLUMN markanvisningar_bk_beviljade.dec_date; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.markanvisningar_bk_beviljade.dec_date IS 'Datum när markanvisningen beviljades';
+
+
+--
+-- Name: markanvisningar_bk_beviljade_ogc_fid_seq; Type: SEQUENCE; Schema: mrr; Owner: geodata
+--
+
+CREATE SEQUENCE mrr.markanvisningar_bk_beviljade_ogc_fid_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE mrr.markanvisningar_bk_beviljade_ogc_fid_seq OWNER TO geodata;
+
+--
+-- Name: markanvisningar_bk_beviljade_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: mrr; Owner: geodata
+--
+
+ALTER SEQUENCE mrr.markanvisningar_bk_beviljade_ogc_fid_seq OWNED BY mrr.markanvisningar_bk_beviljade.ogc_fid;
+
+
+--
+-- Name: ut_diamant_ansokta; Type: TABLE; Schema: mrr; Owner: geodata
+--
+
+CREATE TABLE mrr.ut_diamant_ansokta (
+ ogc_fid bigint NOT NULL,
+ name character varying(254) NOT NULL,
+ diarynr character varying(16) NOT NULL,
+ appl_date date NOT NULL,
+ mineral character varying(254) NOT NULL,
+ owners character varying(254) NOT NULL,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE mrr.ut_diamant_ansokta OWNER TO geodata;
+
+--
+-- Name: TABLE ut_diamant_ansokta; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON TABLE mrr.ut_diamant_ansokta IS 'Undersökningstillstånd - Diamant, ansökta (SGU)';
+
+
+--
+-- Name: COLUMN ut_diamant_ansokta.name; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_diamant_ansokta.name IS 'Namn på ansökt undersökningsområde';
+
+
+--
+-- Name: COLUMN ut_diamant_ansokta.diarynr; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_diamant_ansokta.diarynr IS 'Ärendenummer i diariet';
+
+
+--
+-- Name: COLUMN ut_diamant_ansokta.appl_date; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_diamant_ansokta.appl_date IS 'Datum när ansökan inkom till Bergsstaten';
+
+
+--
+-- Name: COLUMN ut_diamant_ansokta.mineral; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_diamant_ansokta.mineral IS 'Koncessionsmineral som ska eftersökas';
+
+
+--
+-- Name: COLUMN ut_diamant_ansokta.owners; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_diamant_ansokta.owners IS 'Sökanden av undersökningstillståndet';
+
+
+--
+-- Name: ut_diamant_ansokta_ogc_fid_seq; Type: SEQUENCE; Schema: mrr; Owner: geodata
+--
+
+CREATE SEQUENCE mrr.ut_diamant_ansokta_ogc_fid_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE mrr.ut_diamant_ansokta_ogc_fid_seq OWNER TO geodata;
+
+--
+-- Name: ut_diamant_ansokta_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: mrr; Owner: geodata
+--
+
+ALTER SEQUENCE mrr.ut_diamant_ansokta_ogc_fid_seq OWNED BY mrr.ut_diamant_ansokta.ogc_fid;
+
+
+--
+-- Name: ut_diamant_beviljade; Type: TABLE; Schema: mrr; Owner: geodata
+--
+
+CREATE TABLE mrr.ut_diamant_beviljade (
+ ogc_fid bigint NOT NULL,
+ name character varying(254) NOT NULL,
+ licenceid character varying(16),
+ diarynr character varying(16) NOT NULL,
+ appl_date date NOT NULL,
+ dec_date date NOT NULL,
+ validfrom date NOT NULL,
+ validto date NOT NULL,
+ mineral character varying(254) NOT NULL,
+ owners character varying(254) NOT NULL,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE mrr.ut_diamant_beviljade OWNER TO geodata;
+
+--
+-- Name: TABLE ut_diamant_beviljade; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON TABLE mrr.ut_diamant_beviljade IS 'Undersökningstillstånd - Diamant, beviljade (SGU)';
+
+
+--
+-- Name: COLUMN ut_diamant_beviljade.name; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_diamant_beviljade.name IS 'Namn på beviljat undersökningstillstånd';
+
+
+--
+-- Name: COLUMN ut_diamant_beviljade.licenceid; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_diamant_beviljade.licenceid IS 'Tillståndsid för undersökningstillståndet';
+
+
+--
+-- Name: COLUMN ut_diamant_beviljade.diarynr; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_diamant_beviljade.diarynr IS 'Ärendenummer i diariet';
+
+
+--
+-- Name: COLUMN ut_diamant_beviljade.appl_date; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_diamant_beviljade.appl_date IS 'Datum när ansökan inkom till Bergsstaten';
+
+
+--
+-- Name: COLUMN ut_diamant_beviljade.dec_date; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_diamant_beviljade.dec_date IS 'Datum när undersökningstillståndet beviljades';
+
+
+--
+-- Name: COLUMN ut_diamant_beviljade.validfrom; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_diamant_beviljade.validfrom IS 'Datum från och med när undersökningstillståndet började gälla';
+
+
+--
+-- Name: COLUMN ut_diamant_beviljade.validto; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_diamant_beviljade.validto IS 'Sista dagen undersökningstillståndet gäller';
+
+
+--
+-- Name: COLUMN ut_diamant_beviljade.mineral; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_diamant_beviljade.mineral IS 'Koncessionsmineral som eftersöks';
+
+
+--
+-- Name: COLUMN ut_diamant_beviljade.owners; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_diamant_beviljade.owners IS 'Innehavare av undersökningstillståndet';
+
+
+--
+-- Name: ut_diamant_beviljade_ogc_fid_seq; Type: SEQUENCE; Schema: mrr; Owner: geodata
+--
+
+CREATE SEQUENCE mrr.ut_diamant_beviljade_ogc_fid_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE mrr.ut_diamant_beviljade_ogc_fid_seq OWNER TO geodata;
+
+--
+-- Name: ut_diamant_beviljade_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: mrr; Owner: geodata
+--
+
+ALTER SEQUENCE mrr.ut_diamant_beviljade_ogc_fid_seq OWNED BY mrr.ut_diamant_beviljade.ogc_fid;
+
+
+--
+-- Name: ut_diamant_forbud; Type: TABLE; Schema: mrr; Owner: geodata
+--
+
+CREATE TABLE mrr.ut_diamant_forbud (
+ ogc_fid bigint NOT NULL,
+ name character varying(254) NOT NULL,
+ licenceid character varying(16),
+ diarynr character varying(16) NOT NULL,
+ validfrom date NOT NULL,
+ validto date NOT NULL,
+ mineral character varying(254) NOT NULL,
+ owners character varying(254) NOT NULL,
+ prospdata_url character varying(254),
+ prospdata_filesize_mb real,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE mrr.ut_diamant_forbud OWNER TO geodata;
+
+--
+-- Name: TABLE ut_diamant_forbud; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON TABLE mrr.ut_diamant_forbud IS 'Undersökningstillstånd - Diamant, förbud (SGU)';
+
+
+--
+-- Name: COLUMN ut_diamant_forbud.name; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_diamant_forbud.name IS 'Namn på undersökningstillstånd under förbudsår';
+
+
+--
+-- Name: COLUMN ut_diamant_forbud.licenceid; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_diamant_forbud.licenceid IS 'Tillståndsid för undersökningstillståndet';
+
+
+--
+-- Name: COLUMN ut_diamant_forbud.diarynr; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_diamant_forbud.diarynr IS 'Ärendenummer i diariet';
+
+
+--
+-- Name: COLUMN ut_diamant_forbud.validfrom; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_diamant_forbud.validfrom IS 'Datum då undersökningstillståndets förbudsår startar';
+
+
+--
+-- Name: COLUMN ut_diamant_forbud.validto; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_diamant_forbud.validto IS 'Datum då undersökningstillståndets förbudsår slutar';
+
+
+--
+-- Name: COLUMN ut_diamant_forbud.mineral; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_diamant_forbud.mineral IS 'Koncessionsmineral som eftersökts';
+
+
+--
+-- Name: COLUMN ut_diamant_forbud.owners; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_diamant_forbud.owners IS 'Innehavare av undersökningstillståndet';
+
+
+--
+-- Name: COLUMN ut_diamant_forbud.prospdata_url; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_diamant_forbud.prospdata_url IS 'Länk till nedladdning av återrapporterad prospekteringsinformation';
+
+
+--
+-- Name: COLUMN ut_diamant_forbud.prospdata_filesize_mb; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_diamant_forbud.prospdata_filesize_mb IS 'Filstorlek i Mb för återrapporterad prospekteringsinformation';
+
+
+--
+-- Name: ut_diamant_forbud_ogc_fid_seq; Type: SEQUENCE; Schema: mrr; Owner: geodata
+--
+
+CREATE SEQUENCE mrr.ut_diamant_forbud_ogc_fid_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE mrr.ut_diamant_forbud_ogc_fid_seq OWNER TO geodata;
+
+--
+-- Name: ut_diamant_forbud_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: mrr; Owner: geodata
+--
+
+ALTER SEQUENCE mrr.ut_diamant_forbud_ogc_fid_seq OWNED BY mrr.ut_diamant_forbud.ogc_fid;
+
+
+--
+-- Name: ut_metaller_industrimineral_ansokta; Type: TABLE; Schema: mrr; Owner: geodata
+--
+
+CREATE TABLE mrr.ut_metaller_industrimineral_ansokta (
+ ogc_fid bigint NOT NULL,
+ name character varying(254) NOT NULL,
+ diarynr character varying(16) NOT NULL,
+ appl_date date NOT NULL,
+ mineral character varying(254) NOT NULL,
+ owners character varying(254) NOT NULL,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
);
-ALTER TABLE postgis.lansyta OWNER TO webmap_import;
+ALTER TABLE mrr.ut_metaller_industrimineral_ansokta OWNER TO geodata;
+
+--
+-- Name: TABLE ut_metaller_industrimineral_ansokta; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON TABLE mrr.ut_metaller_industrimineral_ansokta IS 'Undersökningstillstånd - Metaller och industrimineral, ansökta (SGU)';
+
+
+--
+-- Name: COLUMN ut_metaller_industrimineral_ansokta.name; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_metaller_industrimineral_ansokta.name IS 'Namn på ansökt undersökningsområde';
+
+
+--
+-- Name: COLUMN ut_metaller_industrimineral_ansokta.diarynr; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_metaller_industrimineral_ansokta.diarynr IS 'Ärendenummer i diariet';
+
+
+--
+-- Name: COLUMN ut_metaller_industrimineral_ansokta.appl_date; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_metaller_industrimineral_ansokta.appl_date IS 'Datum när ansökan inkom till Bergsstaten';
+
+
+--
+-- Name: COLUMN ut_metaller_industrimineral_ansokta.mineral; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_metaller_industrimineral_ansokta.mineral IS 'Koncessionsmineral som ska eftersökas';
+
--
--- Name: TABLE lansyta; Type: COMMENT; Schema: postgis; Owner: webmap_import
+-- Name: COLUMN ut_metaller_industrimineral_ansokta.owners; Type: COMMENT; Schema: mrr; Owner: geodata
--
-COMMENT ON TABLE postgis.lansyta IS 'Sveriges län (Lantmäteriet)';
+COMMENT ON COLUMN mrr.ut_metaller_industrimineral_ansokta.owners IS 'Sökanden av undersökningstillståndet';
--
--- Name: lansyta_ogc_fid_seq; Type: SEQUENCE; Schema: postgis; Owner: webmap_import
+-- Name: ut_metaller_industrimineral_ansokta_ogc_fid_seq; Type: SEQUENCE; Schema: mrr; Owner: geodata
--
-CREATE SEQUENCE postgis.lansyta_ogc_fid_seq
+CREATE SEQUENCE mrr.ut_metaller_industrimineral_ansokta_ogc_fid_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
@@ -150,45 +1944,111 @@ CREATE SEQUENCE postgis.lansyta_ogc_fid_seq
CACHE 1;
-ALTER TABLE postgis.lansyta_ogc_fid_seq OWNER TO webmap_import;
+ALTER SEQUENCE mrr.ut_metaller_industrimineral_ansokta_ogc_fid_seq OWNER TO geodata;
--
--- Name: lansyta_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: postgis; Owner: webmap_import
+-- Name: ut_metaller_industrimineral_ansokta_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: mrr; Owner: geodata
--
-ALTER SEQUENCE postgis.lansyta_ogc_fid_seq OWNED BY postgis.lansyta.ogc_fid;
+ALTER SEQUENCE mrr.ut_metaller_industrimineral_ansokta_ogc_fid_seq OWNED BY mrr.ut_metaller_industrimineral_ansokta.ogc_fid;
--
--- Name: mrr:bearbetningskoncessioner_applied; Type: TABLE; Schema: postgis; Owner: webmap_import
+-- Name: ut_metaller_industrimineral_beviljade; Type: TABLE; Schema: mrr; Owner: geodata
--
-CREATE TABLE postgis."mrr:bearbetningskoncessioner_applied" (
+CREATE TABLE mrr.ut_metaller_industrimineral_beviljade (
ogc_fid bigint NOT NULL,
- "Name" character varying(254) NOT NULL,
- "Mineral" character varying(254) NOT NULL,
- "Applicant" character varying(254) NOT NULL,
- "ApplicationDate" date NOT NULL,
- "DiaryNr" character(16) NOT NULL,
- "LastUpdated" date NOT NULL,
- wkb_geometry postgis.geometry(MultiPolygon,3006)
+ name character varying(254) NOT NULL,
+ licenceid character varying(16),
+ diarynr character varying(16) NOT NULL,
+ appl_date date NOT NULL,
+ dec_date date NOT NULL,
+ validfrom date NOT NULL,
+ validto date NOT NULL,
+ mineral character varying(254) NOT NULL,
+ owners character varying(254) NOT NULL,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
);
-ALTER TABLE postgis."mrr:bearbetningskoncessioner_applied" OWNER TO webmap_import;
+ALTER TABLE mrr.ut_metaller_industrimineral_beviljade OWNER TO geodata;
+
+--
+-- Name: TABLE ut_metaller_industrimineral_beviljade; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON TABLE mrr.ut_metaller_industrimineral_beviljade IS 'Undersökningstillstånd - Metaller och industrimineral, beviljade (SGU)';
+
--
--- Name: TABLE "mrr:bearbetningskoncessioner_applied"; Type: COMMENT; Schema: postgis; Owner: webmap_import
+-- Name: COLUMN ut_metaller_industrimineral_beviljade.name; Type: COMMENT; Schema: mrr; Owner: geodata
--
-COMMENT ON TABLE postgis."mrr:bearbetningskoncessioner_applied" IS 'Bearbetningskoncessioner, ansökta (SGU)';
+COMMENT ON COLUMN mrr.ut_metaller_industrimineral_beviljade.name IS 'Namn på beviljat undersökningstillstånd';
--
--- Name: mrr:bearbetningskoncessioner_applied_ogc_fid_seq; Type: SEQUENCE; Schema: postgis; Owner: webmap_import
+-- Name: COLUMN ut_metaller_industrimineral_beviljade.licenceid; Type: COMMENT; Schema: mrr; Owner: geodata
--
-CREATE SEQUENCE postgis."mrr:bearbetningskoncessioner_applied_ogc_fid_seq"
+COMMENT ON COLUMN mrr.ut_metaller_industrimineral_beviljade.licenceid IS 'Tillståndsid för undersökningstillståndet';
+
+
+--
+-- Name: COLUMN ut_metaller_industrimineral_beviljade.diarynr; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_metaller_industrimineral_beviljade.diarynr IS 'Ärendenummer i diariet';
+
+
+--
+-- Name: COLUMN ut_metaller_industrimineral_beviljade.appl_date; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_metaller_industrimineral_beviljade.appl_date IS 'Datum när ansökan inkom till Bergsstaten';
+
+
+--
+-- Name: COLUMN ut_metaller_industrimineral_beviljade.dec_date; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_metaller_industrimineral_beviljade.dec_date IS 'Datum när undersökningstillståndet beviljades';
+
+
+--
+-- Name: COLUMN ut_metaller_industrimineral_beviljade.validfrom; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_metaller_industrimineral_beviljade.validfrom IS 'Datum från och med när undersökningstillståndet började gälla';
+
+
+--
+-- Name: COLUMN ut_metaller_industrimineral_beviljade.validto; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_metaller_industrimineral_beviljade.validto IS 'Sista dagen undersökningstillståndet gäller';
+
+
+--
+-- Name: COLUMN ut_metaller_industrimineral_beviljade.mineral; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_metaller_industrimineral_beviljade.mineral IS 'Koncessionsmineral som eftersöks';
+
+
+--
+-- Name: COLUMN ut_metaller_industrimineral_beviljade.owners; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_metaller_industrimineral_beviljade.owners IS 'Innehavare av undersökningstillståndet';
+
+
+--
+-- Name: ut_metaller_industrimineral_beviljade_ogc_fid_seq; Type: SEQUENCE; Schema: mrr; Owner: geodata
+--
+
+CREATE SEQUENCE mrr.ut_metaller_industrimineral_beviljade_ogc_fid_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
@@ -196,46 +2056,111 @@ CREATE SEQUENCE postgis."mrr:bearbetningskoncessioner_applied_ogc_fid_seq"
CACHE 1;
-ALTER TABLE postgis."mrr:bearbetningskoncessioner_applied_ogc_fid_seq" OWNER TO webmap_import;
+ALTER SEQUENCE mrr.ut_metaller_industrimineral_beviljade_ogc_fid_seq OWNER TO geodata;
--
--- Name: mrr:bearbetningskoncessioner_applied_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: postgis; Owner: webmap_import
+-- Name: ut_metaller_industrimineral_beviljade_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: mrr; Owner: geodata
--
-ALTER SEQUENCE postgis."mrr:bearbetningskoncessioner_applied_ogc_fid_seq" OWNED BY postgis."mrr:bearbetningskoncessioner_applied".ogc_fid;
+ALTER SEQUENCE mrr.ut_metaller_industrimineral_beviljade_ogc_fid_seq OWNED BY mrr.ut_metaller_industrimineral_beviljade.ogc_fid;
--
--- Name: mrr:bearbetningskoncessioner_approved; Type: TABLE; Schema: postgis; Owner: webmap_import
+-- Name: ut_metaller_industrimineral_forbud; Type: TABLE; Schema: mrr; Owner: geodata
--
-CREATE TABLE postgis."mrr:bearbetningskoncessioner_approved" (
+CREATE TABLE mrr.ut_metaller_industrimineral_forbud (
ogc_fid bigint NOT NULL,
- "Name" character varying(254) NOT NULL,
- "Mineral" character varying(254) NOT NULL,
- "Owner" character varying(254) NOT NULL,
- "ValidFrom" date NOT NULL,
- "ValidTo" date NOT NULL,
- "DiaryNr" character(16),
- "LastUpdated" date NOT NULL,
- wkb_geometry postgis.geometry(MultiPolygon,3006)
+ name character varying(254) NOT NULL,
+ licenceid character varying(16),
+ diarynr character varying(16) NOT NULL,
+ validfrom date NOT NULL,
+ validto date NOT NULL,
+ mineral character varying(254) NOT NULL,
+ owners character varying(254) NOT NULL,
+ prospdata_url character varying(254),
+ prospdata_filesize_mb real,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
);
-ALTER TABLE postgis."mrr:bearbetningskoncessioner_approved" OWNER TO webmap_import;
+ALTER TABLE mrr.ut_metaller_industrimineral_forbud OWNER TO geodata;
+
+--
+-- Name: TABLE ut_metaller_industrimineral_forbud; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON TABLE mrr.ut_metaller_industrimineral_forbud IS 'Undersökningstillstånd - Metaller och industrimineral, förbud (SGU)';
+
+
+--
+-- Name: COLUMN ut_metaller_industrimineral_forbud.name; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_metaller_industrimineral_forbud.name IS 'Namn på undersökningstillstånd under förbudsår';
+
+
+--
+-- Name: COLUMN ut_metaller_industrimineral_forbud.licenceid; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_metaller_industrimineral_forbud.licenceid IS 'Tillståndsid för undersökningstillståndet';
+
--
--- Name: TABLE "mrr:bearbetningskoncessioner_approved"; Type: COMMENT; Schema: postgis; Owner: webmap_import
+-- Name: COLUMN ut_metaller_industrimineral_forbud.diarynr; Type: COMMENT; Schema: mrr; Owner: geodata
--
-COMMENT ON TABLE postgis."mrr:bearbetningskoncessioner_approved" IS 'Bearbetningskoncessioner, beviljade (SGU)';
+COMMENT ON COLUMN mrr.ut_metaller_industrimineral_forbud.diarynr IS 'Ärendenummer i diariet';
--
--- Name: mrr:bearbetningskoncessioner_approved_ogc_fid_seq; Type: SEQUENCE; Schema: postgis; Owner: webmap_import
+-- Name: COLUMN ut_metaller_industrimineral_forbud.validfrom; Type: COMMENT; Schema: mrr; Owner: geodata
--
-CREATE SEQUENCE postgis."mrr:bearbetningskoncessioner_approved_ogc_fid_seq"
+COMMENT ON COLUMN mrr.ut_metaller_industrimineral_forbud.validfrom IS 'Datum då undersökningstillståndets förbudsår startar';
+
+
+--
+-- Name: COLUMN ut_metaller_industrimineral_forbud.validto; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_metaller_industrimineral_forbud.validto IS 'Datum då undersökningstillståndets förbudsår slutar';
+
+
+--
+-- Name: COLUMN ut_metaller_industrimineral_forbud.mineral; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_metaller_industrimineral_forbud.mineral IS 'Koncessionsmineral som eftersökts';
+
+
+--
+-- Name: COLUMN ut_metaller_industrimineral_forbud.owners; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_metaller_industrimineral_forbud.owners IS 'Innehavare av undersökningstillståndet';
+
+
+--
+-- Name: COLUMN ut_metaller_industrimineral_forbud.prospdata_url; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_metaller_industrimineral_forbud.prospdata_url IS 'Länk till nedladdning av återrapporterad prospekteringsinformation';
+
+
+--
+-- Name: COLUMN ut_metaller_industrimineral_forbud.prospdata_filesize_mb; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_metaller_industrimineral_forbud.prospdata_filesize_mb IS 'Filstorlek i Mb för återrapporterad prospekteringsinformation';
+
+
+--
+-- Name: ut_metaller_industrimineral_forbud_ogc_fid_seq; Type: SEQUENCE; Schema: mrr; Owner: geodata
+--
+
+CREATE SEQUENCE mrr.ut_metaller_industrimineral_forbud_ogc_fid_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
@@ -243,43 +2168,111 @@ CREATE SEQUENCE postgis."mrr:bearbetningskoncessioner_approved_ogc_fid_seq"
CACHE 1;
-ALTER TABLE postgis."mrr:bearbetningskoncessioner_approved_ogc_fid_seq" OWNER TO webmap_import;
+ALTER SEQUENCE mrr.ut_metaller_industrimineral_forbud_ogc_fid_seq OWNER TO geodata;
--
--- Name: mrr:bearbetningskoncessioner_approved_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: postgis; Owner: webmap_import
+-- Name: ut_metaller_industrimineral_forbud_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: mrr; Owner: geodata
--
-ALTER SEQUENCE postgis."mrr:bearbetningskoncessioner_approved_ogc_fid_seq" OWNED BY postgis."mrr:bearbetningskoncessioner_approved".ogc_fid;
+ALTER SEQUENCE mrr.ut_metaller_industrimineral_forbud_ogc_fid_seq OWNED BY mrr.ut_metaller_industrimineral_forbud.ogc_fid;
--
--- Name: mrr:markanvisningar; Type: TABLE; Schema: postgis; Owner: webmap_import
+-- Name: ut_metaller_industrimineral_forfallna; Type: TABLE; Schema: mrr; Owner: geodata
--
-CREATE TABLE postgis."mrr:markanvisningar" (
+CREATE TABLE mrr.ut_metaller_industrimineral_forfallna (
ogc_fid bigint NOT NULL,
- "Name" character varying(254) NOT NULL,
- "DecisionDate" date,
- "DiaryNr" character(16),
- "LastUpdated" date NOT NULL,
- wkb_geometry postgis.geometry(MultiPolygon,3006)
+ name character varying(254) NOT NULL,
+ licenceid character varying(16),
+ diarynr character varying(16) NOT NULL,
+ validfrom date NOT NULL,
+ validto date NOT NULL,
+ mineral character varying(254) NOT NULL,
+ owners character varying(510) NOT NULL,
+ prospdata_url character varying(254),
+ prospdata_filesize_mb real,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
);
-ALTER TABLE postgis."mrr:markanvisningar" OWNER TO webmap_import;
+ALTER TABLE mrr.ut_metaller_industrimineral_forfallna OWNER TO geodata;
+
+--
+-- Name: TABLE ut_metaller_industrimineral_forfallna; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON TABLE mrr.ut_metaller_industrimineral_forfallna IS 'Undersökningstillstånd - Metaller och industrimineral, förfallna (SGU)';
+
+
+--
+-- Name: COLUMN ut_metaller_industrimineral_forfallna.name; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_metaller_industrimineral_forfallna.name IS 'Namn på förfallet undersökningstillstånd';
+
+
+--
+-- Name: COLUMN ut_metaller_industrimineral_forfallna.licenceid; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_metaller_industrimineral_forfallna.licenceid IS 'Tillståndsid för undersökningstillståndet';
+
+
+--
+-- Name: COLUMN ut_metaller_industrimineral_forfallna.diarynr; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_metaller_industrimineral_forfallna.diarynr IS 'Ärendenummer i diariet';
+
--
--- Name: TABLE "mrr:markanvisningar"; Type: COMMENT; Schema: postgis; Owner: webmap_import
+-- Name: COLUMN ut_metaller_industrimineral_forfallna.validfrom; Type: COMMENT; Schema: mrr; Owner: geodata
--
-COMMENT ON TABLE postgis."mrr:markanvisningar" IS 'Markanvisning till koncession (SGU)';
+COMMENT ON COLUMN mrr.ut_metaller_industrimineral_forfallna.validfrom IS 'Datum från och med när undersökningstillståndet började gälla';
--
--- Name: mrr:markanvisningar_ogc_fid_seq; Type: SEQUENCE; Schema: postgis; Owner: webmap_import
+-- Name: COLUMN ut_metaller_industrimineral_forfallna.validto; Type: COMMENT; Schema: mrr; Owner: geodata
--
-CREATE SEQUENCE postgis."mrr:markanvisningar_ogc_fid_seq"
+COMMENT ON COLUMN mrr.ut_metaller_industrimineral_forfallna.validto IS 'Sista dagen undersökningstillståndet gällde';
+
+
+--
+-- Name: COLUMN ut_metaller_industrimineral_forfallna.mineral; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_metaller_industrimineral_forfallna.mineral IS 'Koncessionsmineral som eftersökts';
+
+
+--
+-- Name: COLUMN ut_metaller_industrimineral_forfallna.owners; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_metaller_industrimineral_forfallna.owners IS 'Innehavare av undersökningstillståndet';
+
+
+--
+-- Name: COLUMN ut_metaller_industrimineral_forfallna.prospdata_url; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_metaller_industrimineral_forfallna.prospdata_url IS 'Länk till nedladdning av återrapporterad prospekteringsinformation';
+
+
+--
+-- Name: COLUMN ut_metaller_industrimineral_forfallna.prospdata_filesize_mb; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_metaller_industrimineral_forfallna.prospdata_filesize_mb IS 'Filstorlek i Mb för återrapporterad prospekteringsinformation';
+
+
+--
+-- Name: ut_metaller_industrimineral_forfallna_ogc_fid_seq; Type: SEQUENCE; Schema: mrr; Owner: geodata
+--
+
+CREATE SEQUENCE mrr.ut_metaller_industrimineral_forfallna_ogc_fid_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
@@ -287,45 +2280,111 @@ CREATE SEQUENCE postgis."mrr:markanvisningar_ogc_fid_seq"
CACHE 1;
-ALTER TABLE postgis."mrr:markanvisningar_ogc_fid_seq" OWNER TO webmap_import;
+ALTER SEQUENCE mrr.ut_metaller_industrimineral_forfallna_ogc_fid_seq OWNER TO geodata;
--
--- Name: mrr:markanvisningar_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: postgis; Owner: webmap_import
+-- Name: ut_metaller_industrimineral_forfallna_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: mrr; Owner: geodata
--
-ALTER SEQUENCE postgis."mrr:markanvisningar_ogc_fid_seq" OWNED BY postgis."mrr:markanvisningar".ogc_fid;
+ALTER SEQUENCE mrr.ut_metaller_industrimineral_forfallna_ogc_fid_seq OWNED BY mrr.ut_metaller_industrimineral_forfallna.ogc_fid;
--
--- Name: mrr:mineral_applied; Type: TABLE; Schema: postgis; Owner: webmap_import
+-- Name: ut_olja_gas_diamant_forfallna; Type: TABLE; Schema: mrr; Owner: geodata
--
-CREATE TABLE postgis."mrr:mineral_applied" (
+CREATE TABLE mrr.ut_olja_gas_diamant_forfallna (
ogc_fid bigint NOT NULL,
- "Name" character varying(254) NOT NULL,
- "Mineral" character varying(254) NOT NULL,
- "Applicant" character varying(254) NOT NULL,
- "ApplicationDate" date NOT NULL,
- "DiaryNr" character(16) NOT NULL,
- "LastUpdated" date NOT NULL,
- wkb_geometry postgis.geometry(MultiPolygon,3006)
+ name character varying(254) NOT NULL,
+ licenceid character varying(16),
+ diarynr character varying(16) NOT NULL,
+ validfrom date NOT NULL,
+ validto date NOT NULL,
+ mineral character varying(254) NOT NULL,
+ owners character varying(510) NOT NULL,
+ prospdata_url character varying(254),
+ prospdata_filesize_mb real,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
);
-ALTER TABLE postgis."mrr:mineral_applied" OWNER TO webmap_import;
+ALTER TABLE mrr.ut_olja_gas_diamant_forfallna OWNER TO geodata;
+
+--
+-- Name: TABLE ut_olja_gas_diamant_forfallna; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON TABLE mrr.ut_olja_gas_diamant_forfallna IS 'Undersökningstillstånd - Olja, gas och diamant, förfallna (SGU)';
+
--
--- Name: TABLE "mrr:mineral_applied"; Type: COMMENT; Schema: postgis; Owner: webmap_import
+-- Name: COLUMN ut_olja_gas_diamant_forfallna.name; Type: COMMENT; Schema: mrr; Owner: geodata
--
-COMMENT ON TABLE postgis."mrr:mineral_applied" IS 'Undersökningstillstånd, metallar och mineral, ansökta (SGU)';
+COMMENT ON COLUMN mrr.ut_olja_gas_diamant_forfallna.name IS 'Namn på förfallet undersökningstillstånd';
--
--- Name: mrr:mineral_applied_ogc_fid_seq; Type: SEQUENCE; Schema: postgis; Owner: webmap_import
+-- Name: COLUMN ut_olja_gas_diamant_forfallna.licenceid; Type: COMMENT; Schema: mrr; Owner: geodata
--
-CREATE SEQUENCE postgis."mrr:mineral_applied_ogc_fid_seq"
+COMMENT ON COLUMN mrr.ut_olja_gas_diamant_forfallna.licenceid IS 'Tillståndsid för undersökningstillståndet';
+
+
+--
+-- Name: COLUMN ut_olja_gas_diamant_forfallna.diarynr; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_olja_gas_diamant_forfallna.diarynr IS 'Ärendenummer i diariet';
+
+
+--
+-- Name: COLUMN ut_olja_gas_diamant_forfallna.validfrom; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_olja_gas_diamant_forfallna.validfrom IS 'Datum från och med när undersökningstillståndet började gälla';
+
+
+--
+-- Name: COLUMN ut_olja_gas_diamant_forfallna.validto; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_olja_gas_diamant_forfallna.validto IS 'Sista dagen undersökningstillståndet gällde';
+
+
+--
+-- Name: COLUMN ut_olja_gas_diamant_forfallna.mineral; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_olja_gas_diamant_forfallna.mineral IS 'Koncessionsmineral som eftersökts';
+
+
+--
+-- Name: COLUMN ut_olja_gas_diamant_forfallna.owners; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_olja_gas_diamant_forfallna.owners IS 'Innehavare av undersökningstillståndet';
+
+
+--
+-- Name: COLUMN ut_olja_gas_diamant_forfallna.prospdata_url; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_olja_gas_diamant_forfallna.prospdata_url IS 'Länk till nedladdning av återrapporterad prospekteringsinformation';
+
+
+--
+-- Name: COLUMN ut_olja_gas_diamant_forfallna.prospdata_filesize_mb; Type: COMMENT; Schema: mrr; Owner: geodata
+--
+
+COMMENT ON COLUMN mrr.ut_olja_gas_diamant_forfallna.prospdata_filesize_mb IS 'Filstorlek i Mb för återrapporterad prospekteringsinformation';
+
+
+--
+-- Name: ut_olja_gas_diamant_forfallna_ogc_fid_seq; Type: SEQUENCE; Schema: mrr; Owner: geodata
+--
+
+CREATE SEQUENCE mrr.ut_olja_gas_diamant_forfallna_ogc_fid_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
@@ -333,47 +2392,46 @@ CREATE SEQUENCE postgis."mrr:mineral_applied_ogc_fid_seq"
CACHE 1;
-ALTER TABLE postgis."mrr:mineral_applied_ogc_fid_seq" OWNER TO webmap_import;
+ALTER SEQUENCE mrr.ut_olja_gas_diamant_forfallna_ogc_fid_seq OWNER TO geodata;
--
--- Name: mrr:mineral_applied_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: postgis; Owner: webmap_import
+-- Name: ut_olja_gas_diamant_forfallna_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: mrr; Owner: geodata
--
-ALTER SEQUENCE postgis."mrr:mineral_applied_ogc_fid_seq" OWNED BY postgis."mrr:mineral_applied".ogc_fid;
+ALTER SEQUENCE mrr.ut_olja_gas_diamant_forfallna_ogc_fid_seq OWNED BY mrr.ut_olja_gas_diamant_forfallna.ogc_fid;
--
--- Name: mrr:mineral_approved; Type: TABLE; Schema: postgis; Owner: webmap_import
+-- Name: naturvardsavtal; Type: TABLE; Schema: nvk; Owner: geodata
--
-CREATE TABLE postgis."mrr:mineral_approved" (
+CREATE TABLE nvk.naturvardsavtal (
ogc_fid bigint NOT NULL,
- "Name" character varying(254) NOT NULL,
- "Mineral" character varying(254) NOT NULL,
- "Owner" character varying(254) NOT NULL,
- "LicenceID" character(8) NOT NULL,
- "ValidFrom" date NOT NULL,
- "ValidTo" date NOT NULL,
- "DiaryNr" character(16),
- "LastUpdated" date NOT NULL,
- wkb_geometry postgis.geometry(MultiPolygon,3006)
+ "ID" integer NOT NULL,
+ "DIARIENRNV" character varying(12) NOT NULL,
+ "STATUS" character varying(32) NOT NULL,
+ "OBJNAMN" character varying(64),
+ "FASTBET" character varying(64),
+ "DATSTART" date NOT NULL,
+ "DATSLUT" date NOT NULL,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
);
-ALTER TABLE postgis."mrr:mineral_approved" OWNER TO webmap_import;
+ALTER TABLE nvk.naturvardsavtal OWNER TO geodata;
--
--- Name: TABLE "mrr:mineral_approved"; Type: COMMENT; Schema: postgis; Owner: webmap_import
+-- Name: TABLE naturvardsavtal; Type: COMMENT; Schema: nvk; Owner: geodata
--
-COMMENT ON TABLE postgis."mrr:mineral_approved" IS 'Undersökningstillstånd, metallar och mineral, beviljade (SGU)';
+COMMENT ON TABLE nvk.naturvardsavtal IS 'Naturvårdsavtal (Naturvårdsverket, Länsstyrelse)';
--
--- Name: mrr:mineral_approved_ogc_fid_seq; Type: SEQUENCE; Schema: postgis; Owner: webmap_import
+-- Name: naturvardsavtal_ogc_fid_seq; Type: SEQUENCE; Schema: nvk; Owner: geodata
--
-CREATE SEQUENCE postgis."mrr:mineral_approved_ogc_fid_seq"
+CREATE SEQUENCE nvk.naturvardsavtal_ogc_fid_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
@@ -381,45 +2439,66 @@ CREATE SEQUENCE postgis."mrr:mineral_approved_ogc_fid_seq"
CACHE 1;
-ALTER TABLE postgis."mrr:mineral_approved_ogc_fid_seq" OWNER TO webmap_import;
+ALTER SEQUENCE nvk.naturvardsavtal_ogc_fid_seq OWNER TO geodata;
--
--- Name: mrr:mineral_approved_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: postgis; Owner: webmap_import
+-- Name: naturvardsavtal_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: nvk; Owner: geodata
--
-ALTER SEQUENCE postgis."mrr:mineral_approved_ogc_fid_seq" OWNED BY postgis."mrr:mineral_approved".ogc_fid;
+ALTER SEQUENCE nvk.naturvardsavtal_ogc_fid_seq OWNED BY nvk.naturvardsavtal.ogc_fid;
--
--- Name: mrr:olja_gas_diamant_applied; Type: TABLE; Schema: postgis; Owner: webmap_import
+-- Name: riksintresse_friluftsliv; Type: TABLE; Schema: nvk; Owner: geodata
--
-CREATE TABLE postgis."mrr:olja_gas_diamant_applied" (
+CREATE TABLE nvk.riksintresse_friluftsliv (
ogc_fid bigint NOT NULL,
- "Name" character varying(254) NOT NULL,
- "Mineral" character varying(254) NOT NULL,
- "Applicant" character varying(254) NOT NULL,
- "ApplicationDate" date NOT NULL,
- "DiaryNr" character(16) NOT NULL,
- "LastUpdated" date NOT NULL,
- wkb_geometry postgis.geometry(MultiPolygon,3006)
+ "SKYDD" character varying(64) NOT NULL,
+ "OMRADESNR" character varying(16) NOT NULL,
+ "AMNESOMR" character varying(16) NOT NULL,
+ "NAMN" character varying(127) NOT NULL,
+ "LANK_VARDE" character varying(127) NOT NULL,
+ "BESLDATUM" date,
+ "LAGRUM" character varying(64) NOT NULL,
+ "ARENDENR" character varying(11) NOT NULL,
+ "LANK_BESLU" character varying(127) NOT NULL,
+ "AKTIVITET" character varying(127),
+ "NATURTYP" character varying(127),
+ "AREA_LAND_" double precision,
+ "AREA_VATTE" double precision,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
);
-ALTER TABLE postgis."mrr:olja_gas_diamant_applied" OWNER TO webmap_import;
+ALTER TABLE nvk.riksintresse_friluftsliv OWNER TO geodata;
+
+--
+-- Name: TABLE riksintresse_friluftsliv; Type: COMMENT; Schema: nvk; Owner: geodata
+--
+
+COMMENT ON TABLE nvk.riksintresse_friluftsliv IS 'Riksintresse friluftsliv';
+
--
--- Name: TABLE "mrr:olja_gas_diamant_applied"; Type: COMMENT; Schema: postgis; Owner: webmap_import
+-- Name: COLUMN riksintresse_friluftsliv."AREA_LAND_"; Type: COMMENT; Schema: nvk; Owner: geodata
--
-COMMENT ON TABLE postgis."mrr:olja_gas_diamant_applied" IS 'Undersökningstillstånd, olja, gas och diamant, ansökta (SGU)';
+COMMENT ON COLUMN nvk.riksintresse_friluftsliv."AREA_LAND_" IS 'Areal land i hektar';
--
--- Name: mrr:olja_gas_diamant_applied_ogc_fid_seq; Type: SEQUENCE; Schema: postgis; Owner: webmap_import
+-- Name: COLUMN riksintresse_friluftsliv."AREA_VATTE"; Type: COMMENT; Schema: nvk; Owner: geodata
--
-CREATE SEQUENCE postgis."mrr:olja_gas_diamant_applied_ogc_fid_seq"
+COMMENT ON COLUMN nvk.riksintresse_friluftsliv."AREA_VATTE" IS 'Areal vatten i hektar';
+
+
+--
+-- Name: riksintresse_friluftsliv_ogc_fid_seq; Type: SEQUENCE; Schema: nvk; Owner: geodata
+--
+
+CREATE SEQUENCE nvk.riksintresse_friluftsliv_ogc_fid_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
@@ -427,47 +2506,47 @@ CREATE SEQUENCE postgis."mrr:olja_gas_diamant_applied_ogc_fid_seq"
CACHE 1;
-ALTER TABLE postgis."mrr:olja_gas_diamant_applied_ogc_fid_seq" OWNER TO webmap_import;
+ALTER SEQUENCE nvk.riksintresse_friluftsliv_ogc_fid_seq OWNER TO geodata;
--
--- Name: mrr:olja_gas_diamant_applied_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: postgis; Owner: webmap_import
+-- Name: riksintresse_friluftsliv_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: nvk; Owner: geodata
--
-ALTER SEQUENCE postgis."mrr:olja_gas_diamant_applied_ogc_fid_seq" OWNED BY postgis."mrr:olja_gas_diamant_applied".ogc_fid;
+ALTER SEQUENCE nvk.riksintresse_friluftsliv_ogc_fid_seq OWNED BY nvk.riksintresse_friluftsliv.ogc_fid;
--
--- Name: mrr:olja_gas_diamant_approved; Type: TABLE; Schema: postgis; Owner: webmap_import
+-- Name: riksintresse_naturvard; Type: TABLE; Schema: nvk; Owner: geodata
--
-CREATE TABLE postgis."mrr:olja_gas_diamant_approved" (
+CREATE TABLE nvk.riksintresse_naturvard (
ogc_fid bigint NOT NULL,
- "Name" character varying(254) NOT NULL,
- "Mineral" character varying(254) NOT NULL,
- "Owner" character varying(254) NOT NULL,
- "LicenceID" character(8) NOT NULL,
- "ValidFrom" date NOT NULL,
- "ValidTo" date NOT NULL,
- "DiaryNr" character(16),
- "LastUpdated" date NOT NULL,
- wkb_geometry postgis.geometry(MultiPolygon,3006)
+ "SKYDD" character varying(64) NOT NULL,
+ "AMNESOMRAD" character varying(64) NOT NULL,
+ "NAMN" character varying(127) NOT NULL,
+ "BESKRIVNIN" character varying(254) NOT NULL,
+ "LAGRUM" character varying(64) NOT NULL,
+ "BESLUTSDAT" date NOT NULL,
+ "ORGINALID" character varying(16) NOT NULL,
+ "RIKSID" integer NOT NULL,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
);
-ALTER TABLE postgis."mrr:olja_gas_diamant_approved" OWNER TO webmap_import;
+ALTER TABLE nvk.riksintresse_naturvard OWNER TO geodata;
--
--- Name: TABLE "mrr:olja_gas_diamant_approved"; Type: COMMENT; Schema: postgis; Owner: webmap_import
+-- Name: TABLE riksintresse_naturvard; Type: COMMENT; Schema: nvk; Owner: geodata
--
-COMMENT ON TABLE postgis."mrr:olja_gas_diamant_approved" IS 'Undersökningstillstånd, olja, gas och diamant, beviljade (SGU)';
+COMMENT ON TABLE nvk.riksintresse_naturvard IS 'Riksintresse naturvård';
--
--- Name: mrr:olja_gas_diamant_approved_ogc_fid_seq; Type: SEQUENCE; Schema: postgis; Owner: webmap_import
+-- Name: riksintresse_naturvard_ogc_fid_seq; Type: SEQUENCE; Schema: nvk; Owner: geodata
--
-CREATE SEQUENCE postgis."mrr:olja_gas_diamant_approved_ogc_fid_seq"
+CREATE SEQUENCE nvk.riksintresse_naturvard_ogc_fid_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
@@ -475,46 +2554,157 @@ CREATE SEQUENCE postgis."mrr:olja_gas_diamant_approved_ogc_fid_seq"
CACHE 1;
-ALTER TABLE postgis."mrr:olja_gas_diamant_approved_ogc_fid_seq" OWNER TO webmap_import;
+ALTER SEQUENCE nvk.riksintresse_naturvard_ogc_fid_seq OWNER TO geodata;
--
--- Name: mrr:olja_gas_diamant_approved_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: postgis; Owner: webmap_import
+-- Name: riksintresse_naturvard_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: nvk; Owner: geodata
--
-ALTER SEQUENCE postgis."mrr:olja_gas_diamant_approved_ogc_fid_seq" OWNED BY postgis."mrr:olja_gas_diamant_approved".ogc_fid;
+ALTER SEQUENCE nvk.riksintresse_naturvard_ogc_fid_seq OWNED BY nvk.riksintresse_naturvard.ogc_fid;
--
--- Name: mrr:torvkoncessioner; Type: TABLE; Schema: postgis; Owner: webmap_import
+-- Name: skyddsvard_statlig_skog; Type: TABLE; Schema: nvk; Owner: geodata
--
-CREATE TABLE postgis."mrr:torvkoncessioner" (
+CREATE TABLE nvk.skyddsvard_statlig_skog (
ogc_fid bigint NOT NULL,
- "Name" character varying(254) NOT NULL,
- "Mineral" character varying(254),
- "Owner" character varying(254) NOT NULL,
- "ValidFrom" date NOT NULL,
- "ValidTo" date NOT NULL,
- "DiaryNr" character(16),
- "LastUpdated" date NOT NULL,
- wkb_geometry postgis.geometry(MultiPolygon,3006)
+ "ID" integer NOT NULL,
+ "NAMN" character varying(62) NOT NULL,
+ "AR" smallint NOT NULL,
+ "NATURGEOGR" character varying(62),
+ "OBJEKTKATE" character varying(12),
+ "MARKAGARE" character varying(254),
+ "VARDEKARNA" double precision NOT NULL,
+ "UTV_MARK" double precision NOT NULL,
+ "TOTAL_AREA" double precision NOT NULL,
+ "LAND" double precision NOT NULL,
+ "VATTEN" double precision NOT NULL,
+ "PROD_SKOG" double precision NOT NULL,
+ "SKOG_O_FJG" double precision NOT NULL,
+ "SKOG_N_FJG" double precision NOT NULL,
+ "SKYDDSZON" double precision NOT NULL,
+ "ARRO_MARK" double precision NOT NULL,
+ "KRITERIER" character varying(254) NOT NULL,
+ "BESKRIVN" character varying(254) NOT NULL,
+ "LST_BEDOMN" character varying(254) NOT NULL,
+ "KALLOR" character varying(254),
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
);
-ALTER TABLE postgis."mrr:torvkoncessioner" OWNER TO webmap_import;
+ALTER TABLE nvk.skyddsvard_statlig_skog OWNER TO geodata;
--
--- Name: TABLE "mrr:torvkoncessioner"; Type: COMMENT; Schema: postgis; Owner: webmap_import
+-- Name: TABLE skyddsvard_statlig_skog; Type: COMMENT; Schema: nvk; Owner: geodata
--
-COMMENT ON TABLE postgis."mrr:torvkoncessioner" IS 'Torvkoncessioner (SGU)';
+COMMENT ON TABLE nvk.skyddsvard_statlig_skog IS 'Skyddsvärda statliga skogar';
--
--- Name: mrr:torvkoncessioner_ogc_fid_seq; Type: SEQUENCE; Schema: postgis; Owner: webmap_import
+-- Name: COLUMN skyddsvard_statlig_skog."AR"; Type: COMMENT; Schema: nvk; Owner: geodata
--
-CREATE SEQUENCE postgis."mrr:torvkoncessioner_ogc_fid_seq"
+COMMENT ON COLUMN nvk.skyddsvard_statlig_skog."AR" IS 'År';
+
+
+--
+-- Name: COLUMN skyddsvard_statlig_skog."NATURGEOGR"; Type: COMMENT; Schema: nvk; Owner: geodata
+--
+
+COMMENT ON COLUMN nvk.skyddsvard_statlig_skog."NATURGEOGR" IS 'Naturgeografisk region';
+
+
+--
+-- Name: COLUMN skyddsvard_statlig_skog."OBJEKTKATE"; Type: COMMENT; Schema: nvk; Owner: geodata
+--
+
+COMMENT ON COLUMN nvk.skyddsvard_statlig_skog."OBJEKTKATE" IS 'Objektskategori';
+
+
+--
+-- Name: COLUMN skyddsvard_statlig_skog."MARKAGARE"; Type: COMMENT; Schema: nvk; Owner: geodata
+--
+
+COMMENT ON COLUMN nvk.skyddsvard_statlig_skog."MARKAGARE" IS 'Markägare';
+
+
+--
+-- Name: COLUMN skyddsvard_statlig_skog."VARDEKARNA"; Type: COMMENT; Schema: nvk; Owner: geodata
+--
+
+COMMENT ON COLUMN nvk.skyddsvard_statlig_skog."VARDEKARNA" IS 'Areal värdekärna (ha)';
+
+
+--
+-- Name: COLUMN skyddsvard_statlig_skog."UTV_MARK"; Type: COMMENT; Schema: nvk; Owner: geodata
+--
+
+COMMENT ON COLUMN nvk.skyddsvard_statlig_skog."UTV_MARK" IS 'Areal utvecklingsmark (ha)';
+
+
+--
+-- Name: COLUMN skyddsvard_statlig_skog."TOTAL_AREA"; Type: COMMENT; Schema: nvk; Owner: geodata
+--
+
+COMMENT ON COLUMN nvk.skyddsvard_statlig_skog."TOTAL_AREA" IS 'Totalareal (ha)';
+
+
+--
+-- Name: COLUMN skyddsvard_statlig_skog."LAND"; Type: COMMENT; Schema: nvk; Owner: geodata
+--
+
+COMMENT ON COLUMN nvk.skyddsvard_statlig_skog."LAND" IS 'Areal land (ha)';
+
+
+--
+-- Name: COLUMN skyddsvard_statlig_skog."VATTEN"; Type: COMMENT; Schema: nvk; Owner: geodata
+--
+
+COMMENT ON COLUMN nvk.skyddsvard_statlig_skog."VATTEN" IS 'Areal vatten (ha)';
+
+
+--
+-- Name: COLUMN skyddsvard_statlig_skog."PROD_SKOG"; Type: COMMENT; Schema: nvk; Owner: geodata
+--
+
+COMMENT ON COLUMN nvk.skyddsvard_statlig_skog."PROD_SKOG" IS 'Areal produktiv skogsmark (ha)';
+
+
+--
+-- Name: COLUMN skyddsvard_statlig_skog."SKOG_O_FJG"; Type: COMMENT; Schema: nvk; Owner: geodata
+--
+
+COMMENT ON COLUMN nvk.skyddsvard_statlig_skog."SKOG_O_FJG" IS 'Areal produktiv skogsmark ovanför fjällnära gräns (ha)';
+
+
+--
+-- Name: COLUMN skyddsvard_statlig_skog."SKOG_N_FJG"; Type: COMMENT; Schema: nvk; Owner: geodata
+--
+
+COMMENT ON COLUMN nvk.skyddsvard_statlig_skog."SKOG_N_FJG" IS 'Areal produktiv skogsmark nedanför fjällnära gräns (ha)';
+
+
+--
+-- Name: COLUMN skyddsvard_statlig_skog."SKYDDSZON"; Type: COMMENT; Schema: nvk; Owner: geodata
+--
+
+COMMENT ON COLUMN nvk.skyddsvard_statlig_skog."SKYDDSZON" IS 'Areal skyddszon (ha)';
+
+
+--
+-- Name: COLUMN skyddsvard_statlig_skog."ARRO_MARK"; Type: COMMENT; Schema: nvk; Owner: geodata
+--
+
+COMMENT ON COLUMN nvk.skyddsvard_statlig_skog."ARRO_MARK" IS 'Areal arronderingsmark (ha)';
+
+
+--
+-- Name: skyddsvard_statlig_skog_ogc_fid_seq; Type: SEQUENCE; Schema: nvk; Owner: geodata
+--
+
+CREATE SEQUENCE nvk.skyddsvard_statlig_skog_ogc_fid_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
@@ -522,52 +2712,2950 @@ CREATE SEQUENCE postgis."mrr:torvkoncessioner_ogc_fid_seq"
CACHE 1;
-ALTER TABLE postgis."mrr:torvkoncessioner_ogc_fid_seq" OWNER TO webmap_import;
+ALTER SEQUENCE nvk.skyddsvard_statlig_skog_ogc_fid_seq OWNER TO geodata;
--
--- Name: mrr:torvkoncessioner_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: postgis; Owner: webmap_import
+-- Name: skyddsvard_statlig_skog_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: nvk; Owner: geodata
--
-ALTER SEQUENCE postgis."mrr:torvkoncessioner_ogc_fid_seq" OWNED BY postgis."mrr:torvkoncessioner".ogc_fid;
+ALTER SEQUENCE nvk.skyddsvard_statlig_skog_ogc_fid_seq OWNED BY nvk.skyddsvard_statlig_skog.ogc_fid;
--
--- Name: sks:AvverkAnm; Type: TABLE; Schema: postgis; Owner: webmap_import
+-- Name: Biosfarsomraden; Type: TABLE; Schema: nvr; Owner: geodata
--
-CREATE TABLE postgis."sks:AvverkAnm" (
+CREATE TABLE nvr."Biosfarsomraden" (
+ ogc_fid bigint NOT NULL,
+ "SKYDDSTYP" character varying(32) NOT NULL,
+ "NAMN" character varying(32) NOT NULL,
+ "LINK" character varying(254) NOT NULL,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE nvr."Biosfarsomraden" OWNER TO geodata;
+
+--
+-- Name: TABLE "Biosfarsomraden"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON TABLE nvr."Biosfarsomraden" IS 'Biosfärsområden (UNESCO)';
+
+
+--
+-- Name: COLUMN "Biosfarsomraden"."SKYDDSTYP"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Biosfarsomraden"."SKYDDSTYP" IS 'Skyddstyp';
+
+
+--
+-- Name: Biosfarsomraden_ogc_fid_seq; Type: SEQUENCE; Schema: nvr; Owner: geodata
+--
+
+CREATE SEQUENCE nvr."Biosfarsomraden_ogc_fid_seq"
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE nvr."Biosfarsomraden_ogc_fid_seq" OWNER TO geodata;
+
+--
+-- Name: Biosfarsomraden_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: nvr; Owner: geodata
+--
+
+ALTER SEQUENCE nvr."Biosfarsomraden_ogc_fid_seq" OWNED BY nvr."Biosfarsomraden".ogc_fid;
+
+
+--
+-- Name: Biotopskydd; Type: TABLE; Schema: nvr; Owner: geodata
+--
+
+CREATE TABLE nvr."Biotopskydd" (
+ ogc_fid bigint NOT NULL,
+ "Uuid" uuid NOT NULL,
+ "Beteckn" character varying(12) NOT NULL,
+ "ArendeAr" smallint NOT NULL,
+ "Biotyp" character varying(254) NOT NULL,
+ "Naturtyp" character varying(254),
+ "AreaTot" double precision,
+ "AreaProd" double precision,
+ "Standort" character varying(254),
+ "Datbeslut" date,
+ "Url" character varying(254),
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE nvr."Biotopskydd" OWNER TO geodata;
+
+--
+-- Name: TABLE "Biotopskydd"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON TABLE nvr."Biotopskydd" IS 'Biotopskydd i skogsmark (beslutade av Skogsstyrelsen)';
+
+
+--
+-- Name: COLUMN "Biotopskydd"."Uuid"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Biotopskydd"."Uuid" IS 'Unik identitet';
+
+
+--
+-- Name: COLUMN "Biotopskydd"."Beteckn"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Biotopskydd"."Beteckn" IS 'Ärendebeteckning';
+
+
+--
+-- Name: COLUMN "Biotopskydd"."ArendeAr"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Biotopskydd"."ArendeAr" IS 'År anmälan/ansökan registrerades';
+
+
+--
+-- Name: COLUMN "Biotopskydd"."Biotyp"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Biotopskydd"."Biotyp" IS 'Biotoptyp';
+
+
+--
+-- Name: COLUMN "Biotopskydd"."Standort"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Biotopskydd"."Standort" IS 'Ståndortsindex';
+
+
+--
+-- Name: COLUMN "Biotopskydd"."Datbeslut"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Biotopskydd"."Datbeslut" IS 'Datum för beslut';
+
+
+--
+-- Name: COLUMN "Biotopskydd"."Url"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Biotopskydd"."Url" IS 'Länk till visningsformulär i Skogens Pärlor';
+
+
+--
+-- Name: Biotopskydd_ogc_fid_seq; Type: SEQUENCE; Schema: nvr; Owner: geodata
+--
+
+CREATE SEQUENCE nvr."Biotopskydd_ogc_fid_seq"
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE nvr."Biotopskydd_ogc_fid_seq" OWNER TO geodata;
+
+--
+-- Name: Biotopskydd_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: nvr; Owner: geodata
+--
+
+ALTER SEQUENCE nvr."Biotopskydd_ogc_fid_seq" OWNED BY nvr."Biotopskydd".ogc_fid;
+
+
+--
+-- Name: Djur_och_vaxtskyddsomrade; Type: TABLE; Schema: nvr; Owner: geodata
+--
+
+CREATE TABLE nvr."Djur_och_vaxtskyddsomrade" (
+ ogc_fid bigint NOT NULL,
+ "NVRID" integer NOT NULL,
+ "NAMN" character varying(254) NOT NULL,
+ "SKYDDSTYP" character varying(32) NOT NULL,
+ "BESLSTATUS" character varying(12) NOT NULL,
+ "URSBESLDAT" date NOT NULL,
+ "IKRAFTDATF" date,
+ "URSGALLDAT" date,
+ "SENGALLDAT" date,
+ "IUCNKAT" character varying(254) NOT NULL,
+ "FORVALTARE" character varying(62) NOT NULL,
+ "LAND_HA" double precision,
+ "VATTEN_HA" double precision,
+ "SKOG_HA" double precision,
+ "GEOSTATUS" character varying(62) NOT NULL,
+ "DIARIENR" character varying(62),
+ "LAGRUM" character varying(62) NOT NULL,
+ "BESLMYND" character varying(32) NOT NULL,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE nvr."Djur_och_vaxtskyddsomrade" OWNER TO geodata;
+
+--
+-- Name: TABLE "Djur_och_vaxtskyddsomrade"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON TABLE nvr."Djur_och_vaxtskyddsomrade" IS 'Djur- och växtskyddsområden';
+
+
+--
+-- Name: COLUMN "Djur_och_vaxtskyddsomrade"."NVRID"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Djur_och_vaxtskyddsomrade"."NVRID" IS 'Områdets unika ID i naturvårdsregistret';
+
+
+--
+-- Name: COLUMN "Djur_och_vaxtskyddsomrade"."NAMN"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Djur_och_vaxtskyddsomrade"."NAMN" IS 'Områdets namn';
+
+
+--
+-- Name: COLUMN "Djur_och_vaxtskyddsomrade"."SKYDDSTYP"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Djur_och_vaxtskyddsomrade"."SKYDDSTYP" IS 'Skyddstyp';
+
+
+--
+-- Name: COLUMN "Djur_och_vaxtskyddsomrade"."BESLSTATUS"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Djur_och_vaxtskyddsomrade"."BESLSTATUS" IS 'Beslutsstatus';
+
+
+--
+-- Name: COLUMN "Djur_och_vaxtskyddsomrade"."URSBESLDAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Djur_och_vaxtskyddsomrade"."URSBESLDAT" IS 'Ursprungligt beslutsdatum';
+
+
+--
+-- Name: COLUMN "Djur_och_vaxtskyddsomrade"."IKRAFTDATF"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Djur_och_vaxtskyddsomrade"."IKRAFTDATF" IS 'Ikraftträdandedatum för föreskrifte';
+
+
+--
+-- Name: COLUMN "Djur_och_vaxtskyddsomrade"."URSGALLDAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Djur_och_vaxtskyddsomrade"."URSGALLDAT" IS 'Ursprungligt gällandedatum';
+
+
+--
+-- Name: COLUMN "Djur_och_vaxtskyddsomrade"."SENGALLDAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Djur_och_vaxtskyddsomrade"."SENGALLDAT" IS 'Senaste gällandedatum';
+
+
+--
+-- Name: COLUMN "Djur_och_vaxtskyddsomrade"."IUCNKAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Djur_och_vaxtskyddsomrade"."IUCNKAT" IS 'Klassificering av skyddade områden enligt internationella naturvårdsunionens';
+
+
+--
+-- Name: COLUMN "Djur_och_vaxtskyddsomrade"."FORVALTARE"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Djur_och_vaxtskyddsomrade"."FORVALTARE" IS 'Förvaltare för området';
+
+
+--
+-- Name: COLUMN "Djur_och_vaxtskyddsomrade"."LAND_HA"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Djur_och_vaxtskyddsomrade"."LAND_HA" IS 'Areal land i hektar (våtmarker ingår i landarealen)';
+
+
+--
+-- Name: COLUMN "Djur_och_vaxtskyddsomrade"."VATTEN_HA"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Djur_och_vaxtskyddsomrade"."VATTEN_HA" IS 'Areal vatten i hektar (både sötvatten och marint vatten ingår)';
+
+
+--
+-- Name: COLUMN "Djur_och_vaxtskyddsomrade"."SKOG_HA"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Djur_och_vaxtskyddsomrade"."SKOG_HA" IS 'Skogsmarksareal i hektar';
+
+
+--
+-- Name: COLUMN "Djur_och_vaxtskyddsomrade"."GEOSTATUS"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Djur_och_vaxtskyddsomrade"."GEOSTATUS" IS 'Hur ytter gränsen för området har mätts in';
+
+
+--
+-- Name: COLUMN "Djur_och_vaxtskyddsomrade"."DIARIENR"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Djur_och_vaxtskyddsomrade"."DIARIENR" IS 'Diarienummer i beslutande myndighets diarium';
+
+
+--
+-- Name: COLUMN "Djur_och_vaxtskyddsomrade"."LAGRUM"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Djur_och_vaxtskyddsomrade"."LAGRUM" IS 'Lagrum som använts som grund för beslutet';
+
+
+--
+-- Name: COLUMN "Djur_och_vaxtskyddsomrade"."BESLMYND"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Djur_och_vaxtskyddsomrade"."BESLMYND" IS 'Beslutsmyndighet';
+
+
+--
+-- Name: Djur_och_vaxtskyddsomrade_ogc_fid_seq; Type: SEQUENCE; Schema: nvr; Owner: geodata
+--
+
+CREATE SEQUENCE nvr."Djur_och_vaxtskyddsomrade_ogc_fid_seq"
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE nvr."Djur_och_vaxtskyddsomrade_ogc_fid_seq" OWNER TO geodata;
+
+--
+-- Name: Djur_och_vaxtskyddsomrade_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: nvr; Owner: geodata
+--
+
+ALTER SEQUENCE nvr."Djur_och_vaxtskyddsomrade_ogc_fid_seq" OWNED BY nvr."Djur_och_vaxtskyddsomrade".ogc_fid;
+
+
+--
+-- Name: HELCOM; Type: TABLE; Schema: nvr; Owner: geodata
+--
+
+CREATE TABLE nvr."HELCOM" (
+ ogc_fid bigint NOT NULL,
+ "BSPA_ID" integer NOT NULL,
+ "NAME" character varying(62) NOT NULL,
+ wkb_geometry public.geometry(MultiPolygonZ,3006) NOT NULL
+);
+
+
+ALTER TABLE nvr."HELCOM" OWNER TO geodata;
+
+--
+-- Name: TABLE "HELCOM"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON TABLE nvr."HELCOM" IS 'Marina skyddade områden (Helcom MPA)';
+
+
+--
+-- Name: HELCOM_ogc_fid_seq; Type: SEQUENCE; Schema: nvr; Owner: geodata
+--
+
+CREATE SEQUENCE nvr."HELCOM_ogc_fid_seq"
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE nvr."HELCOM_ogc_fid_seq" OWNER TO geodata;
+
+--
+-- Name: HELCOM_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: nvr; Owner: geodata
+--
+
+ALTER SEQUENCE nvr."HELCOM_ogc_fid_seq" OWNED BY nvr."HELCOM".ogc_fid;
+
+
+--
+-- Name: Interimistiskt_forbud; Type: TABLE; Schema: nvr; Owner: geodata
+--
+
+CREATE TABLE nvr."Interimistiskt_forbud" (
+ ogc_fid bigint NOT NULL,
+ "NVRID" integer NOT NULL,
+ "NAMN" character varying(62) NOT NULL,
+ "SKYDDSTYP" character varying(32) NOT NULL,
+ "BESLSTATUS" character varying(12) NOT NULL,
+ "URSBESLDAT" date NOT NULL,
+ "IKRAFTDATF" date,
+ "URSGALLDAT" date,
+ "SENGALLDAT" date,
+ "IUCNKAT" character varying(254) NOT NULL,
+ "FORVALTARE" character varying(62),
+ "LAND_HA" double precision,
+ "VATTEN_HA" double precision,
+ "SKOG_HA" double precision,
+ "GEOSTATUS" character varying(62) NOT NULL,
+ "DIARIENR" character varying(62),
+ "LAGRUM" character varying(16) NOT NULL,
+ "BESLMYND" character varying(32) NOT NULL,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE nvr."Interimistiskt_forbud" OWNER TO geodata;
+
+--
+-- Name: TABLE "Interimistiskt_forbud"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON TABLE nvr."Interimistiskt_forbud" IS 'Interimistiska förbud';
+
+
+--
+-- Name: COLUMN "Interimistiskt_forbud"."NVRID"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Interimistiskt_forbud"."NVRID" IS 'Områdets unika ID i naturvårdsregistret';
+
+
+--
+-- Name: COLUMN "Interimistiskt_forbud"."NAMN"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Interimistiskt_forbud"."NAMN" IS 'Områdets namn';
+
+
+--
+-- Name: COLUMN "Interimistiskt_forbud"."SKYDDSTYP"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Interimistiskt_forbud"."SKYDDSTYP" IS 'Skyddstyp';
+
+
+--
+-- Name: COLUMN "Interimistiskt_forbud"."BESLSTATUS"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Interimistiskt_forbud"."BESLSTATUS" IS 'Beslutsstatus';
+
+
+--
+-- Name: COLUMN "Interimistiskt_forbud"."URSBESLDAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Interimistiskt_forbud"."URSBESLDAT" IS 'Ursprungligt beslutsdatum';
+
+
+--
+-- Name: COLUMN "Interimistiskt_forbud"."IKRAFTDATF"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Interimistiskt_forbud"."IKRAFTDATF" IS 'Ikraftträdandedatum för föreskrifte';
+
+
+--
+-- Name: COLUMN "Interimistiskt_forbud"."URSGALLDAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Interimistiskt_forbud"."URSGALLDAT" IS 'Ursprungligt gällandedatum';
+
+
+--
+-- Name: COLUMN "Interimistiskt_forbud"."SENGALLDAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Interimistiskt_forbud"."SENGALLDAT" IS 'Senaste gällandedatum';
+
+
+--
+-- Name: COLUMN "Interimistiskt_forbud"."IUCNKAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Interimistiskt_forbud"."IUCNKAT" IS 'Klassificering av skyddade områden enligt internationella naturvårdsunionens';
+
+
+--
+-- Name: COLUMN "Interimistiskt_forbud"."FORVALTARE"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Interimistiskt_forbud"."FORVALTARE" IS 'Förvaltare för området';
+
+
+--
+-- Name: COLUMN "Interimistiskt_forbud"."LAND_HA"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Interimistiskt_forbud"."LAND_HA" IS 'Areal land i hektar (våtmarker ingår i landarealen)';
+
+
+--
+-- Name: COLUMN "Interimistiskt_forbud"."VATTEN_HA"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Interimistiskt_forbud"."VATTEN_HA" IS 'Areal vatten i hektar (både sötvatten och marint vatten ingår)';
+
+
+--
+-- Name: COLUMN "Interimistiskt_forbud"."SKOG_HA"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Interimistiskt_forbud"."SKOG_HA" IS 'Skogsmarksareal i hektar';
+
+
+--
+-- Name: COLUMN "Interimistiskt_forbud"."GEOSTATUS"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Interimistiskt_forbud"."GEOSTATUS" IS 'Hur ytter gränsen för området har mätts in';
+
+
+--
+-- Name: COLUMN "Interimistiskt_forbud"."DIARIENR"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Interimistiskt_forbud"."DIARIENR" IS 'Diarienummer i beslutande myndighets diarium';
+
+
+--
+-- Name: COLUMN "Interimistiskt_forbud"."LAGRUM"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Interimistiskt_forbud"."LAGRUM" IS 'Lagrum som använts som grund för beslutet';
+
+
+--
+-- Name: COLUMN "Interimistiskt_forbud"."BESLMYND"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Interimistiskt_forbud"."BESLMYND" IS 'Beslutsmyndighet';
+
+
+--
+-- Name: Interimistiskt_forbud_ogc_fid_seq; Type: SEQUENCE; Schema: nvr; Owner: geodata
+--
+
+CREATE SEQUENCE nvr."Interimistiskt_forbud_ogc_fid_seq"
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE nvr."Interimistiskt_forbud_ogc_fid_seq" OWNER TO geodata;
+
+--
+-- Name: Interimistiskt_forbud_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: nvr; Owner: geodata
+--
+
+ALTER SEQUENCE nvr."Interimistiskt_forbud_ogc_fid_seq" OWNED BY nvr."Interimistiskt_forbud".ogc_fid;
+
+
+--
+-- Name: Kultureservat; Type: TABLE; Schema: nvr; Owner: geodata
+--
+
+CREATE TABLE nvr."Kultureservat" (
+ ogc_fid bigint NOT NULL,
+ "NVRID" integer NOT NULL,
+ "NAMN" character varying(62) NOT NULL,
+ "SKYDDSTYP" character varying(32) NOT NULL,
+ "BESLSTATUS" character varying(12) NOT NULL,
+ "URSBESLDAT" date NOT NULL,
+ "IKRAFTDATF" date,
+ "URSGALLDAT" date,
+ "SENGALLDAT" date,
+ "IUCNKAT" character varying(254) NOT NULL,
+ "FORVALTARE" character varying(62) NOT NULL,
+ "LAND_HA" double precision,
+ "VATTEN_HA" double precision,
+ "SKOG_HA" double precision,
+ "GEOSTATUS" character varying(62) NOT NULL,
+ "DIARIENR" character varying(62),
+ "LAGRUM" character varying(16) NOT NULL,
+ "BESLMYND" character varying(32) NOT NULL,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE nvr."Kultureservat" OWNER TO geodata;
+
+--
+-- Name: TABLE "Kultureservat"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON TABLE nvr."Kultureservat" IS 'Kulturreservat';
+
+
+--
+-- Name: COLUMN "Kultureservat"."NVRID"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Kultureservat"."NVRID" IS 'Områdets unika ID i naturvårdsregistret';
+
+
+--
+-- Name: COLUMN "Kultureservat"."NAMN"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Kultureservat"."NAMN" IS 'Områdets namn';
+
+
+--
+-- Name: COLUMN "Kultureservat"."SKYDDSTYP"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Kultureservat"."SKYDDSTYP" IS 'Skyddstyp';
+
+
+--
+-- Name: COLUMN "Kultureservat"."BESLSTATUS"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Kultureservat"."BESLSTATUS" IS 'Beslutsstatus';
+
+
+--
+-- Name: COLUMN "Kultureservat"."URSBESLDAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Kultureservat"."URSBESLDAT" IS 'Ursprungligt beslutsdatum';
+
+
+--
+-- Name: COLUMN "Kultureservat"."IKRAFTDATF"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Kultureservat"."IKRAFTDATF" IS 'Ikraftträdandedatum för föreskrifte';
+
+
+--
+-- Name: COLUMN "Kultureservat"."URSGALLDAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Kultureservat"."URSGALLDAT" IS 'Ursprungligt gällandedatum';
+
+
+--
+-- Name: COLUMN "Kultureservat"."SENGALLDAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Kultureservat"."SENGALLDAT" IS 'Senaste gällandedatum';
+
+
+--
+-- Name: COLUMN "Kultureservat"."IUCNKAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Kultureservat"."IUCNKAT" IS 'Klassificering av skyddade områden enligt internationella naturvårdsunionens';
+
+
+--
+-- Name: COLUMN "Kultureservat"."FORVALTARE"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Kultureservat"."FORVALTARE" IS 'Förvaltare för området';
+
+
+--
+-- Name: COLUMN "Kultureservat"."LAND_HA"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Kultureservat"."LAND_HA" IS 'Areal land i hektar (våtmarker ingår i landarealen)';
+
+
+--
+-- Name: COLUMN "Kultureservat"."VATTEN_HA"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Kultureservat"."VATTEN_HA" IS 'Areal vatten i hektar (både sötvatten och marint vatten ingår)';
+
+
+--
+-- Name: COLUMN "Kultureservat"."SKOG_HA"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Kultureservat"."SKOG_HA" IS 'Skogsmarksareal i hektar';
+
+
+--
+-- Name: COLUMN "Kultureservat"."GEOSTATUS"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Kultureservat"."GEOSTATUS" IS 'Hur ytter gränsen för området har mätts in';
+
+
+--
+-- Name: COLUMN "Kultureservat"."DIARIENR"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Kultureservat"."DIARIENR" IS 'Diarienummer i beslutande myndighets diarium';
+
+
+--
+-- Name: COLUMN "Kultureservat"."LAGRUM"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Kultureservat"."LAGRUM" IS 'Lagrum som använts som grund för beslutet';
+
+
+--
+-- Name: COLUMN "Kultureservat"."BESLMYND"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Kultureservat"."BESLMYND" IS 'Beslutsmyndighet';
+
+
+--
+-- Name: Kultureservat_ogc_fid_seq; Type: SEQUENCE; Schema: nvr; Owner: geodata
+--
+
+CREATE SEQUENCE nvr."Kultureservat_ogc_fid_seq"
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE nvr."Kultureservat_ogc_fid_seq" OWNER TO geodata;
+
+--
+-- Name: Kultureservat_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: nvr; Owner: geodata
+--
+
+ALTER SEQUENCE nvr."Kultureservat_ogc_fid_seq" OWNED BY nvr."Kultureservat".ogc_fid;
+
+
+--
+-- Name: Landskapsbildsskyddsomrade; Type: TABLE; Schema: nvr; Owner: geodata
+--
+
+CREATE TABLE nvr."Landskapsbildsskyddsomrade" (
+ ogc_fid bigint NOT NULL,
+ "NVRID" integer NOT NULL,
+ "NAMN" character varying(62) NOT NULL,
+ "SKYDDSTYP" character varying(32) NOT NULL,
+ "BESLSTATUS" character varying(12) NOT NULL,
+ "URSBESLDAT" date NOT NULL,
+ "IKRAFTDATF" date,
+ "URSGALLDAT" date,
+ "SENGALLDAT" date,
+ "IUCNKAT" character varying(254) NOT NULL,
+ "FORVALTARE" character varying(62) NOT NULL,
+ "LAND_HA" double precision,
+ "VATTEN_HA" double precision,
+ "SKOG_HA" double precision,
+ "GEOSTATUS" character varying(62) NOT NULL,
+ "DIARIENR" character varying(62),
+ "LAGRUM" character varying(16),
+ "BESLMYND" character varying(32) NOT NULL,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE nvr."Landskapsbildsskyddsomrade" OWNER TO geodata;
+
+--
+-- Name: TABLE "Landskapsbildsskyddsomrade"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON TABLE nvr."Landskapsbildsskyddsomrade" IS 'Landskapsbildsskyddsområden';
+
+
+--
+-- Name: COLUMN "Landskapsbildsskyddsomrade"."NVRID"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Landskapsbildsskyddsomrade"."NVRID" IS 'Områdets unika ID i naturvårdsregistret';
+
+
+--
+-- Name: COLUMN "Landskapsbildsskyddsomrade"."NAMN"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Landskapsbildsskyddsomrade"."NAMN" IS 'Områdets namn';
+
+
+--
+-- Name: COLUMN "Landskapsbildsskyddsomrade"."SKYDDSTYP"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Landskapsbildsskyddsomrade"."SKYDDSTYP" IS 'Skyddstyp';
+
+
+--
+-- Name: COLUMN "Landskapsbildsskyddsomrade"."BESLSTATUS"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Landskapsbildsskyddsomrade"."BESLSTATUS" IS 'Beslutsstatus';
+
+
+--
+-- Name: COLUMN "Landskapsbildsskyddsomrade"."URSBESLDAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Landskapsbildsskyddsomrade"."URSBESLDAT" IS 'Ursprungligt beslutsdatum';
+
+
+--
+-- Name: COLUMN "Landskapsbildsskyddsomrade"."IKRAFTDATF"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Landskapsbildsskyddsomrade"."IKRAFTDATF" IS 'Ikraftträdandedatum för föreskrifte';
+
+
+--
+-- Name: COLUMN "Landskapsbildsskyddsomrade"."URSGALLDAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Landskapsbildsskyddsomrade"."URSGALLDAT" IS 'Ursprungligt gällandedatum';
+
+
+--
+-- Name: COLUMN "Landskapsbildsskyddsomrade"."SENGALLDAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Landskapsbildsskyddsomrade"."SENGALLDAT" IS 'Senaste gällandedatum';
+
+
+--
+-- Name: COLUMN "Landskapsbildsskyddsomrade"."IUCNKAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Landskapsbildsskyddsomrade"."IUCNKAT" IS 'Klassificering av skyddade områden enligt internationella naturvårdsunionens';
+
+
+--
+-- Name: COLUMN "Landskapsbildsskyddsomrade"."FORVALTARE"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Landskapsbildsskyddsomrade"."FORVALTARE" IS 'Förvaltare för området';
+
+
+--
+-- Name: COLUMN "Landskapsbildsskyddsomrade"."LAND_HA"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Landskapsbildsskyddsomrade"."LAND_HA" IS 'Areal land i hektar (våtmarker ingår i landarealen)';
+
+
+--
+-- Name: COLUMN "Landskapsbildsskyddsomrade"."VATTEN_HA"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Landskapsbildsskyddsomrade"."VATTEN_HA" IS 'Areal vatten i hektar (både sötvatten och marint vatten ingår)';
+
+
+--
+-- Name: COLUMN "Landskapsbildsskyddsomrade"."SKOG_HA"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Landskapsbildsskyddsomrade"."SKOG_HA" IS 'Skogsmarksareal i hektar';
+
+
+--
+-- Name: COLUMN "Landskapsbildsskyddsomrade"."GEOSTATUS"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Landskapsbildsskyddsomrade"."GEOSTATUS" IS 'Hur ytter gränsen för området har mätts in';
+
+
+--
+-- Name: COLUMN "Landskapsbildsskyddsomrade"."DIARIENR"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Landskapsbildsskyddsomrade"."DIARIENR" IS 'Diarienummer i beslutande myndighets diarium';
+
+
+--
+-- Name: COLUMN "Landskapsbildsskyddsomrade"."LAGRUM"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Landskapsbildsskyddsomrade"."LAGRUM" IS 'Lagrum som använts som grund för beslutet';
+
+
+--
+-- Name: COLUMN "Landskapsbildsskyddsomrade"."BESLMYND"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Landskapsbildsskyddsomrade"."BESLMYND" IS 'Beslutsmyndighet';
+
+
+--
+-- Name: Landskapsbildsskyddsomrade_ogc_fid_seq; Type: SEQUENCE; Schema: nvr; Owner: geodata
+--
+
+CREATE SEQUENCE nvr."Landskapsbildsskyddsomrade_ogc_fid_seq"
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE nvr."Landskapsbildsskyddsomrade_ogc_fid_seq" OWNER TO geodata;
+
+--
+-- Name: Landskapsbildsskyddsomrade_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: nvr; Owner: geodata
+--
+
+ALTER SEQUENCE nvr."Landskapsbildsskyddsomrade_ogc_fid_seq" OWNED BY nvr."Landskapsbildsskyddsomrade".ogc_fid;
+
+
+--
+-- Name: Nationalpark; Type: TABLE; Schema: nvr; Owner: geodata
+--
+
+CREATE TABLE nvr."Nationalpark" (
+ ogc_fid bigint NOT NULL,
+ "NVRID" integer NOT NULL,
+ "NAMN" character varying(62) NOT NULL,
+ "SKYDDSTYP" character varying(32) NOT NULL,
+ "BESLSTATUS" character varying(12) NOT NULL,
+ "URSBESLDAT" date NOT NULL,
+ "IKRAFTDATF" date,
+ "URSGALLDAT" date,
+ "SENGALLDAT" date,
+ "IUCNKAT" character varying(254) NOT NULL,
+ "FORVALTARE" character varying(62) NOT NULL,
+ "LAND_HA" double precision,
+ "VATTEN_HA" double precision,
+ "SKOG_HA" double precision,
+ "GEOSTATUS" character varying(62) NOT NULL,
+ "DIARIENR" character varying(62),
+ "LAGRUM" character varying(16) NOT NULL,
+ "BESLMYND" character varying(32) NOT NULL,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE nvr."Nationalpark" OWNER TO geodata;
+
+--
+-- Name: TABLE "Nationalpark"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON TABLE nvr."Nationalpark" IS 'Nationalparker';
+
+
+--
+-- Name: COLUMN "Nationalpark"."NVRID"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Nationalpark"."NVRID" IS 'Områdets unika ID i naturvårdsregistret';
+
+
+--
+-- Name: COLUMN "Nationalpark"."NAMN"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Nationalpark"."NAMN" IS 'Områdets namn';
+
+
+--
+-- Name: COLUMN "Nationalpark"."SKYDDSTYP"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Nationalpark"."SKYDDSTYP" IS 'Skyddstyp';
+
+
+--
+-- Name: COLUMN "Nationalpark"."BESLSTATUS"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Nationalpark"."BESLSTATUS" IS 'Beslutsstatus';
+
+
+--
+-- Name: COLUMN "Nationalpark"."URSBESLDAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Nationalpark"."URSBESLDAT" IS 'Ursprungligt beslutsdatum';
+
+
+--
+-- Name: COLUMN "Nationalpark"."IKRAFTDATF"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Nationalpark"."IKRAFTDATF" IS 'Ikraftträdandedatum för föreskrifte';
+
+
+--
+-- Name: COLUMN "Nationalpark"."URSGALLDAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Nationalpark"."URSGALLDAT" IS 'Ursprungligt gällandedatum';
+
+
+--
+-- Name: COLUMN "Nationalpark"."SENGALLDAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Nationalpark"."SENGALLDAT" IS 'Senaste gällandedatum';
+
+
+--
+-- Name: COLUMN "Nationalpark"."IUCNKAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Nationalpark"."IUCNKAT" IS 'Klassificering av skyddade områden enligt internationella naturvårdsunionens';
+
+
+--
+-- Name: COLUMN "Nationalpark"."FORVALTARE"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Nationalpark"."FORVALTARE" IS 'Förvaltare för området';
+
+
+--
+-- Name: COLUMN "Nationalpark"."LAND_HA"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Nationalpark"."LAND_HA" IS 'Areal land i hektar (våtmarker ingår i landarealen)';
+
+
+--
+-- Name: COLUMN "Nationalpark"."VATTEN_HA"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Nationalpark"."VATTEN_HA" IS 'Areal vatten i hektar (både sötvatten och marint vatten ingår)';
+
+
+--
+-- Name: COLUMN "Nationalpark"."SKOG_HA"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Nationalpark"."SKOG_HA" IS 'Skogsmarksareal i hektar';
+
+
+--
+-- Name: COLUMN "Nationalpark"."GEOSTATUS"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Nationalpark"."GEOSTATUS" IS 'Hur ytter gränsen för området har mätts in';
+
+
+--
+-- Name: COLUMN "Nationalpark"."DIARIENR"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Nationalpark"."DIARIENR" IS 'Diarienummer i beslutande myndighets diarium';
+
+
+--
+-- Name: COLUMN "Nationalpark"."LAGRUM"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Nationalpark"."LAGRUM" IS 'Lagrum som använts som grund för beslutet';
+
+
+--
+-- Name: COLUMN "Nationalpark"."BESLMYND"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Nationalpark"."BESLMYND" IS 'Beslutsmyndighet';
+
+
+--
+-- Name: Nationalpark_ogc_fid_seq; Type: SEQUENCE; Schema: nvr; Owner: geodata
+--
+
+CREATE SEQUENCE nvr."Nationalpark_ogc_fid_seq"
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE nvr."Nationalpark_ogc_fid_seq" OWNER TO geodata;
+
+--
+-- Name: Nationalpark_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: nvr; Owner: geodata
+--
+
+ALTER SEQUENCE nvr."Nationalpark_ogc_fid_seq" OWNED BY nvr."Nationalpark".ogc_fid;
+
+
+--
+-- Name: Naturminne_punkt; Type: TABLE; Schema: nvr; Owner: geodata
+--
+
+CREATE TABLE nvr."Naturminne_punkt" (
+ ogc_fid bigint NOT NULL,
+ "NVRID" integer NOT NULL,
+ "NAMN" character varying(62) NOT NULL,
+ "SKYDDSTYP" character varying(32) NOT NULL,
+ "BESLSTATUS" character varying(12) NOT NULL,
+ "URSBESLDAT" date NOT NULL,
+ "IKRAFTDATF" date,
+ "URSGALLDAT" date,
+ "SENGALLDAT" date,
+ "IUCNKAT" character varying(254) NOT NULL,
+ "FORVALTARE" character varying(62) NOT NULL,
+ "GEOSTATUS" character varying(62) NOT NULL,
+ "DIARIENR" character varying(62),
+ "LAGRUM" character varying(64) NOT NULL,
+ "BESLMYND" character varying(32) NOT NULL,
+ wkb_geometry public.geometry(MultiPoint,3006) NOT NULL
+);
+
+
+ALTER TABLE nvr."Naturminne_punkt" OWNER TO geodata;
+
+--
+-- Name: TABLE "Naturminne_punkt"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON TABLE nvr."Naturminne_punkt" IS 'Naturminne, punkt';
+
+
+--
+-- Name: COLUMN "Naturminne_punkt"."NVRID"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturminne_punkt"."NVRID" IS 'Områdets unika ID i naturvårdsregistret';
+
+
+--
+-- Name: COLUMN "Naturminne_punkt"."NAMN"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturminne_punkt"."NAMN" IS 'Områdets namn';
+
+
+--
+-- Name: COLUMN "Naturminne_punkt"."SKYDDSTYP"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturminne_punkt"."SKYDDSTYP" IS 'Skyddstyp';
+
+
+--
+-- Name: COLUMN "Naturminne_punkt"."BESLSTATUS"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturminne_punkt"."BESLSTATUS" IS 'Beslutsstatus';
+
+
+--
+-- Name: COLUMN "Naturminne_punkt"."URSBESLDAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturminne_punkt"."URSBESLDAT" IS 'Ursprungligt beslutsdatum';
+
+
+--
+-- Name: COLUMN "Naturminne_punkt"."IKRAFTDATF"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturminne_punkt"."IKRAFTDATF" IS 'Ikraftträdandedatum för föreskrifte';
+
+
+--
+-- Name: COLUMN "Naturminne_punkt"."URSGALLDAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturminne_punkt"."URSGALLDAT" IS 'Ursprungligt gällandedatum';
+
+
+--
+-- Name: COLUMN "Naturminne_punkt"."SENGALLDAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturminne_punkt"."SENGALLDAT" IS 'Senaste gällandedatum';
+
+
+--
+-- Name: COLUMN "Naturminne_punkt"."IUCNKAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturminne_punkt"."IUCNKAT" IS 'Klassificering av skyddade områden enligt internationella naturvårdsunionens';
+
+
+--
+-- Name: COLUMN "Naturminne_punkt"."FORVALTARE"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturminne_punkt"."FORVALTARE" IS 'Förvaltare för området';
+
+
+--
+-- Name: COLUMN "Naturminne_punkt"."GEOSTATUS"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturminne_punkt"."GEOSTATUS" IS 'Hur ytter gränsen för området har mätts in';
+
+
+--
+-- Name: COLUMN "Naturminne_punkt"."DIARIENR"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturminne_punkt"."DIARIENR" IS 'Diarienummer i beslutande myndighets diarium';
+
+
+--
+-- Name: COLUMN "Naturminne_punkt"."LAGRUM"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturminne_punkt"."LAGRUM" IS 'Lagrum som använts som grund för beslutet';
+
+
+--
+-- Name: COLUMN "Naturminne_punkt"."BESLMYND"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturminne_punkt"."BESLMYND" IS 'Beslutsmyndighet';
+
+
+--
+-- Name: Naturminne_punkt_ogc_fid_seq; Type: SEQUENCE; Schema: nvr; Owner: geodata
+--
+
+CREATE SEQUENCE nvr."Naturminne_punkt_ogc_fid_seq"
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE nvr."Naturminne_punkt_ogc_fid_seq" OWNER TO geodata;
+
+--
+-- Name: Naturminne_punkt_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: nvr; Owner: geodata
+--
+
+ALTER SEQUENCE nvr."Naturminne_punkt_ogc_fid_seq" OWNED BY nvr."Naturminne_punkt".ogc_fid;
+
+
+--
+-- Name: Naturminne_yta; Type: TABLE; Schema: nvr; Owner: geodata
+--
+
+CREATE TABLE nvr."Naturminne_yta" (
+ ogc_fid bigint NOT NULL,
+ "NVRID" integer NOT NULL,
+ "NAMN" character varying(62) NOT NULL,
+ "SKYDDSTYP" character varying(32) NOT NULL,
+ "BESLSTATUS" character varying(12) NOT NULL,
+ "URSBESLDAT" date NOT NULL,
+ "IKRAFTDATF" date,
+ "URSGALLDAT" date,
+ "SENGALLDAT" date,
+ "IUCNKAT" character varying(254) NOT NULL,
+ "FORVALTARE" character varying(62) NOT NULL,
+ "LAND_HA" double precision,
+ "VATTEN_HA" double precision,
+ "SKOG_HA" double precision,
+ "GEOSTATUS" character varying(62) NOT NULL,
+ "DIARIENR" character varying(62),
+ "LAGRUM" character varying(64) NOT NULL,
+ "BESLMYND" character varying(32) NOT NULL,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE nvr."Naturminne_yta" OWNER TO geodata;
+
+--
+-- Name: TABLE "Naturminne_yta"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON TABLE nvr."Naturminne_yta" IS 'Naturminne, yta';
+
+
+--
+-- Name: COLUMN "Naturminne_yta"."NVRID"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturminne_yta"."NVRID" IS 'Områdets unika ID i naturvårdsregistret';
+
+
+--
+-- Name: COLUMN "Naturminne_yta"."NAMN"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturminne_yta"."NAMN" IS 'Områdets namn';
+
+
+--
+-- Name: COLUMN "Naturminne_yta"."SKYDDSTYP"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturminne_yta"."SKYDDSTYP" IS 'Skyddstyp';
+
+
+--
+-- Name: COLUMN "Naturminne_yta"."BESLSTATUS"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturminne_yta"."BESLSTATUS" IS 'Beslutsstatus';
+
+
+--
+-- Name: COLUMN "Naturminne_yta"."URSBESLDAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturminne_yta"."URSBESLDAT" IS 'Ursprungligt beslutsdatum';
+
+
+--
+-- Name: COLUMN "Naturminne_yta"."IKRAFTDATF"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturminne_yta"."IKRAFTDATF" IS 'Ikraftträdandedatum för föreskrifte';
+
+
+--
+-- Name: COLUMN "Naturminne_yta"."URSGALLDAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturminne_yta"."URSGALLDAT" IS 'Ursprungligt gällandedatum';
+
+
+--
+-- Name: COLUMN "Naturminne_yta"."SENGALLDAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturminne_yta"."SENGALLDAT" IS 'Senaste gällandedatum';
+
+
+--
+-- Name: COLUMN "Naturminne_yta"."IUCNKAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturminne_yta"."IUCNKAT" IS 'Klassificering av skyddade områden enligt internationella naturvårdsunionens';
+
+
+--
+-- Name: COLUMN "Naturminne_yta"."FORVALTARE"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturminne_yta"."FORVALTARE" IS 'Förvaltare för området';
+
+
+--
+-- Name: COLUMN "Naturminne_yta"."LAND_HA"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturminne_yta"."LAND_HA" IS 'Areal land i hektar (våtmarker ingår i landarealen)';
+
+
+--
+-- Name: COLUMN "Naturminne_yta"."VATTEN_HA"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturminne_yta"."VATTEN_HA" IS 'Areal vatten i hektar (både sötvatten och marint vatten ingår)';
+
+
+--
+-- Name: COLUMN "Naturminne_yta"."SKOG_HA"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturminne_yta"."SKOG_HA" IS 'Skogsmarksareal i hektar';
+
+
+--
+-- Name: COLUMN "Naturminne_yta"."GEOSTATUS"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturminne_yta"."GEOSTATUS" IS 'Hur ytter gränsen för området har mätts in';
+
+
+--
+-- Name: COLUMN "Naturminne_yta"."DIARIENR"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturminne_yta"."DIARIENR" IS 'Diarienummer i beslutande myndighets diarium';
+
+
+--
+-- Name: COLUMN "Naturminne_yta"."LAGRUM"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturminne_yta"."LAGRUM" IS 'Lagrum som använts som grund för beslutet';
+
+
+--
+-- Name: COLUMN "Naturminne_yta"."BESLMYND"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturminne_yta"."BESLMYND" IS 'Beslutsmyndighet';
+
+
+--
+-- Name: Naturminne_yta_ogc_fid_seq; Type: SEQUENCE; Schema: nvr; Owner: geodata
+--
+
+CREATE SEQUENCE nvr."Naturminne_yta_ogc_fid_seq"
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE nvr."Naturminne_yta_ogc_fid_seq" OWNER TO geodata;
+
+--
+-- Name: Naturminne_yta_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: nvr; Owner: geodata
+--
+
+ALTER SEQUENCE nvr."Naturminne_yta_ogc_fid_seq" OWNED BY nvr."Naturminne_yta".ogc_fid;
+
+
+--
+-- Name: Naturreservat; Type: TABLE; Schema: nvr; Owner: geodata
+--
+
+CREATE TABLE nvr."Naturreservat" (
+ ogc_fid bigint NOT NULL,
+ "NVRID" integer NOT NULL,
+ "NAMN" character varying(128) NOT NULL,
+ "SKYDDSTYP" character varying(32) NOT NULL,
+ "BESLSTATUS" character varying(12) NOT NULL,
+ "URSBESLDAT" date,
+ "IKRAFTDATF" date,
+ "URSGALLDAT" date,
+ "SENGALLDAT" date,
+ "IUCNKAT" character varying(254) NOT NULL,
+ "FORVALTARE" character varying(62),
+ "LAND_HA" double precision,
+ "VATTEN_HA" double precision,
+ "SKOG_HA" double precision,
+ "GEOSTATUS" character varying(62) NOT NULL,
+ "DIARIENR" character varying(62),
+ "LAGRUM" character varying(16),
+ "BESLMYND" character varying(32) NOT NULL,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE nvr."Naturreservat" OWNER TO geodata;
+
+--
+-- Name: TABLE "Naturreservat"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON TABLE nvr."Naturreservat" IS 'Naturreservat';
+
+
+--
+-- Name: COLUMN "Naturreservat"."NVRID"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturreservat"."NVRID" IS 'Områdets unika ID i naturvårdsregistret';
+
+
+--
+-- Name: COLUMN "Naturreservat"."NAMN"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturreservat"."NAMN" IS 'Områdets namn';
+
+
+--
+-- Name: COLUMN "Naturreservat"."SKYDDSTYP"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturreservat"."SKYDDSTYP" IS 'Skyddstyp';
+
+
+--
+-- Name: COLUMN "Naturreservat"."BESLSTATUS"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturreservat"."BESLSTATUS" IS 'Beslutsstatus';
+
+
+--
+-- Name: COLUMN "Naturreservat"."URSBESLDAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturreservat"."URSBESLDAT" IS 'Ursprungligt beslutsdatum';
+
+
+--
+-- Name: COLUMN "Naturreservat"."IKRAFTDATF"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturreservat"."IKRAFTDATF" IS 'Ikraftträdandedatum för föreskrifte';
+
+
+--
+-- Name: COLUMN "Naturreservat"."URSGALLDAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturreservat"."URSGALLDAT" IS 'Ursprungligt gällandedatum';
+
+
+--
+-- Name: COLUMN "Naturreservat"."SENGALLDAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturreservat"."SENGALLDAT" IS 'Senaste gällandedatum';
+
+
+--
+-- Name: COLUMN "Naturreservat"."IUCNKAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturreservat"."IUCNKAT" IS 'Klassificering av skyddade områden enligt internationella naturvårdsunionens';
+
+
+--
+-- Name: COLUMN "Naturreservat"."FORVALTARE"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturreservat"."FORVALTARE" IS 'Förvaltare för området';
+
+
+--
+-- Name: COLUMN "Naturreservat"."LAND_HA"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturreservat"."LAND_HA" IS 'Areal land i hektar (våtmarker ingår i landarealen)';
+
+
+--
+-- Name: COLUMN "Naturreservat"."VATTEN_HA"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturreservat"."VATTEN_HA" IS 'Areal vatten i hektar (både sötvatten och marint vatten ingår)';
+
+
+--
+-- Name: COLUMN "Naturreservat"."SKOG_HA"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturreservat"."SKOG_HA" IS 'Skogsmarksareal i hektar';
+
+
+--
+-- Name: COLUMN "Naturreservat"."GEOSTATUS"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturreservat"."GEOSTATUS" IS 'Hur ytter gränsen för området har mätts in';
+
+
+--
+-- Name: COLUMN "Naturreservat"."DIARIENR"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturreservat"."DIARIENR" IS 'Diarienummer i beslutande myndighets diarium';
+
+
+--
+-- Name: COLUMN "Naturreservat"."LAGRUM"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturreservat"."LAGRUM" IS 'Lagrum som använts som grund för beslutet';
+
+
+--
+-- Name: COLUMN "Naturreservat"."BESLMYND"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturreservat"."BESLMYND" IS 'Beslutsmyndighet';
+
+
+--
+-- Name: Naturreservat_ogc_fid_seq; Type: SEQUENCE; Schema: nvr; Owner: geodata
+--
+
+CREATE SEQUENCE nvr."Naturreservat_ogc_fid_seq"
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE nvr."Naturreservat_ogc_fid_seq" OWNER TO geodata;
+
+--
+-- Name: Naturreservat_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: nvr; Owner: geodata
+--
+
+ALTER SEQUENCE nvr."Naturreservat_ogc_fid_seq" OWNED BY nvr."Naturreservat".ogc_fid;
+
+
+--
+-- Name: Naturvardsomrade; Type: TABLE; Schema: nvr; Owner: geodata
+--
+
+CREATE TABLE nvr."Naturvardsomrade" (
+ ogc_fid bigint NOT NULL,
+ "NVRID" integer NOT NULL,
+ "NAMN" character varying(64) NOT NULL,
+ "SKYDDSTYP" character varying(32) NOT NULL,
+ "BESLSTATUS" character varying(12) NOT NULL,
+ "URSBESLDAT" date NOT NULL,
+ "IKRAFTDATF" date,
+ "URSGALLDAT" date,
+ "SENGALLDAT" date,
+ "IUCNKAT" character varying(254) NOT NULL,
+ "FORVALTARE" character varying(62) NOT NULL,
+ "LAND_HA" double precision,
+ "VATTEN_HA" double precision,
+ "SKOG_HA" double precision,
+ "GEOSTATUS" character varying(62) NOT NULL,
+ "DIARIENR" character varying(62),
+ "LAGRUM" character varying(16) NOT NULL,
+ "BESLMYND" character varying(32) NOT NULL,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE nvr."Naturvardsomrade" OWNER TO geodata;
+
+--
+-- Name: TABLE "Naturvardsomrade"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON TABLE nvr."Naturvardsomrade" IS 'Naturvårdsområden';
+
+
+--
+-- Name: COLUMN "Naturvardsomrade"."NVRID"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturvardsomrade"."NVRID" IS 'Områdets unika ID i naturvårdsregistret';
+
+
+--
+-- Name: COLUMN "Naturvardsomrade"."NAMN"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturvardsomrade"."NAMN" IS 'Områdets namn';
+
+
+--
+-- Name: COLUMN "Naturvardsomrade"."SKYDDSTYP"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturvardsomrade"."SKYDDSTYP" IS 'Skyddstyp';
+
+
+--
+-- Name: COLUMN "Naturvardsomrade"."BESLSTATUS"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturvardsomrade"."BESLSTATUS" IS 'Beslutsstatus';
+
+
+--
+-- Name: COLUMN "Naturvardsomrade"."URSBESLDAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturvardsomrade"."URSBESLDAT" IS 'Ursprungligt beslutsdatum';
+
+
+--
+-- Name: COLUMN "Naturvardsomrade"."IKRAFTDATF"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturvardsomrade"."IKRAFTDATF" IS 'Ikraftträdandedatum för föreskrifte';
+
+
+--
+-- Name: COLUMN "Naturvardsomrade"."URSGALLDAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturvardsomrade"."URSGALLDAT" IS 'Ursprungligt gällandedatum';
+
+
+--
+-- Name: COLUMN "Naturvardsomrade"."SENGALLDAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturvardsomrade"."SENGALLDAT" IS 'Senaste gällandedatum';
+
+
+--
+-- Name: COLUMN "Naturvardsomrade"."IUCNKAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturvardsomrade"."IUCNKAT" IS 'Klassificering av skyddade områden enligt internationella naturvårdsunionens';
+
+
+--
+-- Name: COLUMN "Naturvardsomrade"."FORVALTARE"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturvardsomrade"."FORVALTARE" IS 'Förvaltare för området';
+
+
+--
+-- Name: COLUMN "Naturvardsomrade"."LAND_HA"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturvardsomrade"."LAND_HA" IS 'Areal land i hektar (våtmarker ingår i landarealen)';
+
+
+--
+-- Name: COLUMN "Naturvardsomrade"."VATTEN_HA"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturvardsomrade"."VATTEN_HA" IS 'Areal vatten i hektar (både sötvatten och marint vatten ingår)';
+
+
+--
+-- Name: COLUMN "Naturvardsomrade"."SKOG_HA"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturvardsomrade"."SKOG_HA" IS 'Skogsmarksareal i hektar';
+
+
+--
+-- Name: COLUMN "Naturvardsomrade"."GEOSTATUS"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturvardsomrade"."GEOSTATUS" IS 'Hur ytter gränsen för området har mätts in';
+
+
+--
+-- Name: COLUMN "Naturvardsomrade"."DIARIENR"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturvardsomrade"."DIARIENR" IS 'Diarienummer i beslutande myndighets diarium';
+
+
+--
+-- Name: COLUMN "Naturvardsomrade"."LAGRUM"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturvardsomrade"."LAGRUM" IS 'Lagrum som använts som grund för beslutet';
+
+
+--
+-- Name: COLUMN "Naturvardsomrade"."BESLMYND"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Naturvardsomrade"."BESLMYND" IS 'Beslutsmyndighet';
+
+
+--
+-- Name: Naturvardsomrade_ogc_fid_seq; Type: SEQUENCE; Schema: nvr; Owner: geodata
+--
+
+CREATE SEQUENCE nvr."Naturvardsomrade_ogc_fid_seq"
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE nvr."Naturvardsomrade_ogc_fid_seq" OWNER TO geodata;
+
+--
+-- Name: Naturvardsomrade_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: nvr; Owner: geodata
+--
+
+ALTER SEQUENCE nvr."Naturvardsomrade_ogc_fid_seq" OWNED BY nvr."Naturvardsomrade".ogc_fid;
+
+
+--
+-- Name: OSPAR; Type: TABLE; Schema: nvr; Owner: geodata
+--
+
+CREATE TABLE nvr."OSPAR" (
+ ogc_fid bigint NOT NULL,
+ "ORIGIN" character varying(10) NOT NULL,
+ "NAMN_N2000" character varying(64) NOT NULL,
+ "MPA_ID" character varying(16) NOT NULL,
+ "MPA_NAMN" character varying(64) NOT NULL,
+ "N2000_SITE" character varying(16) NOT NULL,
+ wkb_geometry public.geometry(MultiPolygonZ,3006) NOT NULL
+);
+
+
+ALTER TABLE nvr."OSPAR" OWNER TO geodata;
+
+--
+-- Name: TABLE "OSPAR"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON TABLE nvr."OSPAR" IS 'Marina skyddade områden (Ospar MPA)';
+
+
+--
+-- Name: OSPAR_ogc_fid_seq; Type: SEQUENCE; Schema: nvr; Owner: geodata
+--
+
+CREATE SEQUENCE nvr."OSPAR_ogc_fid_seq"
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE nvr."OSPAR_ogc_fid_seq" OWNER TO geodata;
+
+--
+-- Name: OSPAR_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: nvr; Owner: geodata
+--
+
+ALTER SEQUENCE nvr."OSPAR_ogc_fid_seq" OWNED BY nvr."OSPAR".ogc_fid;
+
+
+--
+-- Name: Ovrigt_biotopskyddsomrade; Type: TABLE; Schema: nvr; Owner: geodata
+--
+
+CREATE TABLE nvr."Ovrigt_biotopskyddsomrade" (
+ ogc_fid bigint NOT NULL,
+ "NVRID" integer NOT NULL,
+ "NAMN" character varying(62) NOT NULL,
+ "SKYDDSTYP" character varying(32) NOT NULL,
+ "BESLSTATUS" character varying(12) NOT NULL,
+ "URSBESLDAT" date NOT NULL,
+ "IKRAFTDATF" date,
+ "URSGALLDAT" date,
+ "SENGALLDAT" date,
+ "IUCNKAT" character varying(254) NOT NULL,
+ "FORVALTARE" character varying(62) NOT NULL,
+ "LAND_HA" double precision,
+ "VATTEN_HA" double precision,
+ "SKOG_HA" double precision,
+ "GEOSTATUS" character varying(62) NOT NULL,
+ "DIARIENR" character varying(62),
+ "LAGRUM" character varying(16) NOT NULL,
+ "BESLMYND" character varying(32) NOT NULL,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE nvr."Ovrigt_biotopskyddsomrade" OWNER TO geodata;
+
+--
+-- Name: TABLE "Ovrigt_biotopskyddsomrade"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON TABLE nvr."Ovrigt_biotopskyddsomrade" IS 'Biotopskydd utanför skogsmark';
+
+
+--
+-- Name: COLUMN "Ovrigt_biotopskyddsomrade"."NVRID"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Ovrigt_biotopskyddsomrade"."NVRID" IS 'Områdets unika ID i naturvårdsregistret';
+
+
+--
+-- Name: COLUMN "Ovrigt_biotopskyddsomrade"."NAMN"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Ovrigt_biotopskyddsomrade"."NAMN" IS 'Områdets namn';
+
+
+--
+-- Name: COLUMN "Ovrigt_biotopskyddsomrade"."SKYDDSTYP"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Ovrigt_biotopskyddsomrade"."SKYDDSTYP" IS 'Skyddstyp';
+
+
+--
+-- Name: COLUMN "Ovrigt_biotopskyddsomrade"."BESLSTATUS"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Ovrigt_biotopskyddsomrade"."BESLSTATUS" IS 'Beslutsstatus';
+
+
+--
+-- Name: COLUMN "Ovrigt_biotopskyddsomrade"."URSBESLDAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Ovrigt_biotopskyddsomrade"."URSBESLDAT" IS 'Ursprungligt beslutsdatum';
+
+
+--
+-- Name: COLUMN "Ovrigt_biotopskyddsomrade"."IKRAFTDATF"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Ovrigt_biotopskyddsomrade"."IKRAFTDATF" IS 'Ikraftträdandedatum för föreskrifte';
+
+
+--
+-- Name: COLUMN "Ovrigt_biotopskyddsomrade"."URSGALLDAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Ovrigt_biotopskyddsomrade"."URSGALLDAT" IS 'Ursprungligt gällandedatum';
+
+
+--
+-- Name: COLUMN "Ovrigt_biotopskyddsomrade"."SENGALLDAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Ovrigt_biotopskyddsomrade"."SENGALLDAT" IS 'Senaste gällandedatum';
+
+
+--
+-- Name: COLUMN "Ovrigt_biotopskyddsomrade"."IUCNKAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Ovrigt_biotopskyddsomrade"."IUCNKAT" IS 'Klassificering av skyddade områden enligt internationella naturvårdsunionens';
+
+
+--
+-- Name: COLUMN "Ovrigt_biotopskyddsomrade"."FORVALTARE"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Ovrigt_biotopskyddsomrade"."FORVALTARE" IS 'Förvaltare för området';
+
+
+--
+-- Name: COLUMN "Ovrigt_biotopskyddsomrade"."LAND_HA"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Ovrigt_biotopskyddsomrade"."LAND_HA" IS 'Areal land i hektar (våtmarker ingår i landarealen)';
+
+
+--
+-- Name: COLUMN "Ovrigt_biotopskyddsomrade"."VATTEN_HA"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Ovrigt_biotopskyddsomrade"."VATTEN_HA" IS 'Areal vatten i hektar (både sötvatten och marint vatten ingår)';
+
+
+--
+-- Name: COLUMN "Ovrigt_biotopskyddsomrade"."SKOG_HA"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Ovrigt_biotopskyddsomrade"."SKOG_HA" IS 'Skogsmarksareal i hektar';
+
+
+--
+-- Name: COLUMN "Ovrigt_biotopskyddsomrade"."GEOSTATUS"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Ovrigt_biotopskyddsomrade"."GEOSTATUS" IS 'Hur ytter gränsen för området har mätts in';
+
+
+--
+-- Name: COLUMN "Ovrigt_biotopskyddsomrade"."DIARIENR"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Ovrigt_biotopskyddsomrade"."DIARIENR" IS 'Diarienummer i beslutande myndighets diarium';
+
+
+--
+-- Name: COLUMN "Ovrigt_biotopskyddsomrade"."LAGRUM"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Ovrigt_biotopskyddsomrade"."LAGRUM" IS 'Lagrum som använts som grund för beslutet';
+
+
+--
+-- Name: COLUMN "Ovrigt_biotopskyddsomrade"."BESLMYND"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Ovrigt_biotopskyddsomrade"."BESLMYND" IS 'Beslutsmyndighet';
+
+
+--
+-- Name: Ovrigt_biotopskyddsomrade_ogc_fid_seq; Type: SEQUENCE; Schema: nvr; Owner: geodata
+--
+
+CREATE SEQUENCE nvr."Ovrigt_biotopskyddsomrade_ogc_fid_seq"
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE nvr."Ovrigt_biotopskyddsomrade_ogc_fid_seq" OWNER TO geodata;
+
+--
+-- Name: Ovrigt_biotopskyddsomrade_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: nvr; Owner: geodata
+--
+
+ALTER SEQUENCE nvr."Ovrigt_biotopskyddsomrade_ogc_fid_seq" OWNED BY nvr."Ovrigt_biotopskyddsomrade".ogc_fid;
+
+
+--
+-- Name: Ramsar; Type: TABLE; Schema: nvr; Owner: geodata
+--
+
+CREATE TABLE nvr."Ramsar" (
+ ogc_fid bigint NOT NULL,
+ "RAMSAR_ID" integer NOT NULL,
+ "SKYDDSTYP" character varying(32) NOT NULL,
+ "NATION" character varying(32) NOT NULL,
+ "NAMN" character varying(32) NOT NULL,
+ "LAND_HA" double precision,
+ "VATTEN_HA" double precision,
+ "SKOG_HA" double precision,
+ "LINK" character varying(254) NOT NULL,
+ "URSPR_BESL" date NOT NULL,
+ "SEN_BESLUT" date,
+ "LEGAL_ACT" character varying(254) NOT NULL,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE nvr."Ramsar" OWNER TO geodata;
+
+--
+-- Name: TABLE "Ramsar"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON TABLE nvr."Ramsar" IS 'Ramsar-områden (Våtmarkskonventionen)';
+
+
+--
+-- Name: COLUMN "Ramsar"."SKYDDSTYP"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Ramsar"."SKYDDSTYP" IS 'Skyddstyp';
+
+
+--
+-- Name: COLUMN "Ramsar"."LAND_HA"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Ramsar"."LAND_HA" IS 'Areal land i hektar (våtmarker ingår i landarealen)';
+
+
+--
+-- Name: COLUMN "Ramsar"."VATTEN_HA"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Ramsar"."VATTEN_HA" IS 'Areal vatten i hektar (både sötvatten och marint vatten ingår)';
+
+
+--
+-- Name: COLUMN "Ramsar"."SKOG_HA"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Ramsar"."SKOG_HA" IS 'Skogsmarksareal i hektar';
+
+
+--
+-- Name: Ramsar_ogc_fid_seq; Type: SEQUENCE; Schema: nvr; Owner: geodata
+--
+
+CREATE SEQUENCE nvr."Ramsar_ogc_fid_seq"
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE nvr."Ramsar_ogc_fid_seq" OWNER TO geodata;
+
+--
+-- Name: Ramsar_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: nvr; Owner: geodata
+--
+
+ALTER SEQUENCE nvr."Ramsar_ogc_fid_seq" OWNED BY nvr."Ramsar".ogc_fid;
+
+
+--
+-- Name: SCI_Rikstackande; Type: TABLE; Schema: nvr; Owner: geodata
+--
+
+CREATE TABLE nvr."SCI_Rikstackande" (
+ ogc_fid bigint NOT NULL,
+ "NAMN" character varying(62) NOT NULL,
+ "BEVPLAN" character varying(128) NOT NULL,
+ "SITE_CODE" character varying(9) NOT NULL,
+ "OMRADESTYP" character varying(16) NOT NULL,
+ "UPPLAMNARE" character varying(62) NOT NULL,
+ "SCI_FORSL" character varying(6) NOT NULL,
+ "SCI_DATUM" character varying(6),
+ "SAC_DATUM" character varying(6),
+ "SPA_DATUM" character varying(6),
+ "KVALITET" character varying(254) NOT NULL,
+ "KARAKTAR" character varying(254) NOT NULL,
+ "ARTER" character varying(254),
+ "NATURTYPER" character varying(254),
+ wkb_geometry public.geometry(MultiPolygonZ,3006) NOT NULL
+);
+
+
+ALTER TABLE nvr."SCI_Rikstackande" OWNER TO geodata;
+
+--
+-- Name: TABLE "SCI_Rikstackande"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON TABLE nvr."SCI_Rikstackande" IS 'Habitatdirektivet (SCI, direktiv 92/43/EEG)';
+
+
+--
+-- Name: COLUMN "SCI_Rikstackande"."NAMN"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."SCI_Rikstackande"."NAMN" IS 'Områdets namn';
+
+
+--
+-- Name: SCI_Rikstackande_ogc_fid_seq; Type: SEQUENCE; Schema: nvr; Owner: geodata
+--
+
+CREATE SEQUENCE nvr."SCI_Rikstackande_ogc_fid_seq"
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE nvr."SCI_Rikstackande_ogc_fid_seq" OWNER TO geodata;
+
+--
+-- Name: SCI_Rikstackande_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: nvr; Owner: geodata
+--
+
+ALTER SEQUENCE nvr."SCI_Rikstackande_ogc_fid_seq" OWNED BY nvr."SCI_Rikstackande".ogc_fid;
+
+
+--
+-- Name: SPA_Rikstackande; Type: TABLE; Schema: nvr; Owner: geodata
+--
+
+CREATE TABLE nvr."SPA_Rikstackande" (
+ ogc_fid bigint NOT NULL,
+ "NAMN" character varying(62) NOT NULL,
+ "BEVPLAN" character varying(128) NOT NULL,
+ "SITE_CODE" character varying(9) NOT NULL,
+ "OMRADESTYP" character varying(16) NOT NULL,
+ "UPPLAMNARE" character varying(62) NOT NULL,
+ "SCI_FORSL" character varying(6),
+ "SCI_DATUM" character varying(6),
+ "SAC_DATUM" character varying(6),
+ "SPA_DATUM" character varying(6) NOT NULL,
+ "KVALITET" character varying(254) NOT NULL,
+ "KARAKTAR" character varying(254) NOT NULL,
+ "ARTER" character varying(254) NOT NULL,
+ "NATURTYPER" character varying(254),
+ wkb_geometry public.geometry(MultiPolygonZ,3006) NOT NULL
+);
+
+
+ALTER TABLE nvr."SPA_Rikstackande" OWNER TO geodata;
+
+--
+-- Name: TABLE "SPA_Rikstackande"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON TABLE nvr."SPA_Rikstackande" IS 'Fågeldirektivet (SPA, direktiv 79/409/EEG)';
+
+
+--
+-- Name: COLUMN "SPA_Rikstackande"."NAMN"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."SPA_Rikstackande"."NAMN" IS 'Områdets namn';
+
+
+--
+-- Name: SPA_Rikstackande_ogc_fid_seq; Type: SEQUENCE; Schema: nvr; Owner: geodata
+--
+
+CREATE SEQUENCE nvr."SPA_Rikstackande_ogc_fid_seq"
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE nvr."SPA_Rikstackande_ogc_fid_seq" OWNER TO geodata;
+
+--
+-- Name: SPA_Rikstackande_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: nvr; Owner: geodata
+--
+
+ALTER SEQUENCE nvr."SPA_Rikstackande_ogc_fid_seq" OWNED BY nvr."SPA_Rikstackande".ogc_fid;
+
+
+--
+-- Name: Tilltradesforbud; Type: TABLE; Schema: nvr; Owner: geodata
+--
+
+CREATE TABLE nvr."Tilltradesforbud" (
+ ogc_fid bigint NOT NULL,
+ "NVRID" integer NOT NULL,
+ "BESLSTAT" character varying(12) NOT NULL,
+ "FORESKRTYP" character varying(16) NOT NULL,
+ "FORESKRIFT" character varying(62) NOT NULL,
+ "FRANDATUM" character varying(10) NOT NULL,
+ "TILLDATUM" character varying(10) NOT NULL,
+ "BESKRIVN" character varying(254),
+ "OBJEKTNAMN" character varying(254) NOT NULL,
+ "FORSKRNAMN" character varying(254),
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE nvr."Tilltradesforbud" OWNER TO geodata;
+
+--
+-- Name: TABLE "Tilltradesforbud"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON TABLE nvr."Tilltradesforbud" IS 'Områden med föreskrifter som inskränker rätten att färdas eller vistas i området, permanent eller under en del av året';
+
+
+--
+-- Name: COLUMN "Tilltradesforbud"."NVRID"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Tilltradesforbud"."NVRID" IS 'Områdets unika ID i naturvårdsregistret';
+
+
+--
+-- Name: COLUMN "Tilltradesforbud"."BESLSTAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Tilltradesforbud"."BESLSTAT" IS 'Beslutsstatus';
+
+
+--
+-- Name: Tilltradesforbud_ogc_fid_seq; Type: SEQUENCE; Schema: nvr; Owner: geodata
+--
+
+CREATE SEQUENCE nvr."Tilltradesforbud_ogc_fid_seq"
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE nvr."Tilltradesforbud_ogc_fid_seq" OWNER TO geodata;
+
+--
+-- Name: Tilltradesforbud_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: nvr; Owner: geodata
+--
+
+ALTER SEQUENCE nvr."Tilltradesforbud_ogc_fid_seq" OWNED BY nvr."Tilltradesforbud".ogc_fid;
+
+
+--
+-- Name: Varldsarv; Type: TABLE; Schema: nvr; Owner: geodata
+--
+
+CREATE TABLE nvr."Varldsarv" (
+ ogc_fid bigint NOT NULL,
+ "NAMN" character varying(64) NOT NULL,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE nvr."Varldsarv" OWNER TO geodata;
+
+--
+-- Name: TABLE "Varldsarv"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON TABLE nvr."Varldsarv" IS 'Världsarv med mycket höga naturvärden (UNESCO)';
+
+
+--
+-- Name: Varldsarv_ogc_fid_seq; Type: SEQUENCE; Schema: nvr; Owner: geodata
+--
+
+CREATE SEQUENCE nvr."Varldsarv_ogc_fid_seq"
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE nvr."Varldsarv_ogc_fid_seq" OWNER TO geodata;
+
+--
+-- Name: Varldsarv_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: nvr; Owner: geodata
+--
+
+ALTER SEQUENCE nvr."Varldsarv_ogc_fid_seq" OWNED BY nvr."Varldsarv".ogc_fid;
+
+
+--
+-- Name: Vattenskyddsomrade; Type: TABLE; Schema: nvr; Owner: geodata
+--
+
+CREATE TABLE nvr."Vattenskyddsomrade" (
+ ogc_fid bigint NOT NULL,
+ "NVRID" integer NOT NULL,
+ "NAMN" character varying(254) NOT NULL,
+ "SKYDDSTYP" character varying(32) NOT NULL,
+ "BESLSTATUS" character varying(12) NOT NULL,
+ "URSBESLDAT" date NOT NULL,
+ "IKRAFTDATF" date,
+ "URSGALLDAT" date,
+ "SENGALLDAT" date,
+ "TILLSYNSMH" character varying(64) NOT NULL,
+ "PROVNMHDIS" character varying(64),
+ "PROVNMHTIL" character varying(64),
+ "IUCNKAT" character varying(254) NOT NULL,
+ "LAND_HA" double precision,
+ "VATTEN_HA" double precision,
+ "SKOG_HA" double precision,
+ "GEOSTATUS" character varying(62) NOT NULL,
+ "DIARIENR" character varying(62),
+ "LAGRUM" character varying(16),
+ "BESLMYND" character varying(32) NOT NULL,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE nvr."Vattenskyddsomrade" OWNER TO geodata;
+
+--
+-- Name: TABLE "Vattenskyddsomrade"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON TABLE nvr."Vattenskyddsomrade" IS 'Vattenskyddsområden';
+
+
+--
+-- Name: COLUMN "Vattenskyddsomrade"."NVRID"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Vattenskyddsomrade"."NVRID" IS 'Områdets unika ID i naturvårdsregistret';
+
+
+--
+-- Name: COLUMN "Vattenskyddsomrade"."NAMN"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Vattenskyddsomrade"."NAMN" IS 'Områdets namn';
+
+
+--
+-- Name: COLUMN "Vattenskyddsomrade"."SKYDDSTYP"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Vattenskyddsomrade"."SKYDDSTYP" IS 'Skyddstyp';
+
+
+--
+-- Name: COLUMN "Vattenskyddsomrade"."BESLSTATUS"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Vattenskyddsomrade"."BESLSTATUS" IS 'Beslutsstatus';
+
+
+--
+-- Name: COLUMN "Vattenskyddsomrade"."URSBESLDAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Vattenskyddsomrade"."URSBESLDAT" IS 'Ursprungligt beslutsdatum';
+
+
+--
+-- Name: COLUMN "Vattenskyddsomrade"."IKRAFTDATF"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Vattenskyddsomrade"."IKRAFTDATF" IS 'Ikraftträdandedatum för föreskrifte';
+
+
+--
+-- Name: COLUMN "Vattenskyddsomrade"."URSGALLDAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Vattenskyddsomrade"."URSGALLDAT" IS 'Ursprungligt gällandedatum';
+
+
+--
+-- Name: COLUMN "Vattenskyddsomrade"."SENGALLDAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Vattenskyddsomrade"."SENGALLDAT" IS 'Senaste gällandedatum';
+
+
+--
+-- Name: COLUMN "Vattenskyddsomrade"."TILLSYNSMH"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Vattenskyddsomrade"."TILLSYNSMH" IS 'Tillsynsmyndighet';
+
+
+--
+-- Name: COLUMN "Vattenskyddsomrade"."PROVNMHDIS"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Vattenskyddsomrade"."PROVNMHDIS" IS 'Prövningsmyndighet för dispens';
+
+
+--
+-- Name: COLUMN "Vattenskyddsomrade"."PROVNMHTIL"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Vattenskyddsomrade"."PROVNMHTIL" IS 'Prövningsmyndighet för tillstånd';
+
+
+--
+-- Name: COLUMN "Vattenskyddsomrade"."IUCNKAT"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Vattenskyddsomrade"."IUCNKAT" IS 'Klassificering av skyddade områden enligt internationella naturvårdsunionens';
+
+
+--
+-- Name: COLUMN "Vattenskyddsomrade"."LAND_HA"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Vattenskyddsomrade"."LAND_HA" IS 'Areal land i hektar (våtmarker ingår i landarealen)';
+
+
+--
+-- Name: COLUMN "Vattenskyddsomrade"."VATTEN_HA"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Vattenskyddsomrade"."VATTEN_HA" IS 'Areal vatten i hektar (både sötvatten och marint vatten ingår)';
+
+
+--
+-- Name: COLUMN "Vattenskyddsomrade"."SKOG_HA"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Vattenskyddsomrade"."SKOG_HA" IS 'Skogsmarksareal i hektar';
+
+
+--
+-- Name: COLUMN "Vattenskyddsomrade"."GEOSTATUS"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Vattenskyddsomrade"."GEOSTATUS" IS 'Hur ytter gränsen för området har mätts in';
+
+
+--
+-- Name: COLUMN "Vattenskyddsomrade"."DIARIENR"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Vattenskyddsomrade"."DIARIENR" IS 'Diarienummer i beslutande myndighets diarium';
+
+
+--
+-- Name: COLUMN "Vattenskyddsomrade"."LAGRUM"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Vattenskyddsomrade"."LAGRUM" IS 'Lagrum som använts som grund för beslutet';
+
+
+--
+-- Name: COLUMN "Vattenskyddsomrade"."BESLMYND"; Type: COMMENT; Schema: nvr; Owner: geodata
+--
+
+COMMENT ON COLUMN nvr."Vattenskyddsomrade"."BESLMYND" IS 'Beslutsmyndighet';
+
+
+--
+-- Name: Vattenskyddsomrade_ogc_fid_seq; Type: SEQUENCE; Schema: nvr; Owner: geodata
+--
+
+CREATE SEQUENCE nvr."Vattenskyddsomrade_ogc_fid_seq"
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE nvr."Vattenskyddsomrade_ogc_fid_seq" OWNER TO geodata;
+
+--
+-- Name: Vattenskyddsomrade_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: nvr; Owner: geodata
+--
+
+ALTER SEQUENCE nvr."Vattenskyddsomrade_ogc_fid_seq" OWNED BY nvr."Vattenskyddsomrade".ogc_fid;
+
+
+--
+-- Name: metadata; Type: TABLE; Schema: ogr_system_tables; Owner: geodata
+--
+
+CREATE TABLE ogr_system_tables.metadata (
+ id integer NOT NULL,
+ schema_name text NOT NULL,
+ table_name text NOT NULL,
+ metadata text
+);
+
+
+ALTER TABLE ogr_system_tables.metadata OWNER TO geodata;
+
+--
+-- Name: metadata_id_seq; Type: SEQUENCE; Schema: ogr_system_tables; Owner: geodata
+--
+
+CREATE SEQUENCE ogr_system_tables.metadata_id_seq
+ AS integer
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE ogr_system_tables.metadata_id_seq OWNER TO geodata;
+
+--
+-- Name: metadata_id_seq; Type: SEQUENCE OWNED BY; Schema: ogr_system_tables; Owner: geodata
+--
+
+ALTER SEQUENCE ogr_system_tables.metadata_id_seq OWNED BY ogr_system_tables.metadata.id;
+
+
+--
+-- Name: layercache; Type: TABLE; Schema: public; Owner: geodata
+--
+
+CREATE TABLE public.layercache (
+ ogc_fid bigint NOT NULL,
+ layername character varying(255) NOT NULL,
+ last_updated timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL,
+ fingerprint bytea NOT NULL
+);
+
+
+ALTER TABLE public.layercache OWNER TO geodata;
+
+--
+-- Name: TABLE layercache; Type: COMMENT; Schema: public; Owner: geodata
+--
+
+COMMENT ON TABLE public.layercache IS 'Layer metadata cache';
+
+
+--
+-- Name: layercache_ogc_fid_seq; Type: SEQUENCE; Schema: public; Owner: geodata
+--
+
+CREATE SEQUENCE public.layercache_ogc_fid_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE public.layercache_ogc_fid_seq OWNER TO geodata;
+
+--
+-- Name: layercache_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: geodata
+--
+
+ALTER SEQUENCE public.layercache_ogc_fid_seq OWNED BY public.layercache.ogc_fid;
+
+
+--
+-- Name: betesomrade; Type: TABLE; Schema: sametinget; Owner: geodata
+--
+
+CREATE TABLE sametinget.betesomrade (
+ ogc_fid bigint NOT NULL,
+ "SAMEBY_ID" integer NOT NULL,
+ "BY_ID" integer,
+ "NAMN" character varying(62) NOT NULL,
+ "SIGNATUR" character varying(25) NOT NULL,
+ "SAMEBY_TYP" character varying(62) NOT NULL,
+ "BY_OMR" boolean NOT NULL,
+ "OVR_OMR" boolean NOT NULL,
+ "AKTUALITET" date NOT NULL,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE sametinget.betesomrade OWNER TO geodata;
+
+--
+-- Name: TABLE betesomrade; Type: COMMENT; Schema: sametinget; Owner: geodata
+--
+
+COMMENT ON TABLE sametinget.betesomrade IS 'Samebyarnas betesområden: Renbetesområden';
+
+
+--
+-- Name: betesomrade_ogc_fid_seq; Type: SEQUENCE; Schema: sametinget; Owner: geodata
+--
+
+CREATE SEQUENCE sametinget.betesomrade_ogc_fid_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE sametinget.betesomrade_ogc_fid_seq OWNER TO geodata;
+
+--
+-- Name: betesomrade_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: sametinget; Owner: geodata
+--
+
+ALTER SEQUENCE sametinget.betesomrade_ogc_fid_seq OWNED BY sametinget.betesomrade.ogc_fid;
+
+
+--
+-- Name: flyttled; Type: TABLE; Schema: sametinget; Owner: geodata
+--
+
+CREATE TABLE sametinget.flyttled (
+ ogc_fid bigint NOT NULL,
+ "LED_ID" integer NOT NULL,
+ "BYNR1" integer NOT NULL,
+ "BYNR2" integer NOT NULL,
+ "BYNR3" integer NOT NULL,
+ "SAMEBY1" character varying(62),
+ "SAMEBY2" character varying(62),
+ "SAMEBY3" character varying(62),
+ "KKOD" integer NOT NULL,
+ "BESKRIVNIN" character varying(62),
+ "ARSTID" character varying(62),
+ "KONV_AR" character varying(62),
+ "SIGNATUR" character varying(25),
+ "RIKSINTR" boolean NOT NULL,
+ "FAST_LED" boolean NOT NULL,
+ "AKTUALITET" character varying(10),
+ "GlobalID" uuid NOT NULL,
+ wkb_geometry public.geometry(MultiLineString,3006) NOT NULL
+);
+
+
+ALTER TABLE sametinget.flyttled OWNER TO geodata;
+
+--
+-- Name: TABLE flyttled; Type: COMMENT; Schema: sametinget; Owner: geodata
+--
+
+COMMENT ON TABLE sametinget.flyttled IS 'Samebyarnas markanvändningsredovisning: Flyttled';
+
+
+--
+-- Name: flyttled_ogc_fid_seq; Type: SEQUENCE; Schema: sametinget; Owner: geodata
+--
+
+CREATE SEQUENCE sametinget.flyttled_ogc_fid_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE sametinget.flyttled_ogc_fid_seq OWNER TO geodata;
+
+--
+-- Name: flyttled_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: sametinget; Owner: geodata
+--
+
+ALTER SEQUENCE sametinget.flyttled_ogc_fid_seq OWNED BY sametinget.flyttled.ogc_fid;
+
+
+--
+-- Name: riksintresse_rennaringen; Type: TABLE; Schema: sametinget; Owner: geodata
+--
+
+CREATE TABLE sametinget.riksintresse_rennaringen (
+ ogc_fid bigint NOT NULL,
+ "LAGRUM" character varying(254) NOT NULL,
+ "AKTUALITET" date NOT NULL,
+ "SIGNATUR" character varying(25) NOT NULL,
+ "LANK" character varying(254),
+ "GlobalID" uuid NOT NULL,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE sametinget.riksintresse_rennaringen OWNER TO geodata;
+
+--
+-- Name: TABLE riksintresse_rennaringen; Type: COMMENT; Schema: sametinget; Owner: geodata
+--
+
+COMMENT ON TABLE sametinget.riksintresse_rennaringen IS 'Riksintresse Rennäringen';
+
+
+--
+-- Name: riksintresse_rennaringen_karnomrade; Type: TABLE; Schema: sametinget; Owner: geodata
+--
+
+CREATE TABLE sametinget.riksintresse_rennaringen_karnomrade (
+ ogc_fid bigint NOT NULL,
+ "LANK" character varying(254) NOT NULL,
+ "LANSKOD" character varying(25) NOT NULL,
+ "OMR_NR" integer,
+ "ARET_RUNT" integer,
+ "SAMEBY" character varying(62) NOT NULL,
+ "ANSVARIG" character varying(25) NOT NULL,
+ "AKTUALITET" date NOT NULL,
+ "SIGNATUR" character varying(25),
+ "GlobalID" uuid NOT NULL,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE sametinget.riksintresse_rennaringen_karnomrade OWNER TO geodata;
+
+--
+-- Name: TABLE riksintresse_rennaringen_karnomrade; Type: COMMENT; Schema: sametinget; Owner: geodata
+--
+
+COMMENT ON TABLE sametinget.riksintresse_rennaringen_karnomrade IS 'Riksintresse Rennäringen — Kärnområde';
+
+
+--
+-- Name: riksintresse_rennaringen_karnomrade_ogc_fid_seq; Type: SEQUENCE; Schema: sametinget; Owner: geodata
+--
+
+CREATE SEQUENCE sametinget.riksintresse_rennaringen_karnomrade_ogc_fid_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE sametinget.riksintresse_rennaringen_karnomrade_ogc_fid_seq OWNER TO geodata;
+
+--
+-- Name: riksintresse_rennaringen_karnomrade_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: sametinget; Owner: geodata
+--
+
+ALTER SEQUENCE sametinget.riksintresse_rennaringen_karnomrade_ogc_fid_seq OWNED BY sametinget.riksintresse_rennaringen_karnomrade.ogc_fid;
+
+
+--
+-- Name: riksintresse_rennaringen_ogc_fid_seq; Type: SEQUENCE; Schema: sametinget; Owner: geodata
+--
+
+CREATE SEQUENCE sametinget.riksintresse_rennaringen_ogc_fid_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE sametinget.riksintresse_rennaringen_ogc_fid_seq OWNER TO geodata;
+
+--
+-- Name: riksintresse_rennaringen_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: sametinget; Owner: geodata
+--
+
+ALTER SEQUENCE sametinget.riksintresse_rennaringen_ogc_fid_seq OWNED BY sametinget.riksintresse_rennaringen.ogc_fid;
+
+
+--
+-- Name: atervatningsavtal; Type: TABLE; Schema: sks; Owner: geodata
+--
+
+CREATE TABLE sks.atervatningsavtal (
+ ogc_fid bigint NOT NULL,
+ "Uuid" uuid NOT NULL,
+ "Beteckn" character varying(12) NOT NULL,
+ "ArendeAr" smallint NOT NULL,
+ "AvtalatDatum" date,
+ "Url" character varying(252),
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE sks.atervatningsavtal OWNER TO geodata;
+
+--
+-- Name: TABLE atervatningsavtal; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON TABLE sks.atervatningsavtal IS 'Återvätningsavtal';
+
+
+--
+-- Name: COLUMN atervatningsavtal."Uuid"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.atervatningsavtal."Uuid" IS 'Unikt ID';
+
+
+--
+-- Name: COLUMN atervatningsavtal."Beteckn"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.atervatningsavtal."Beteckn" IS 'Ärendebeteckning';
+
+
+--
+-- Name: COLUMN atervatningsavtal."ArendeAr"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.atervatningsavtal."ArendeAr" IS 'Ärendeår';
+
+
+--
+-- Name: COLUMN atervatningsavtal."AvtalatDatum"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.atervatningsavtal."AvtalatDatum" IS 'Avtalat datum';
+
+
+--
+-- Name: COLUMN atervatningsavtal."Url"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.atervatningsavtal."Url" IS 'Länk till Skogens pärlors formulär för objektet';
+
+
+--
+-- Name: atervatningsavtal_ogc_fid_seq; Type: SEQUENCE; Schema: sks; Owner: geodata
+--
+
+CREATE SEQUENCE sks.atervatningsavtal_ogc_fid_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE sks.atervatningsavtal_ogc_fid_seq OWNER TO geodata;
+
+--
+-- Name: atervatningsavtal_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: sks; Owner: geodata
+--
+
+ALTER SEQUENCE sks.atervatningsavtal_ogc_fid_seq OWNED BY sks.atervatningsavtal.ogc_fid;
+
+
+--
+-- Name: avverk_anmald; Type: TABLE; Schema: sks; Owner: geodata
+--
+
+CREATE TABLE sks.avverk_anmald (
ogc_fid bigint NOT NULL,
"OBJECTID" integer NOT NULL,
- "Beteckn" character(12) NOT NULL,
+ "Beteckn" character varying(12) NOT NULL,
"ArendeAr" smallint NOT NULL,
- "Avverktyp" character varying(254) NOT NULL,
- "Skogstyp" character varying(254) NOT NULL,
"Inkomdatum" date NOT NULL,
"AnmaldHa" real NOT NULL,
- "SkogsodlHa" real NOT NULL,
- "NatforHa" real NOT NULL,
+ "SkogsodlHa" real,
+ "NatforHa" real,
"AvvSasong" character varying(254) NOT NULL,
- "ArendeStat" character varying(254) NOT NULL,
+ "ArendeStatus" character varying(254) NOT NULL,
"AvvHa" real,
- "Avverkning" character varying(254) NOT NULL,
- wkb_geometry postgis.geometry(MultiPolygon,3006)
+ "AvverkningsanmalanKlass" character varying(254) NOT NULL,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
);
-ALTER TABLE postgis."sks:AvverkAnm" OWNER TO webmap_import;
+ALTER TABLE sks.avverk_anmald OWNER TO geodata;
+
+--
+-- Name: TABLE avverk_anmald; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON TABLE sks.avverk_anmald IS 'Avverkningsanmälningar (Skogsstyrelsen)';
+
+
+--
+-- Name: COLUMN avverk_anmald."OBJECTID"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.avverk_anmald."OBJECTID" IS 'Unik identitet';
+
--
--- Name: TABLE "sks:AvverkAnm"; Type: COMMENT; Schema: postgis; Owner: webmap_import
+-- Name: COLUMN avverk_anmald."Beteckn"; Type: COMMENT; Schema: sks; Owner: geodata
--
-COMMENT ON TABLE postgis."sks:AvverkAnm" IS 'Avverkningsanmälningar (Skogsstyrelsen)';
+COMMENT ON COLUMN sks.avverk_anmald."Beteckn" IS 'Ärendebeteckning';
--
--- Name: sks:AvverkAnm_ogc_fid_seq; Type: SEQUENCE; Schema: postgis; Owner: webmap_import
+-- Name: COLUMN avverk_anmald."ArendeAr"; Type: COMMENT; Schema: sks; Owner: geodata
--
-CREATE SEQUENCE postgis."sks:AvverkAnm_ogc_fid_seq"
+COMMENT ON COLUMN sks.avverk_anmald."ArendeAr" IS 'År anmälan/ansökan registrerades';
+
+
+--
+-- Name: COLUMN avverk_anmald."Inkomdatum"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.avverk_anmald."Inkomdatum" IS 'Anmälan/ansökan inkom datum';
+
+
+--
+-- Name: COLUMN avverk_anmald."AnmaldHa"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.avverk_anmald."AnmaldHa" IS 'Areal anmält (ha)';
+
+
+--
+-- Name: COLUMN avverk_anmald."SkogsodlHa"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.avverk_anmald."SkogsodlHa" IS 'Areal plantering (ha)';
+
+
+--
+-- Name: COLUMN avverk_anmald."NatforHa"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.avverk_anmald."NatforHa" IS 'Areal naturlig föryngring (ha)';
+
+
+--
+-- Name: COLUMN avverk_anmald."AvvSasong"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.avverk_anmald."AvvSasong" IS 'Avverkningssäsong';
+
+
+--
+-- Name: COLUMN avverk_anmald."ArendeStatus"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.avverk_anmald."ArendeStatus" IS 'Ärendestatus';
+
+
+--
+-- Name: COLUMN avverk_anmald."AvvHa"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.avverk_anmald."AvvHa" IS 'Avverkad areal (ha)';
+
+
+--
+-- Name: COLUMN avverk_anmald."AvverkningsanmalanKlass"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.avverk_anmald."AvverkningsanmalanKlass" IS 'Avverkningsamalan/NyAvverkningsanmalan';
+
+
+--
+-- Name: avverk_anmald_ogc_fid_seq; Type: SEQUENCE; Schema: sks; Owner: geodata
+--
+
+CREATE SEQUENCE sks.avverk_anmald_ogc_fid_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
@@ -575,53 +5663,307 @@ CREATE SEQUENCE postgis."sks:AvverkAnm_ogc_fid_seq"
CACHE 1;
-ALTER TABLE postgis."sks:AvverkAnm_ogc_fid_seq" OWNER TO webmap_import;
+ALTER SEQUENCE sks.avverk_anmald_ogc_fid_seq OWNER TO geodata;
--
--- Name: sks:AvverkAnm_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: postgis; Owner: webmap_import
+-- Name: avverk_anmald_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: sks; Owner: geodata
--
-ALTER SEQUENCE postgis."sks:AvverkAnm_ogc_fid_seq" OWNED BY postgis."sks:AvverkAnm".ogc_fid;
+ALTER SEQUENCE sks.avverk_anmald_ogc_fid_seq OWNED BY sks.avverk_anmald.ogc_fid;
--
--- Name: sks:UtfordAvverk; Type: TABLE; Schema: postgis; Owner: webmap_import
+-- Name: avverk_utford; Type: TABLE; Schema: sks; Owner: geodata
--
-CREATE TABLE postgis."sks:UtfordAvverk" (
+CREATE TABLE sks.avverk_utford (
ogc_fid bigint NOT NULL,
"OBJECTID" integer NOT NULL,
- "Beteckn" character(12),
+ "Beteckn" character varying(12),
"ArendeAr" smallint NOT NULL,
"Avverktyp" character varying(254) NOT NULL,
"Skogstyp" character varying(254) NOT NULL,
"AnmaldHa" real NOT NULL,
- "SkogsodlHa" real NOT NULL,
- "NatforHa" real NOT NULL,
- "Avvdatum" date NOT NULL,
- "KallaDatum" date,
- "KallaAreal" character varying(62),
+ "NatforHa" real,
+ "Avvdatum" date,
+ "KallaDatum" character varying(62),
"Forebild" character varying(62),
"Efterbild" character varying(62),
"ArealHa" real NOT NULL,
- wkb_geometry postgis.geometry(MultiPolygon,3006)
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE sks.avverk_utford OWNER TO geodata;
+
+--
+-- Name: TABLE avverk_utford; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON TABLE sks.avverk_utford IS 'Utförd avverkning (Skogsstyrelsen)';
+
+
+--
+-- Name: COLUMN avverk_utford."OBJECTID"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.avverk_utford."OBJECTID" IS 'Unik identitet';
+
+
+--
+-- Name: COLUMN avverk_utford."Beteckn"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.avverk_utford."Beteckn" IS 'Ärendebeteckning';
+
+
+--
+-- Name: COLUMN avverk_utford."ArendeAr"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.avverk_utford."ArendeAr" IS 'År anmälan/ansökan registrerades';
+
+
+--
+-- Name: COLUMN avverk_utford."Avverktyp"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.avverk_utford."Avverktyp" IS 'Vad anmälan/ansökan gäller';
+
+
+--
+-- Name: COLUMN avverk_utford."Skogstyp"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.avverk_utford."Skogstyp" IS 'Anger om avverkning är inom fjällnära skog, ädellövskog eller normal skog';
+
+
+--
+-- Name: COLUMN avverk_utford."AnmaldHa"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.avverk_utford."AnmaldHa" IS 'Areal anmält (ha)';
+
+
+--
+-- Name: COLUMN avverk_utford."NatforHa"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.avverk_utford."NatforHa" IS 'Areal naturlig föryngring (ha)';
+
+
+--
+-- Name: COLUMN avverk_utford."Avvdatum"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.avverk_utford."Avvdatum" IS 'Datum för avverkning';
+
+
+--
+-- Name: COLUMN avverk_utford."KallaDatum"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.avverk_utford."KallaDatum" IS 'Ursprung för datum för avverkning (vid ”Uppgift saknas” är det vanligen Skogsstyrelsens personal som registrerat datumet)';
+
+
+--
+-- Name: COLUMN avverk_utford."Forebild"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.avverk_utford."Forebild" IS 'Namnet på den gamla bilden i skillnadsanalysen';
+
+
+--
+-- Name: COLUMN avverk_utford."Efterbild"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.avverk_utford."Efterbild" IS 'Namnet på den nya bilden i skillnadsanalysen';
+
+
+--
+-- Name: COLUMN avverk_utford."ArealHa"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.avverk_utford."ArealHa" IS 'Areal för ytan (ha)';
+
+
+--
+-- Name: avverk_utford_ogc_fid_seq; Type: SEQUENCE; Schema: sks; Owner: geodata
+--
+
+CREATE SEQUENCE sks.avverk_utford_ogc_fid_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE sks.avverk_utford_ogc_fid_seq OWNER TO geodata;
+
+--
+-- Name: avverk_utford_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: sks; Owner: geodata
+--
+
+ALTER SEQUENCE sks.avverk_utford_ogc_fid_seq OWNED BY sks.avverk_utford.ogc_fid;
+
+
+--
+-- Name: naturvarde; Type: TABLE; Schema: sks; Owner: geodata
+--
+
+CREATE TABLE sks.naturvarde (
+ ogc_fid bigint NOT NULL,
+ "ObjectId" integer NOT NULL,
+ "Beteckn" character varying(12) NOT NULL,
+ "Objnamn" character varying(62),
+ "Datinv" date NOT NULL,
+ "Biotop1" character varying(62),
+ "Biotop2" character varying(62),
+ "Biotop3" character varying(62),
+ "Beskrivn1" character varying(62),
+ "Beskrivn2" character varying(62),
+ "Beskrivn3" character varying(62),
+ "Url" character varying(254) NOT NULL,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE sks.naturvarde OWNER TO geodata;
+
+--
+-- Name: TABLE naturvarde; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON TABLE sks.naturvarde IS 'Objekt med naturvärden - Skogsstyrelsen';
+
+
+--
+-- Name: COLUMN naturvarde."ObjectId"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.naturvarde."ObjectId" IS 'Unik identitet';
+
+
+--
+-- Name: COLUMN naturvarde."Beteckn"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.naturvarde."Beteckn" IS 'Ärendebeteckning';
+
+
+--
+-- Name: COLUMN naturvarde."Objnamn"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.naturvarde."Objnamn" IS 'Namn på objektet';
+
+
+--
+-- Name: COLUMN naturvarde."Datinv"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.naturvarde."Datinv" IS 'Datum för fältinventering';
+
+
+--
+-- Name: COLUMN naturvarde."Url"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.naturvarde."Url" IS 'Länk till visningsformulär i Skogens Pärlor';
+
+
+--
+-- Name: naturvarde_ogc_fid_seq; Type: SEQUENCE; Schema: sks; Owner: geodata
+--
+
+CREATE SEQUENCE sks.naturvarde_ogc_fid_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE sks.naturvarde_ogc_fid_seq OWNER TO geodata;
+
+--
+-- Name: naturvarde_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: sks; Owner: geodata
+--
+
+ALTER SEQUENCE sks.naturvarde_ogc_fid_seq OWNED BY sks.naturvarde.ogc_fid;
+
+
+--
+-- Name: naturvardsavtal; Type: TABLE; Schema: sks; Owner: geodata
+--
+
+CREATE TABLE sks.naturvardsavtal (
+ ogc_fid bigint NOT NULL,
+ "Uuid" uuid NOT NULL,
+ "Beteckn" character varying(12) NOT NULL,
+ "ArendeAr" smallint NOT NULL,
+ "NvaTyp" character varying(254),
+ "Naturtyp" character varying(254),
+ "AreaTot" double precision NOT NULL,
+ "AreaProd" double precision NOT NULL,
+ "Standort" character varying(254),
+ "DatAvtal" date,
+ "Url" character varying(254) NOT NULL,
+ "Undertyp" character varying(64),
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
);
-ALTER TABLE postgis."sks:UtfordAvverk" OWNER TO webmap_import;
+ALTER TABLE sks.naturvardsavtal OWNER TO geodata;
+
+--
+-- Name: TABLE naturvardsavtal; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON TABLE sks.naturvardsavtal IS 'Naturvårdsavtal (Skogsstyrelsen)';
+
+
+--
+-- Name: COLUMN naturvardsavtal."Uuid"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.naturvardsavtal."Uuid" IS 'Unik identitet';
+
+
+--
+-- Name: COLUMN naturvardsavtal."Beteckn"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.naturvardsavtal."Beteckn" IS 'Ärendebeteckning';
+
+
+--
+-- Name: COLUMN naturvardsavtal."ArendeAr"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.naturvardsavtal."ArendeAr" IS 'År anmälan/ansökan registrerades';
+
+
+--
+-- Name: COLUMN naturvardsavtal."Standort"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.naturvardsavtal."Standort" IS 'Ståndortsindex';
+
--
--- Name: TABLE "sks:UtfordAvverk"; Type: COMMENT; Schema: postgis; Owner: webmap_import
+-- Name: COLUMN naturvardsavtal."Url"; Type: COMMENT; Schema: sks; Owner: geodata
--
-COMMENT ON TABLE postgis."sks:UtfordAvverk" IS 'Utförd avverkning (Skogsstyrelsen)';
+COMMENT ON COLUMN sks.naturvardsavtal."Url" IS 'Länk till visningsformulär i Skogens Pärlor';
--
--- Name: sks:UtfordAvverk_ogc_fid_seq; Type: SEQUENCE; Schema: postgis; Owner: webmap_import
+-- Name: naturvardsavtal_ogc_fid_seq; Type: SEQUENCE; Schema: sks; Owner: geodata
--
-CREATE SEQUENCE postgis."sks:UtfordAvverk_ogc_fid_seq"
+CREATE SEQUENCE sks.naturvardsavtal_ogc_fid_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
@@ -629,25 +5971,545 @@ CREATE SEQUENCE postgis."sks:UtfordAvverk_ogc_fid_seq"
CACHE 1;
-ALTER TABLE postgis."sks:UtfordAvverk_ogc_fid_seq" OWNER TO webmap_import;
+ALTER SEQUENCE sks.naturvardsavtal_ogc_fid_seq OWNER TO geodata;
--
--- Name: sks:UtfordAvverk_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: postgis; Owner: webmap_import
+-- Name: naturvardsavtal_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: sks; Owner: geodata
--
-ALTER SEQUENCE postgis."sks:UtfordAvverk_ogc_fid_seq" OWNED BY postgis."sks:UtfordAvverk".ogc_fid;
+ALTER SEQUENCE sks.naturvardsavtal_ogc_fid_seq OWNED BY sks.naturvardsavtal.ogc_fid;
--
--- Name: vbk:havsbaserad_vindkraft; Type: TABLE; Schema: postgis; Owner: webmap_import
+-- Name: nyckelbiotop; Type: TABLE; Schema: sks; Owner: geodata
--
-CREATE TABLE postgis."vbk:havsbaserad_vindkraft" (
+CREATE TABLE sks.nyckelbiotop (
ogc_fid bigint NOT NULL,
- "OmrID" character(10) NOT NULL,
+ "Beteckn" character varying(12) NOT NULL,
+ "Objnamn" character varying(62),
+ "Datinv" date NOT NULL,
+ "Biotop1" character varying(62),
+ "Biotop2" character varying(62),
+ "Biotop3" character varying(62),
+ "Beskrivn1" character varying(62),
+ "Beskrivn2" character varying(62),
+ "Beskrivn3" character varying(62),
+ "Beskrivn4" character varying(62),
+ "Beskrivn5" character varying(62),
+ "Beskrivn6" character varying(62),
+ "Beskrivn7" character varying(62),
+ "Beskrivn8" character varying(62),
+ "Url" character varying(254) NOT NULL,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE sks.nyckelbiotop OWNER TO geodata;
+
+--
+-- Name: TABLE nyckelbiotop; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON TABLE sks.nyckelbiotop IS 'Nyckelbiotoper - Skogsstyrelsen';
+
+
+--
+-- Name: COLUMN nyckelbiotop."Beteckn"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.nyckelbiotop."Beteckn" IS 'Ärendebeteckning';
+
+
+--
+-- Name: COLUMN nyckelbiotop."Objnamn"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.nyckelbiotop."Objnamn" IS 'Namn på objektet';
+
+
+--
+-- Name: COLUMN nyckelbiotop."Datinv"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.nyckelbiotop."Datinv" IS 'Datum för fältinventering';
+
+
+--
+-- Name: COLUMN nyckelbiotop."Url"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.nyckelbiotop."Url" IS 'Länk till visningsformulär i Skogens Pärlor';
+
+
+--
+-- Name: nyckelbiotop_ogc_fid_seq; Type: SEQUENCE; Schema: sks; Owner: geodata
+--
+
+CREATE SEQUENCE sks.nyckelbiotop_ogc_fid_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE sks.nyckelbiotop_ogc_fid_seq OWNER TO geodata;
+
+--
+-- Name: nyckelbiotop_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: sks; Owner: geodata
+--
+
+ALTER SEQUENCE sks.nyckelbiotop_ogc_fid_seq OWNED BY sks.nyckelbiotop.ogc_fid;
+
+
+--
+-- Name: nyckelbiotop_storskogsbruk; Type: TABLE; Schema: sks; Owner: geodata
+--
+
+CREATE TABLE sks.nyckelbiotop_storskogsbruk (
+ ogc_fid bigint NOT NULL,
+ objectid integer NOT NULL,
+ "Org" character varying(62) NOT NULL,
+ "InkomDatum" date NOT NULL,
+ "Url" character varying(254) NOT NULL,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE sks.nyckelbiotop_storskogsbruk OWNER TO geodata;
+
+--
+-- Name: TABLE nyckelbiotop_storskogsbruk; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON TABLE sks.nyckelbiotop_storskogsbruk IS 'Nyckelbiotoper - storskogsbruket';
+
+
+--
+-- Name: COLUMN nyckelbiotop_storskogsbruk.objectid; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.nyckelbiotop_storskogsbruk.objectid IS 'Unik identitet';
+
+
+--
+-- Name: COLUMN nyckelbiotop_storskogsbruk."Org"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.nyckelbiotop_storskogsbruk."Org" IS 'Namn på Organisation som gjort inventeringen';
+
+
+--
+-- Name: COLUMN nyckelbiotop_storskogsbruk."InkomDatum"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.nyckelbiotop_storskogsbruk."InkomDatum" IS 'Datum då data inkommit till Skogsstyrelsen';
+
+
+--
+-- Name: COLUMN nyckelbiotop_storskogsbruk."Url"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.nyckelbiotop_storskogsbruk."Url" IS 'Länk till Skogens Pärlors visningsformulär';
+
+
+--
+-- Name: nyckelbiotop_storskogsbruk_ogc_fid_seq; Type: SEQUENCE; Schema: sks; Owner: geodata
+--
+
+CREATE SEQUENCE sks.nyckelbiotop_storskogsbruk_ogc_fid_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE sks.nyckelbiotop_storskogsbruk_ogc_fid_seq OWNER TO geodata;
+
+--
+-- Name: nyckelbiotop_storskogsbruk_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: sks; Owner: geodata
+--
+
+ALTER SEQUENCE sks.nyckelbiotop_storskogsbruk_ogc_fid_seq OWNED BY sks.nyckelbiotop_storskogsbruk.ogc_fid;
+
+
+--
+-- Name: sumpskog; Type: TABLE; Schema: sks; Owner: geodata
+--
+
+CREATE TABLE sks.sumpskog (
+ ogc_fid bigint NOT NULL,
+ "OBJECTID" integer NOT NULL,
+ "Namn" character varying(62),
+ "Hydrtext" character varying(62),
+ "Tradtext" character varying(62) NOT NULL,
+ "Delklass" character varying(62),
+ "Klassu" character varying(62),
+ "Lovandel" character varying(62),
+ "Krontakn" character varying(62),
+ "Huggklas" character varying(62),
+ "Andelva" character varying(62),
+ "Ingrepp" character varying(62),
+ "Ingrpavv" character varying(62),
+ "Objnyck" character varying(62),
+ "Delnyck" character varying(62),
+ "Flygar" smallint,
+ "Faltdat" date,
+ "Invtekn" character varying(62) NOT NULL,
+ "Invdat" date NOT NULL,
+ "Ansvmynd" character varying(62) NOT NULL,
+ "Url" character varying(252) NOT NULL,
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
+);
+
+
+ALTER TABLE sks.sumpskog OWNER TO geodata;
+
+--
+-- Name: TABLE sumpskog; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON TABLE sks.sumpskog IS 'Sumpskogar';
+
+
+--
+-- Name: COLUMN sumpskog."OBJECTID"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.sumpskog."OBJECTID" IS 'Unik identitet';
+
+
+--
+-- Name: COLUMN sumpskog."Namn"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.sumpskog."Namn" IS 'Objektnamn';
+
+
+--
+-- Name: COLUMN sumpskog."Hydrtext"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.sumpskog."Hydrtext" IS 'Hydrologisk text, ex. kärrskog, mosseskog';
+
+
+--
+-- Name: COLUMN sumpskog."Tradtext"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.sumpskog."Tradtext" IS 'Trädslag';
+
+
+--
+-- Name: COLUMN sumpskog."Delklass"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.sumpskog."Delklass" IS 'Klass på delobjektet';
+
+
+--
+-- Name: COLUMN sumpskog."Klassu"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.sumpskog."Klassu" IS 'Klass på objektet';
+
+
+--
+-- Name: COLUMN sumpskog."Lovandel"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.sumpskog."Lovandel" IS 'Lövandel';
+
+
+--
+-- Name: COLUMN sumpskog."Krontakn"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.sumpskog."Krontakn" IS 'Krontäckning';
+
+
+--
+-- Name: COLUMN sumpskog."Huggklas"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.sumpskog."Huggklas" IS 'Huggningsklass';
+
+
+--
+-- Name: COLUMN sumpskog."Andelva"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.sumpskog."Andelva" IS 'Andel öppet vatten';
+
+
+--
+-- Name: COLUMN sumpskog."Ingrepp"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.sumpskog."Ingrepp" IS 'Ingrepp på delobjekt (max 4)';
+
+
+--
+-- Name: COLUMN sumpskog."Ingrpavv"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.sumpskog."Ingrpavv" IS 'Grad av påverkan på delobjekt (max 4)';
+
+
+--
+-- Name: COLUMN sumpskog."Objnyck"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.sumpskog."Objnyck" IS 'Nyckelord på objektnivå';
+
+
+--
+-- Name: COLUMN sumpskog."Delnyck"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.sumpskog."Delnyck" IS 'Nyckelord på delobjektsnivå';
+
+
+--
+-- Name: COLUMN sumpskog."Flygar"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.sumpskog."Flygar" IS 'Flygbildsår';
+
+
+--
+-- Name: COLUMN sumpskog."Faltdat"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.sumpskog."Faltdat" IS 'Faltdat';
+
+
+--
+-- Name: COLUMN sumpskog."Invtekn"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.sumpskog."Invtekn" IS 'Inventeringsteknik';
+
+
+--
+-- Name: COLUMN sumpskog."Invdat"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.sumpskog."Invdat" IS 'Inventeringdatum';
+
+
+--
+-- Name: COLUMN sumpskog."Ansvmynd"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.sumpskog."Ansvmynd" IS 'Ansvarig myndighet';
+
+
+--
+-- Name: COLUMN sumpskog."Url"; Type: COMMENT; Schema: sks; Owner: geodata
+--
+
+COMMENT ON COLUMN sks.sumpskog."Url" IS 'Länk till Skogens pärlors formulär för objektet';
+
+
+--
+-- Name: sumpskog_ogc_fid_seq; Type: SEQUENCE; Schema: sks; Owner: geodata
+--
+
+CREATE SEQUENCE sks.sumpskog_ogc_fid_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE sks.sumpskog_ogc_fid_seq OWNER TO geodata;
+
+--
+-- Name: sumpskog_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: sks; Owner: geodata
+--
+
+ALTER SEQUENCE sks.sumpskog_ogc_fid_seq OWNED BY sks.sumpskog.ogc_fid;
+
+
+--
+-- Name: ledningar; Type: TABLE; Schema: svk; Owner: geodata
+--
+
+CREATE TABLE svk.ledningar (
+ ogc_fid bigint NOT NULL,
+ "Placement" character varying(32),
+ "Voltage" integer,
+ wkb_geometry public.geometry(MultiLineString,3006) NOT NULL
+);
+
+
+ALTER TABLE svk.ledningar OWNER TO geodata;
+
+--
+-- Name: TABLE ledningar; Type: COMMENT; Schema: svk; Owner: geodata
+--
+
+COMMENT ON TABLE svk.ledningar IS 'Kraftledningar (befintliga)';
+
+
+--
+-- Name: ledningar_ogc_fid_seq; Type: SEQUENCE; Schema: svk; Owner: geodata
+--
+
+CREATE SEQUENCE svk.ledningar_ogc_fid_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE svk.ledningar_ogc_fid_seq OWNER TO geodata;
+
+--
+-- Name: ledningar_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: svk; Owner: geodata
+--
+
+ALTER SEQUENCE svk.ledningar_ogc_fid_seq OWNED BY svk.ledningar.ogc_fid;
+
+
+--
+-- Name: stationsomraden; Type: TABLE; Schema: svk; Owner: geodata
+--
+
+CREATE TABLE svk.stationsomraden (
+ ogc_fid bigint NOT NULL,
+ wkb_geometry public.geometry(MultiPolygonZ,3006) NOT NULL
+);
+
+
+ALTER TABLE svk.stationsomraden OWNER TO geodata;
+
+--
+-- Name: TABLE stationsomraden; Type: COMMENT; Schema: svk; Owner: geodata
+--
+
+COMMENT ON TABLE svk.stationsomraden IS 'Stationsomraden';
+
+
+--
+-- Name: stationsomraden_ogc_fid_seq; Type: SEQUENCE; Schema: svk; Owner: geodata
+--
+
+CREATE SEQUENCE svk.stationsomraden_ogc_fid_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE svk.stationsomraden_ogc_fid_seq OWNER TO geodata;
+
+--
+-- Name: stationsomraden_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: svk; Owner: geodata
+--
+
+ALTER SEQUENCE svk.stationsomraden_ogc_fid_seq OWNED BY svk.stationsomraden.ogc_fid;
+
+
+--
+-- Name: stolpar; Type: TABLE; Schema: svk; Owner: geodata
+--
+
+CREATE TABLE svk.stolpar (
+ ogc_fid bigint NOT NULL,
+ wkb_geometry public.geometry(PointZ,3006) NOT NULL
+);
+
+
+ALTER TABLE svk.stolpar OWNER TO geodata;
+
+--
+-- Name: TABLE stolpar; Type: COMMENT; Schema: svk; Owner: geodata
+--
+
+COMMENT ON TABLE svk.stolpar IS 'Stolpar (befintliga)';
+
+
+--
+-- Name: stolpar_ogc_fid_seq; Type: SEQUENCE; Schema: svk; Owner: geodata
+--
+
+CREATE SEQUENCE svk.stolpar_ogc_fid_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE svk.stolpar_ogc_fid_seq OWNER TO geodata;
+
+--
+-- Name: stolpar_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: svk; Owner: geodata
+--
+
+ALTER SEQUENCE svk.stolpar_ogc_fid_seq OWNED BY svk.stolpar.ogc_fid;
+
+
+--
+-- Name: transmissionsnatsprojekt; Type: TABLE; Schema: svk; Owner: geodata
+--
+
+CREATE TABLE svk.transmissionsnatsprojekt (
+ ogc_fid bigint NOT NULL,
+ "Name" character varying(254),
+ "Voltage" integer,
+ "Url" character varying(254),
+ wkb_geometry public.geometry(MultiLineString,3006) NOT NULL
+);
+
+
+ALTER TABLE svk.transmissionsnatsprojekt OWNER TO geodata;
+
+--
+-- Name: TABLE transmissionsnatsprojekt; Type: COMMENT; Schema: svk; Owner: geodata
+--
+
+COMMENT ON TABLE svk.transmissionsnatsprojekt IS 'Transmissionsnätsprojekt';
+
+
+--
+-- Name: transmissionsnatsprojekt_ogc_fid_seq; Type: SEQUENCE; Schema: svk; Owner: geodata
+--
+
+CREATE SEQUENCE svk.transmissionsnatsprojekt_ogc_fid_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+
+ALTER SEQUENCE svk.transmissionsnatsprojekt_ogc_fid_seq OWNER TO geodata;
+
+--
+-- Name: transmissionsnatsprojekt_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: svk; Owner: geodata
+--
+
+ALTER SEQUENCE svk.transmissionsnatsprojekt_ogc_fid_seq OWNED BY svk.transmissionsnatsprojekt.ogc_fid;
+
+
+--
+-- Name: havsbaserad_vindkraft; Type: TABLE; Schema: vbk; Owner: geodata
+--
+
+CREATE TABLE vbk.havsbaserad_vindkraft (
+ ogc_fid bigint NOT NULL,
+ "OmrID" character varying(10) NOT NULL,
"Projektnamn" character varying(62),
"Organisationsnamn" character varying(254),
- "Organisationsnummer" character(11),
+ "Organisationsnummer" character varying(11),
"Projektstatus" character varying(62) NOT NULL,
"Diarienummer" character varying(254),
"AndringsansokanPagar" boolean,
@@ -677,24 +6539,108 @@ CREATE TABLE postgis."vbk:havsbaserad_vindkraft" (
"ElNamn" character varying(62) NOT NULL,
"SenasteUppdaterat" date NOT NULL,
"Raderat" boolean NOT NULL,
- wkb_geometry postgis.geometry(MultiPolygon,3006)
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
);
-ALTER TABLE postgis."vbk:havsbaserad_vindkraft" OWNER TO webmap_import;
+ALTER TABLE vbk.havsbaserad_vindkraft OWNER TO geodata;
+
+--
+-- Name: TABLE havsbaserad_vindkraft; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON TABLE vbk.havsbaserad_vindkraft IS 'Vindbrukskollen havsbaserad vindkraft (Länsstyrelsen)';
+
+
+--
+-- Name: COLUMN havsbaserad_vindkraft."OmrID"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.havsbaserad_vindkraft."OmrID" IS 'ID-nummer i Vindbruksollen för projekteringsområdet';
+
+
+--
+-- Name: COLUMN havsbaserad_vindkraft."Projektnamn"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.havsbaserad_vindkraft."Projektnamn" IS 'Namn på projekteringsområdet';
+
--
--- Name: TABLE "vbk:havsbaserad_vindkraft"; Type: COMMENT; Schema: postgis; Owner: webmap_import
+-- Name: COLUMN havsbaserad_vindkraft."Organisationsnamn"; Type: COMMENT; Schema: vbk; Owner: geodata
--
-COMMENT ON TABLE postgis."vbk:havsbaserad_vindkraft" IS 'Vindbrukskollen havsbaserad vindkraft (Länsstyrelsen)';
+COMMENT ON COLUMN vbk.havsbaserad_vindkraft."Organisationsnamn" IS 'Namnet på verksamhetsutövaren för projekteringsområdet';
--
--- Name: vbk:havsbaserad_vindkraft_ogc_fid_seq; Type: SEQUENCE; Schema: postgis; Owner: webmap_import
+-- Name: COLUMN havsbaserad_vindkraft."Organisationsnummer"; Type: COMMENT; Schema: vbk; Owner: geodata
--
-CREATE SEQUENCE postgis."vbk:havsbaserad_vindkraft_ogc_fid_seq"
+COMMENT ON COLUMN vbk.havsbaserad_vindkraft."Organisationsnummer" IS 'Verksamhetsutövarens organisationsnummer';
+
+
+--
+-- Name: COLUMN havsbaserad_vindkraft."AndringsansokanPagar"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.havsbaserad_vindkraft."AndringsansokanPagar" IS 'Om ändringsansökan pågår';
+
+
+--
+-- Name: COLUMN havsbaserad_vindkraft."UnderByggnation"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.havsbaserad_vindkraft."UnderByggnation" IS 'Om projekteringsområdet är under byggnation';
+
+
+--
+-- Name: COLUMN havsbaserad_vindkraft."Uppfort"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.havsbaserad_vindkraft."Uppfort" IS 'Uppförandedatum för vindkraftverket';
+
+
+--
+-- Name: COLUMN havsbaserad_vindkraft."PlaneradByggstart"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.havsbaserad_vindkraft."PlaneradByggstart" IS 'Datumangivelse för planerad byggstart för projektet';
+
+
+--
+-- Name: COLUMN havsbaserad_vindkraft."PlaneratDrift"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.havsbaserad_vindkraft."PlaneratDrift" IS 'Datumangivelse för planerat idrifttagande för projektet';
+
+
+--
+-- Name: COLUMN havsbaserad_vindkraft."Calprod"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.havsbaserad_vindkraft."Calprod" IS 'Den beräknade årsproduktionern (GWh) för vindkraftverket';
+
+
+--
+-- Name: COLUMN havsbaserad_vindkraft."ElNamn"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.havsbaserad_vindkraft."ElNamn" IS 'Elområde dit vindkraftverket tillhör';
+
+
+--
+-- Name: COLUMN havsbaserad_vindkraft."SenasteUppdaterat"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.havsbaserad_vindkraft."SenasteUppdaterat" IS 'Datum då vindkraftverket senast sparats i Vindbrukskollen';
+
+
+--
+-- Name: havsbaserad_vindkraft_ogc_fid_seq; Type: SEQUENCE; Schema: vbk; Owner: geodata
+--
+
+CREATE SEQUENCE vbk.havsbaserad_vindkraft_ogc_fid_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
@@ -702,22 +6648,22 @@ CREATE SEQUENCE postgis."vbk:havsbaserad_vindkraft_ogc_fid_seq"
CACHE 1;
-ALTER TABLE postgis."vbk:havsbaserad_vindkraft_ogc_fid_seq" OWNER TO webmap_import;
+ALTER SEQUENCE vbk.havsbaserad_vindkraft_ogc_fid_seq OWNER TO geodata;
--
--- Name: vbk:havsbaserad_vindkraft_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: postgis; Owner: webmap_import
+-- Name: havsbaserad_vindkraft_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: vbk; Owner: geodata
--
-ALTER SEQUENCE postgis."vbk:havsbaserad_vindkraft_ogc_fid_seq" OWNED BY postgis."vbk:havsbaserad_vindkraft".ogc_fid;
+ALTER SEQUENCE vbk.havsbaserad_vindkraft_ogc_fid_seq OWNED BY vbk.havsbaserad_vindkraft.ogc_fid;
--
--- Name: vbk:projekteringsomraden; Type: TABLE; Schema: postgis; Owner: webmap_import
+-- Name: projekteringsomraden; Type: TABLE; Schema: vbk; Owner: geodata
--
-CREATE TABLE postgis."vbk:projekteringsomraden" (
+CREATE TABLE vbk.projekteringsomraden (
ogc_fid bigint NOT NULL,
- "OmrID" character(10) NOT NULL,
+ "OmrID" character varying(10) NOT NULL,
"Projektnamn" character varying(62),
"AntalVerk" smallint NOT NULL,
"AntalEjXY" smallint NOT NULL,
@@ -727,29 +6673,127 @@ CREATE TABLE postgis."vbk:projekteringsomraden" (
"AndringsansokanPagar" boolean,
"UnderByggnation" boolean,
"Organisationsnamn" character varying(254),
- "Organisationsnummer" character(11),
+ "Organisationsnummer" character varying(11),
"ElNamn" character varying(62) NOT NULL,
"SenasteUppdaterat" date,
"EjAktuell" boolean NOT NULL,
"Raderat" boolean NOT NULL,
- wkb_geometry postgis.geometry(MultiPolygon,3006)
+ wkb_geometry public.geometry(MultiPolygon,3006) NOT NULL
);
-ALTER TABLE postgis."vbk:projekteringsomraden" OWNER TO webmap_import;
+ALTER TABLE vbk.projekteringsomraden OWNER TO geodata;
+
+--
+-- Name: TABLE projekteringsomraden; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON TABLE vbk.projekteringsomraden IS 'Vindbrukskollen landbaserade projekteringsområden (Länsstyrelsen)';
+
+
+--
+-- Name: COLUMN projekteringsomraden."OmrID"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.projekteringsomraden."OmrID" IS 'ID-nummer i Vindbruksollen för projekteringsområdet';
+
--
--- Name: TABLE "vbk:projekteringsomraden"; Type: COMMENT; Schema: postgis; Owner: webmap_import
+-- Name: COLUMN projekteringsomraden."Projektnamn"; Type: COMMENT; Schema: vbk; Owner: geodata
--
-COMMENT ON TABLE postgis."vbk:projekteringsomraden" IS 'Vindbrukskollen landbaserade projekteringsområden (Länsstyrelsen)';
+COMMENT ON COLUMN vbk.projekteringsomraden."Projektnamn" IS 'Namn på projekteringsområdet';
--
--- Name: vbk:projekteringsomraden_ogc_fid_seq; Type: SEQUENCE; Schema: postgis; Owner: webmap_import
+-- Name: COLUMN projekteringsomraden."AntalVerk"; Type: COMMENT; Schema: vbk; Owner: geodata
--
-CREATE SEQUENCE postgis."vbk:projekteringsomraden_ogc_fid_seq"
+COMMENT ON COLUMN vbk.projekteringsomraden."AntalVerk" IS 'Antal vindkraftverk exklusive status "Ej aktuell/återkallat"';
+
+
+--
+-- Name: COLUMN projekteringsomraden."AntalEjXY"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.projekteringsomraden."AntalEjXY" IS 'Antal vindkraftverk utan koordinater som tillhör projekteringsområdet';
+
+
+--
+-- Name: COLUMN projekteringsomraden."Calprod"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.projekteringsomraden."Calprod" IS 'Summan av verkens uppgivna beräknade årsproduktion (GWh)';
+
+
+--
+-- Name: COLUMN projekteringsomraden."PlaneradByggstart"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.projekteringsomraden."PlaneradByggstart" IS 'Datumangivelse för planerad byggstart för projektet';
+
+
+--
+-- Name: COLUMN projekteringsomraden."PlaneratDrift"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.projekteringsomraden."PlaneratDrift" IS 'Datumangivelse för planerat idrifttagande för projektet';
+
+
+--
+-- Name: COLUMN projekteringsomraden."AndringsansokanPagar"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.projekteringsomraden."AndringsansokanPagar" IS 'Om ändringsansökan pågår';
+
+
+--
+-- Name: COLUMN projekteringsomraden."UnderByggnation"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.projekteringsomraden."UnderByggnation" IS 'Om projekteringsområdet är under byggnation';
+
+
+--
+-- Name: COLUMN projekteringsomraden."Organisationsnamn"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.projekteringsomraden."Organisationsnamn" IS 'Namnet på verksamhetsutövaren för projekteringsområdet';
+
+
+--
+-- Name: COLUMN projekteringsomraden."Organisationsnummer"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.projekteringsomraden."Organisationsnummer" IS 'Verksamhetsutövarens organisationsnummer';
+
+
+--
+-- Name: COLUMN projekteringsomraden."ElNamn"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.projekteringsomraden."ElNamn" IS 'Elområde dit projekteringsområdet tillhör';
+
+
+--
+-- Name: COLUMN projekteringsomraden."SenasteUppdaterat"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.projekteringsomraden."SenasteUppdaterat" IS 'Datum då projektet senast sparats i Vindbrukskollen (om datum saknas har området inte sparats efter nov 2018)';
+
+
+--
+-- Name: COLUMN projekteringsomraden."EjAktuell"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.projekteringsomraden."EjAktuell" IS 'Om samtliga verk inom projekteringsområdet har status ej aktuellt / återkallat / avslag med laga kraft';
+
+
+--
+-- Name: projekteringsomraden_ogc_fid_seq; Type: SEQUENCE; Schema: vbk; Owner: geodata
+--
+
+CREATE SEQUENCE vbk.projekteringsomraden_ogc_fid_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
@@ -757,23 +6801,23 @@ CREATE SEQUENCE postgis."vbk:projekteringsomraden_ogc_fid_seq"
CACHE 1;
-ALTER TABLE postgis."vbk:projekteringsomraden_ogc_fid_seq" OWNER TO webmap_import;
+ALTER SEQUENCE vbk.projekteringsomraden_ogc_fid_seq OWNER TO geodata;
--
--- Name: vbk:projekteringsomraden_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: postgis; Owner: webmap_import
+-- Name: projekteringsomraden_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: vbk; Owner: geodata
--
-ALTER SEQUENCE postgis."vbk:projekteringsomraden_ogc_fid_seq" OWNED BY postgis."vbk:projekteringsomraden".ogc_fid;
+ALTER SEQUENCE vbk.projekteringsomraden_ogc_fid_seq OWNED BY vbk.projekteringsomraden.ogc_fid;
--
--- Name: vbk:vindkraftverk; Type: TABLE; Schema: postgis; Owner: webmap_import
+-- Name: vindkraftverk; Type: TABLE; Schema: vbk; Owner: geodata
--
-CREATE TABLE postgis."vbk:vindkraftverk" (
+CREATE TABLE vbk.vindkraftverk (
ogc_fid bigint NOT NULL,
- "VerkID" character(14) NOT NULL,
- "OmrID" character(10) NOT NULL,
+ "VerkID" character varying(14) NOT NULL,
+ "OmrID" character varying(10) NOT NULL,
"Projektnamn" character varying(62),
"Status" character varying(62) NOT NULL,
"Statuskod" smallint NOT NULL,
@@ -788,30 +6832,163 @@ CREATE TABLE postgis."vbk:vindkraftverk" (
"Fabrikat" character varying(62),
"Modell" character varying(62),
"Organisationsnamn" character varying(254),
- "Organisationsnummer" character(11),
+ "Organisationsnummer" character varying(11),
"Placering" character varying(62),
"ElNamn" character varying(62) NOT NULL,
"SenasteUppdaterat" date,
"EjAktuell" boolean,
"Raderat" boolean NOT NULL,
- wkb_geometry postgis.geometry(Point,3006)
+ wkb_geometry public.geometry(Point,3006) NOT NULL
);
-ALTER TABLE postgis."vbk:vindkraftverk" OWNER TO webmap_import;
+ALTER TABLE vbk.vindkraftverk OWNER TO geodata;
--
--- Name: TABLE "vbk:vindkraftverk"; Type: COMMENT; Schema: postgis; Owner: webmap_import
+-- Name: TABLE vindkraftverk; Type: COMMENT; Schema: vbk; Owner: geodata
--
-COMMENT ON TABLE postgis."vbk:vindkraftverk" IS 'Vindbrukskollen landbaserade vindkraftverk (Länsstyrelsen)';
+COMMENT ON TABLE vbk.vindkraftverk IS 'Vindbrukskollen landbaserade vindkraftverk (Länsstyrelsen)';
--
--- Name: vbk:vindkraftverk_ogc_fid_seq; Type: SEQUENCE; Schema: postgis; Owner: webmap_import
+-- Name: COLUMN vindkraftverk."VerkID"; Type: COMMENT; Schema: vbk; Owner: geodata
--
-CREATE SEQUENCE postgis."vbk:vindkraftverk_ogc_fid_seq"
+COMMENT ON COLUMN vbk.vindkraftverk."VerkID" IS 'ID-nummer i Vindbrukskollen för vindkraftverket';
+
+
+--
+-- Name: COLUMN vindkraftverk."OmrID"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.vindkraftverk."OmrID" IS 'ID-nummer i Vindbruksollen för projekteringsområdet';
+
+
+--
+-- Name: COLUMN vindkraftverk."Projektnamn"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.vindkraftverk."Projektnamn" IS 'Namn på projekteringsområdet';
+
+
+--
+-- Name: COLUMN vindkraftverk."Status"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.vindkraftverk."Status" IS 'Status för vindkraftverket (t.ex beviljat)';
+
+
+--
+-- Name: COLUMN vindkraftverk."Handlingstyp"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.vindkraftverk."Handlingstyp" IS 'Aktuell prövningsgrund enligt Miljöbalken eller Plan och Bygglagen';
+
+
+--
+-- Name: COLUMN vindkraftverk."Uppfort"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.vindkraftverk."Uppfort" IS 'Uppförandedatum för vindkraftverket';
+
+
+--
+-- Name: COLUMN vindkraftverk."MB_Tillstand"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.vindkraftverk."MB_Tillstand" IS 'Datum för tidsbegränsning av miljötillståndet';
+
+
+--
+-- Name: COLUMN vindkraftverk."Totalhojd"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.vindkraftverk."Totalhojd" IS 'Totalhöjd (m) för vindkraftverket';
+
+
+--
+-- Name: COLUMN vindkraftverk."Navhojd"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.vindkraftverk."Navhojd" IS 'Navhöjd (m) för vindkraftverket';
+
+
+--
+-- Name: COLUMN vindkraftverk."Rotordiameter"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.vindkraftverk."Rotordiameter" IS 'Rotordiameter (m) för vindkraftverket';
+
+
+--
+-- Name: COLUMN vindkraftverk."Maxeffekt"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.vindkraftverk."Maxeffekt" IS 'Ansökt eller installerad maxeffekt (MW) för vindkraftverket';
+
+
+--
+-- Name: COLUMN vindkraftverk."Calprod"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.vindkraftverk."Calprod" IS 'Den beräknade årsproduktionern (GWh) för vindkraftverket';
+
+
+--
+-- Name: COLUMN vindkraftverk."Fabrikat"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.vindkraftverk."Fabrikat" IS 'Namn på vindkraftverkets fabrikat';
+
+
+--
+-- Name: COLUMN vindkraftverk."Modell"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.vindkraftverk."Modell" IS 'Namn på vindkraftverkets modell';
+
+
+--
+-- Name: COLUMN vindkraftverk."Organisationsnamn"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.vindkraftverk."Organisationsnamn" IS 'Namnet på verksamhetsutövaren för projekteringsområdet';
+
+
+--
+-- Name: COLUMN vindkraftverk."Organisationsnummer"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.vindkraftverk."Organisationsnummer" IS 'Verksamhetsutövarens organisationsnummer';
+
+
+--
+-- Name: COLUMN vindkraftverk."Placering"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.vindkraftverk."Placering" IS 'Anger om verket är placerat på land eller i vatten';
+
+
+--
+-- Name: COLUMN vindkraftverk."ElNamn"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.vindkraftverk."ElNamn" IS 'Elområde dit vindkraftverket tillhör';
+
+
+--
+-- Name: COLUMN vindkraftverk."SenasteUppdaterat"; Type: COMMENT; Schema: vbk; Owner: geodata
+--
+
+COMMENT ON COLUMN vbk.vindkraftverk."SenasteUppdaterat" IS 'Datum då vindkraftverket senast sparats i Vindbrukskollen (om datum saknas har vindkraftverket inte sparats efter nov 2018)';
+
+
+--
+-- Name: vindkraftverk_ogc_fid_seq; Type: SEQUENCE; Schema: vbk; Owner: geodata
+--
+
+CREATE SEQUENCE vbk.vindkraftverk_ogc_fid_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
@@ -819,809 +6996,3243 @@ CREATE SEQUENCE postgis."vbk:vindkraftverk_ogc_fid_seq"
CACHE 1;
-ALTER TABLE postgis."vbk:vindkraftverk_ogc_fid_seq" OWNER TO webmap_import;
+ALTER SEQUENCE vbk.vindkraftverk_ogc_fid_seq OWNER TO geodata;
+
+--
+-- Name: vindkraftverk_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: vbk; Owner: geodata
+--
+
+ALTER SEQUENCE vbk.vindkraftverk_ogc_fid_seq OWNED BY vbk.vindkraftverk.ogc_fid;
+
+
+--
+-- Name: kommunyta ogc_fid; Type: DEFAULT; Schema: lm_topo250; Owner: geodata
+--
+
+ALTER TABLE ONLY lm_topo250.kommunyta ALTER COLUMN ogc_fid SET DEFAULT nextval('lm_topo250.kommunyta_ogc_fid_seq'::regclass);
+
+
+--
+-- Name: kommunyta_sub ogc_fid; Type: DEFAULT; Schema: lm_topo250; Owner: geodata
+--
+
+ALTER TABLE ONLY lm_topo250.kommunyta_sub ALTER COLUMN ogc_fid SET DEFAULT nextval('lm_topo250.kommunyta_sub_ogc_fid_seq'::regclass);
+
+
+--
+-- Name: lansyta ogc_fid; Type: DEFAULT; Schema: lm_topo250; Owner: geodata
+--
+
+ALTER TABLE ONLY lm_topo250.lansyta ALTER COLUMN ogc_fid SET DEFAULT nextval('lm_topo250.lansyta_ogc_fid_seq'::regclass);
+
+
+--
+-- Name: lansyta_sub ogc_fid; Type: DEFAULT; Schema: lm_topo250; Owner: geodata
+--
+
+ALTER TABLE ONLY lm_topo250.lansyta_sub ALTER COLUMN ogc_fid SET DEFAULT nextval('lm_topo250.lansyta_sub_ogc_fid_seq'::regclass);
+
+
+--
+-- Name: pagaende_naturreservatsbildning ogc_fid; Type: DEFAULT; Schema: lst; Owner: geodata
+--
+
+ALTER TABLE ONLY lst.pagaende_naturreservatsbildning ALTER COLUMN ogc_fid SET DEFAULT nextval('lst.pagaende_naturreservatsbildning_ogc_fid_seq'::regclass);
+
+
+--
+-- Name: riksintresse_obruten_kust ogc_fid; Type: DEFAULT; Schema: lst; Owner: geodata
+--
+
+ALTER TABLE ONLY lst.riksintresse_obruten_kust ALTER COLUMN ogc_fid SET DEFAULT nextval('lst.riksintresse_obruten_kust_ogc_fid_seq'::regclass);
+
+
+--
+-- Name: riksintresse_obrutet_fjall ogc_fid; Type: DEFAULT; Schema: lst; Owner: geodata
+--
+
+ALTER TABLE ONLY lst.riksintresse_obrutet_fjall ALTER COLUMN ogc_fid SET DEFAULT nextval('lst.riksintresse_obrutet_fjall_ogc_fid_seq'::regclass);
+
+
+--
+-- Name: riksintresse_rorligt_friluftsliv ogc_fid; Type: DEFAULT; Schema: lst; Owner: geodata
+--
+
+ALTER TABLE ONLY lst.riksintresse_rorligt_friluftsliv ALTER COLUMN ogc_fid SET DEFAULT nextval('lst.riksintresse_rorligt_friluftsliv_ogc_fid_seq'::regclass);
+
+
+--
+-- Name: riksintresse_skyddade_vattendrag ogc_fid; Type: DEFAULT; Schema: lst; Owner: geodata
+--
+
+ALTER TABLE ONLY lst.riksintresse_skyddade_vattendrag ALTER COLUMN ogc_fid SET DEFAULT nextval('lst.riksintresse_skyddade_vattendrag_ogc_fid_seq'::regclass);
+
+
+--
+-- Name: dammar ogc_fid; Type: DEFAULT; Schema: misc; Owner: geodata
+--
+
+ALTER TABLE ONLY misc.dammar ALTER COLUMN ogc_fid SET DEFAULT nextval('misc.dammar_ogc_fid_seq'::regclass);
+
+
+--
+-- Name: gigafactories ogc_fid; Type: DEFAULT; Schema: misc; Owner: geodata
+--
+
+ALTER TABLE ONLY misc.gigafactories ALTER COLUMN ogc_fid SET DEFAULT nextval('misc.gigafactories_ogc_fid_seq'::regclass);
+
+
+--
+-- Name: bearbetningskoncessioner_ansokta ogc_fid; Type: DEFAULT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.bearbetningskoncessioner_ansokta ALTER COLUMN ogc_fid SET DEFAULT nextval('mrr.bearbetningskoncessioner_ansokta_ogc_fid_seq'::regclass);
+
+
+--
+-- Name: bearbetningskoncessioner_beviljade ogc_fid; Type: DEFAULT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.bearbetningskoncessioner_beviljade ALTER COLUMN ogc_fid SET DEFAULT nextval('mrr.bearbetningskoncessioner_beviljade_ogc_fid_seq'::regclass);
+
+
+--
+-- Name: bearbetningskoncessioner_forfallna ogc_fid; Type: DEFAULT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.bearbetningskoncessioner_forfallna ALTER COLUMN ogc_fid SET DEFAULT nextval('mrr.bearbetningskoncessioner_forfallna_ogc_fid_seq'::regclass);
+
+
+--
+-- Name: markanvisningar_bk_ansokta ogc_fid; Type: DEFAULT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.markanvisningar_bk_ansokta ALTER COLUMN ogc_fid SET DEFAULT nextval('mrr.markanvisningar_bk_ansokta_ogc_fid_seq'::regclass);
+
+
+--
+-- Name: markanvisningar_bk_beviljade ogc_fid; Type: DEFAULT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.markanvisningar_bk_beviljade ALTER COLUMN ogc_fid SET DEFAULT nextval('mrr.markanvisningar_bk_beviljade_ogc_fid_seq'::regclass);
+
+
+--
+-- Name: ut_diamant_ansokta ogc_fid; Type: DEFAULT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.ut_diamant_ansokta ALTER COLUMN ogc_fid SET DEFAULT nextval('mrr.ut_diamant_ansokta_ogc_fid_seq'::regclass);
+
+
+--
+-- Name: ut_diamant_beviljade ogc_fid; Type: DEFAULT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.ut_diamant_beviljade ALTER COLUMN ogc_fid SET DEFAULT nextval('mrr.ut_diamant_beviljade_ogc_fid_seq'::regclass);
+
+
+--
+-- Name: ut_diamant_forbud ogc_fid; Type: DEFAULT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.ut_diamant_forbud ALTER COLUMN ogc_fid SET DEFAULT nextval('mrr.ut_diamant_forbud_ogc_fid_seq'::regclass);
+
+
+--
+-- Name: ut_metaller_industrimineral_ansokta ogc_fid; Type: DEFAULT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.ut_metaller_industrimineral_ansokta ALTER COLUMN ogc_fid SET DEFAULT nextval('mrr.ut_metaller_industrimineral_ansokta_ogc_fid_seq'::regclass);
+
+
+--
+-- Name: ut_metaller_industrimineral_beviljade ogc_fid; Type: DEFAULT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.ut_metaller_industrimineral_beviljade ALTER COLUMN ogc_fid SET DEFAULT nextval('mrr.ut_metaller_industrimineral_beviljade_ogc_fid_seq'::regclass);
+
+
+--
+-- Name: ut_metaller_industrimineral_forbud ogc_fid; Type: DEFAULT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.ut_metaller_industrimineral_forbud ALTER COLUMN ogc_fid SET DEFAULT nextval('mrr.ut_metaller_industrimineral_forbud_ogc_fid_seq'::regclass);
+
+
+--
+-- Name: ut_metaller_industrimineral_forfallna ogc_fid; Type: DEFAULT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.ut_metaller_industrimineral_forfallna ALTER COLUMN ogc_fid SET DEFAULT nextval('mrr.ut_metaller_industrimineral_forfallna_ogc_fid_seq'::regclass);
+
+
+--
+-- Name: ut_olja_gas_diamant_forfallna ogc_fid; Type: DEFAULT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.ut_olja_gas_diamant_forfallna ALTER COLUMN ogc_fid SET DEFAULT nextval('mrr.ut_olja_gas_diamant_forfallna_ogc_fid_seq'::regclass);
+
+
+--
+-- Name: naturvardsavtal ogc_fid; Type: DEFAULT; Schema: nvk; Owner: geodata
+--
+
+ALTER TABLE ONLY nvk.naturvardsavtal ALTER COLUMN ogc_fid SET DEFAULT nextval('nvk.naturvardsavtal_ogc_fid_seq'::regclass);
+
+
+--
+-- Name: riksintresse_friluftsliv ogc_fid; Type: DEFAULT; Schema: nvk; Owner: geodata
+--
+
+ALTER TABLE ONLY nvk.riksintresse_friluftsliv ALTER COLUMN ogc_fid SET DEFAULT nextval('nvk.riksintresse_friluftsliv_ogc_fid_seq'::regclass);
+
+
+--
+-- Name: riksintresse_naturvard ogc_fid; Type: DEFAULT; Schema: nvk; Owner: geodata
+--
+
+ALTER TABLE ONLY nvk.riksintresse_naturvard ALTER COLUMN ogc_fid SET DEFAULT nextval('nvk.riksintresse_naturvard_ogc_fid_seq'::regclass);
+
+
+--
+-- Name: skyddsvard_statlig_skog ogc_fid; Type: DEFAULT; Schema: nvk; Owner: geodata
+--
+
+ALTER TABLE ONLY nvk.skyddsvard_statlig_skog ALTER COLUMN ogc_fid SET DEFAULT nextval('nvk.skyddsvard_statlig_skog_ogc_fid_seq'::regclass);
+
+
+--
+-- Name: Biosfarsomraden ogc_fid; Type: DEFAULT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Biosfarsomraden" ALTER COLUMN ogc_fid SET DEFAULT nextval('nvr."Biosfarsomraden_ogc_fid_seq"'::regclass);
+
+
+--
+-- Name: Biotopskydd ogc_fid; Type: DEFAULT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Biotopskydd" ALTER COLUMN ogc_fid SET DEFAULT nextval('nvr."Biotopskydd_ogc_fid_seq"'::regclass);
+
+
+--
+-- Name: Djur_och_vaxtskyddsomrade ogc_fid; Type: DEFAULT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Djur_och_vaxtskyddsomrade" ALTER COLUMN ogc_fid SET DEFAULT nextval('nvr."Djur_och_vaxtskyddsomrade_ogc_fid_seq"'::regclass);
+
+
+--
+-- Name: HELCOM ogc_fid; Type: DEFAULT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."HELCOM" ALTER COLUMN ogc_fid SET DEFAULT nextval('nvr."HELCOM_ogc_fid_seq"'::regclass);
+
+
+--
+-- Name: Interimistiskt_forbud ogc_fid; Type: DEFAULT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Interimistiskt_forbud" ALTER COLUMN ogc_fid SET DEFAULT nextval('nvr."Interimistiskt_forbud_ogc_fid_seq"'::regclass);
+
+
+--
+-- Name: Kultureservat ogc_fid; Type: DEFAULT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Kultureservat" ALTER COLUMN ogc_fid SET DEFAULT nextval('nvr."Kultureservat_ogc_fid_seq"'::regclass);
+
+
+--
+-- Name: Landskapsbildsskyddsomrade ogc_fid; Type: DEFAULT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Landskapsbildsskyddsomrade" ALTER COLUMN ogc_fid SET DEFAULT nextval('nvr."Landskapsbildsskyddsomrade_ogc_fid_seq"'::regclass);
+
+
+--
+-- Name: Nationalpark ogc_fid; Type: DEFAULT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Nationalpark" ALTER COLUMN ogc_fid SET DEFAULT nextval('nvr."Nationalpark_ogc_fid_seq"'::regclass);
+
+
+--
+-- Name: Naturminne_punkt ogc_fid; Type: DEFAULT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Naturminne_punkt" ALTER COLUMN ogc_fid SET DEFAULT nextval('nvr."Naturminne_punkt_ogc_fid_seq"'::regclass);
+
+
+--
+-- Name: Naturminne_yta ogc_fid; Type: DEFAULT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Naturminne_yta" ALTER COLUMN ogc_fid SET DEFAULT nextval('nvr."Naturminne_yta_ogc_fid_seq"'::regclass);
+
+
+--
+-- Name: Naturreservat ogc_fid; Type: DEFAULT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Naturreservat" ALTER COLUMN ogc_fid SET DEFAULT nextval('nvr."Naturreservat_ogc_fid_seq"'::regclass);
+
+
+--
+-- Name: Naturvardsomrade ogc_fid; Type: DEFAULT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Naturvardsomrade" ALTER COLUMN ogc_fid SET DEFAULT nextval('nvr."Naturvardsomrade_ogc_fid_seq"'::regclass);
+
+
+--
+-- Name: OSPAR ogc_fid; Type: DEFAULT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."OSPAR" ALTER COLUMN ogc_fid SET DEFAULT nextval('nvr."OSPAR_ogc_fid_seq"'::regclass);
+
+
+--
+-- Name: Ovrigt_biotopskyddsomrade ogc_fid; Type: DEFAULT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Ovrigt_biotopskyddsomrade" ALTER COLUMN ogc_fid SET DEFAULT nextval('nvr."Ovrigt_biotopskyddsomrade_ogc_fid_seq"'::regclass);
+
+
+--
+-- Name: Ramsar ogc_fid; Type: DEFAULT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Ramsar" ALTER COLUMN ogc_fid SET DEFAULT nextval('nvr."Ramsar_ogc_fid_seq"'::regclass);
+
+
+--
+-- Name: SCI_Rikstackande ogc_fid; Type: DEFAULT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."SCI_Rikstackande" ALTER COLUMN ogc_fid SET DEFAULT nextval('nvr."SCI_Rikstackande_ogc_fid_seq"'::regclass);
+
+
+--
+-- Name: SPA_Rikstackande ogc_fid; Type: DEFAULT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."SPA_Rikstackande" ALTER COLUMN ogc_fid SET DEFAULT nextval('nvr."SPA_Rikstackande_ogc_fid_seq"'::regclass);
+
+
+--
+-- Name: Tilltradesforbud ogc_fid; Type: DEFAULT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Tilltradesforbud" ALTER COLUMN ogc_fid SET DEFAULT nextval('nvr."Tilltradesforbud_ogc_fid_seq"'::regclass);
+
+
+--
+-- Name: Varldsarv ogc_fid; Type: DEFAULT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Varldsarv" ALTER COLUMN ogc_fid SET DEFAULT nextval('nvr."Varldsarv_ogc_fid_seq"'::regclass);
+
+
+--
+-- Name: Vattenskyddsomrade ogc_fid; Type: DEFAULT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Vattenskyddsomrade" ALTER COLUMN ogc_fid SET DEFAULT nextval('nvr."Vattenskyddsomrade_ogc_fid_seq"'::regclass);
+
+
+--
+-- Name: metadata id; Type: DEFAULT; Schema: ogr_system_tables; Owner: geodata
+--
+
+ALTER TABLE ONLY ogr_system_tables.metadata ALTER COLUMN id SET DEFAULT nextval('ogr_system_tables.metadata_id_seq'::regclass);
+
+
+--
+-- Name: layercache ogc_fid; Type: DEFAULT; Schema: public; Owner: geodata
+--
+
+ALTER TABLE ONLY public.layercache ALTER COLUMN ogc_fid SET DEFAULT nextval('public.layercache_ogc_fid_seq'::regclass);
+
+
+--
+-- Name: betesomrade ogc_fid; Type: DEFAULT; Schema: sametinget; Owner: geodata
+--
+
+ALTER TABLE ONLY sametinget.betesomrade ALTER COLUMN ogc_fid SET DEFAULT nextval('sametinget.betesomrade_ogc_fid_seq'::regclass);
+
+
+--
+-- Name: flyttled ogc_fid; Type: DEFAULT; Schema: sametinget; Owner: geodata
+--
+
+ALTER TABLE ONLY sametinget.flyttled ALTER COLUMN ogc_fid SET DEFAULT nextval('sametinget.flyttled_ogc_fid_seq'::regclass);
+
--
--- Name: vbk:vindkraftverk_ogc_fid_seq; Type: SEQUENCE OWNED BY; Schema: postgis; Owner: webmap_import
+-- Name: riksintresse_rennaringen ogc_fid; Type: DEFAULT; Schema: sametinget; Owner: geodata
--
-ALTER SEQUENCE postgis."vbk:vindkraftverk_ogc_fid_seq" OWNED BY postgis."vbk:vindkraftverk".ogc_fid;
+ALTER TABLE ONLY sametinget.riksintresse_rennaringen ALTER COLUMN ogc_fid SET DEFAULT nextval('sametinget.riksintresse_rennaringen_ogc_fid_seq'::regclass);
--
--- Name: kommunyta ogc_fid; Type: DEFAULT; Schema: postgis; Owner: webmap_import
+-- Name: riksintresse_rennaringen_karnomrade ogc_fid; Type: DEFAULT; Schema: sametinget; Owner: geodata
--
-ALTER TABLE ONLY postgis.kommunyta ALTER COLUMN ogc_fid SET DEFAULT nextval('postgis.kommunyta_ogc_fid_seq'::regclass);
+ALTER TABLE ONLY sametinget.riksintresse_rennaringen_karnomrade ALTER COLUMN ogc_fid SET DEFAULT nextval('sametinget.riksintresse_rennaringen_karnomrade_ogc_fid_seq'::regclass);
--
--- Name: lansyta ogc_fid; Type: DEFAULT; Schema: postgis; Owner: webmap_import
+-- Name: atervatningsavtal ogc_fid; Type: DEFAULT; Schema: sks; Owner: geodata
--
-ALTER TABLE ONLY postgis.lansyta ALTER COLUMN ogc_fid SET DEFAULT nextval('postgis.lansyta_ogc_fid_seq'::regclass);
+ALTER TABLE ONLY sks.atervatningsavtal ALTER COLUMN ogc_fid SET DEFAULT nextval('sks.atervatningsavtal_ogc_fid_seq'::regclass);
--
--- Name: mrr:bearbetningskoncessioner_applied ogc_fid; Type: DEFAULT; Schema: postgis; Owner: webmap_import
+-- Name: avverk_anmald ogc_fid; Type: DEFAULT; Schema: sks; Owner: geodata
--
-ALTER TABLE ONLY postgis."mrr:bearbetningskoncessioner_applied" ALTER COLUMN ogc_fid SET DEFAULT nextval('postgis."mrr:bearbetningskoncessioner_applied_ogc_fid_seq"'::regclass);
+ALTER TABLE ONLY sks.avverk_anmald ALTER COLUMN ogc_fid SET DEFAULT nextval('sks.avverk_anmald_ogc_fid_seq'::regclass);
--
--- Name: mrr:bearbetningskoncessioner_approved ogc_fid; Type: DEFAULT; Schema: postgis; Owner: webmap_import
+-- Name: avverk_utford ogc_fid; Type: DEFAULT; Schema: sks; Owner: geodata
--
-ALTER TABLE ONLY postgis."mrr:bearbetningskoncessioner_approved" ALTER COLUMN ogc_fid SET DEFAULT nextval('postgis."mrr:bearbetningskoncessioner_approved_ogc_fid_seq"'::regclass);
+ALTER TABLE ONLY sks.avverk_utford ALTER COLUMN ogc_fid SET DEFAULT nextval('sks.avverk_utford_ogc_fid_seq'::regclass);
--
--- Name: mrr:markanvisningar ogc_fid; Type: DEFAULT; Schema: postgis; Owner: webmap_import
+-- Name: naturvarde ogc_fid; Type: DEFAULT; Schema: sks; Owner: geodata
--
-ALTER TABLE ONLY postgis."mrr:markanvisningar" ALTER COLUMN ogc_fid SET DEFAULT nextval('postgis."mrr:markanvisningar_ogc_fid_seq"'::regclass);
+ALTER TABLE ONLY sks.naturvarde ALTER COLUMN ogc_fid SET DEFAULT nextval('sks.naturvarde_ogc_fid_seq'::regclass);
--
--- Name: mrr:mineral_applied ogc_fid; Type: DEFAULT; Schema: postgis; Owner: webmap_import
+-- Name: naturvardsavtal ogc_fid; Type: DEFAULT; Schema: sks; Owner: geodata
--
-ALTER TABLE ONLY postgis."mrr:mineral_applied" ALTER COLUMN ogc_fid SET DEFAULT nextval('postgis."mrr:mineral_applied_ogc_fid_seq"'::regclass);
+ALTER TABLE ONLY sks.naturvardsavtal ALTER COLUMN ogc_fid SET DEFAULT nextval('sks.naturvardsavtal_ogc_fid_seq'::regclass);
--
--- Name: mrr:mineral_approved ogc_fid; Type: DEFAULT; Schema: postgis; Owner: webmap_import
+-- Name: nyckelbiotop ogc_fid; Type: DEFAULT; Schema: sks; Owner: geodata
--
-ALTER TABLE ONLY postgis."mrr:mineral_approved" ALTER COLUMN ogc_fid SET DEFAULT nextval('postgis."mrr:mineral_approved_ogc_fid_seq"'::regclass);
+ALTER TABLE ONLY sks.nyckelbiotop ALTER COLUMN ogc_fid SET DEFAULT nextval('sks.nyckelbiotop_ogc_fid_seq'::regclass);
--
--- Name: mrr:olja_gas_diamant_applied ogc_fid; Type: DEFAULT; Schema: postgis; Owner: webmap_import
+-- Name: nyckelbiotop_storskogsbruk ogc_fid; Type: DEFAULT; Schema: sks; Owner: geodata
--
-ALTER TABLE ONLY postgis."mrr:olja_gas_diamant_applied" ALTER COLUMN ogc_fid SET DEFAULT nextval('postgis."mrr:olja_gas_diamant_applied_ogc_fid_seq"'::regclass);
+ALTER TABLE ONLY sks.nyckelbiotop_storskogsbruk ALTER COLUMN ogc_fid SET DEFAULT nextval('sks.nyckelbiotop_storskogsbruk_ogc_fid_seq'::regclass);
--
--- Name: mrr:olja_gas_diamant_approved ogc_fid; Type: DEFAULT; Schema: postgis; Owner: webmap_import
+-- Name: sumpskog ogc_fid; Type: DEFAULT; Schema: sks; Owner: geodata
--
-ALTER TABLE ONLY postgis."mrr:olja_gas_diamant_approved" ALTER COLUMN ogc_fid SET DEFAULT nextval('postgis."mrr:olja_gas_diamant_approved_ogc_fid_seq"'::regclass);
+ALTER TABLE ONLY sks.sumpskog ALTER COLUMN ogc_fid SET DEFAULT nextval('sks.sumpskog_ogc_fid_seq'::regclass);
--
--- Name: mrr:torvkoncessioner ogc_fid; Type: DEFAULT; Schema: postgis; Owner: webmap_import
+-- Name: ledningar ogc_fid; Type: DEFAULT; Schema: svk; Owner: geodata
--
-ALTER TABLE ONLY postgis."mrr:torvkoncessioner" ALTER COLUMN ogc_fid SET DEFAULT nextval('postgis."mrr:torvkoncessioner_ogc_fid_seq"'::regclass);
+ALTER TABLE ONLY svk.ledningar ALTER COLUMN ogc_fid SET DEFAULT nextval('svk.ledningar_ogc_fid_seq'::regclass);
--
--- Name: sks:AvverkAnm ogc_fid; Type: DEFAULT; Schema: postgis; Owner: webmap_import
+-- Name: stationsomraden ogc_fid; Type: DEFAULT; Schema: svk; Owner: geodata
--
-ALTER TABLE ONLY postgis."sks:AvverkAnm" ALTER COLUMN ogc_fid SET DEFAULT nextval('postgis."sks:AvverkAnm_ogc_fid_seq"'::regclass);
+ALTER TABLE ONLY svk.stationsomraden ALTER COLUMN ogc_fid SET DEFAULT nextval('svk.stationsomraden_ogc_fid_seq'::regclass);
--
--- Name: sks:UtfordAvverk ogc_fid; Type: DEFAULT; Schema: postgis; Owner: webmap_import
+-- Name: stolpar ogc_fid; Type: DEFAULT; Schema: svk; Owner: geodata
--
-ALTER TABLE ONLY postgis."sks:UtfordAvverk" ALTER COLUMN ogc_fid SET DEFAULT nextval('postgis."sks:UtfordAvverk_ogc_fid_seq"'::regclass);
+ALTER TABLE ONLY svk.stolpar ALTER COLUMN ogc_fid SET DEFAULT nextval('svk.stolpar_ogc_fid_seq'::regclass);
--
--- Name: vbk:havsbaserad_vindkraft ogc_fid; Type: DEFAULT; Schema: postgis; Owner: webmap_import
+-- Name: transmissionsnatsprojekt ogc_fid; Type: DEFAULT; Schema: svk; Owner: geodata
--
-ALTER TABLE ONLY postgis."vbk:havsbaserad_vindkraft" ALTER COLUMN ogc_fid SET DEFAULT nextval('postgis."vbk:havsbaserad_vindkraft_ogc_fid_seq"'::regclass);
+ALTER TABLE ONLY svk.transmissionsnatsprojekt ALTER COLUMN ogc_fid SET DEFAULT nextval('svk.transmissionsnatsprojekt_ogc_fid_seq'::regclass);
--
--- Name: vbk:projekteringsomraden ogc_fid; Type: DEFAULT; Schema: postgis; Owner: webmap_import
+-- Name: havsbaserad_vindkraft ogc_fid; Type: DEFAULT; Schema: vbk; Owner: geodata
--
-ALTER TABLE ONLY postgis."vbk:projekteringsomraden" ALTER COLUMN ogc_fid SET DEFAULT nextval('postgis."vbk:projekteringsomraden_ogc_fid_seq"'::regclass);
+ALTER TABLE ONLY vbk.havsbaserad_vindkraft ALTER COLUMN ogc_fid SET DEFAULT nextval('vbk.havsbaserad_vindkraft_ogc_fid_seq'::regclass);
--
--- Name: vbk:vindkraftverk ogc_fid; Type: DEFAULT; Schema: postgis; Owner: webmap_import
+-- Name: projekteringsomraden ogc_fid; Type: DEFAULT; Schema: vbk; Owner: geodata
--
-ALTER TABLE ONLY postgis."vbk:vindkraftverk" ALTER COLUMN ogc_fid SET DEFAULT nextval('postgis."vbk:vindkraftverk_ogc_fid_seq"'::regclass);
+ALTER TABLE ONLY vbk.projekteringsomraden ALTER COLUMN ogc_fid SET DEFAULT nextval('vbk.projekteringsomraden_ogc_fid_seq'::regclass);
--
--- Name: kommunyta kommunyta_kommunkod_key; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: vindkraftverk ogc_fid; Type: DEFAULT; Schema: vbk; Owner: geodata
--
-ALTER TABLE ONLY postgis.kommunyta
+ALTER TABLE ONLY vbk.vindkraftverk ALTER COLUMN ogc_fid SET DEFAULT nextval('vbk.vindkraftverk_ogc_fid_seq'::regclass);
+
+
+--
+-- Name: kommunyta kommunyta_kommunkod_key; Type: CONSTRAINT; Schema: lm_topo250; Owner: geodata
+--
+
+ALTER TABLE ONLY lm_topo250.kommunyta
ADD CONSTRAINT kommunyta_kommunkod_key UNIQUE (kommunkod);
--
--- Name: kommunyta kommunyta_objektidentitet_key; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: kommunyta kommunyta_objektidentitet_key; Type: CONSTRAINT; Schema: lm_topo250; Owner: geodata
--
-ALTER TABLE ONLY postgis.kommunyta
+ALTER TABLE ONLY lm_topo250.kommunyta
ADD CONSTRAINT kommunyta_objektidentitet_key UNIQUE (objektidentitet);
--
--- Name: kommunyta kommunyta_pkey; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: kommunyta kommunyta_pkey; Type: CONSTRAINT; Schema: lm_topo250; Owner: geodata
--
-ALTER TABLE ONLY postgis.kommunyta
+ALTER TABLE ONLY lm_topo250.kommunyta
ADD CONSTRAINT kommunyta_pkey PRIMARY KEY (ogc_fid);
--
--- Name: lansyta lansyta_lanskod_key; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: lansyta lansyta_lanskod_key; Type: CONSTRAINT; Schema: lm_topo250; Owner: geodata
--
-ALTER TABLE ONLY postgis.lansyta
+ALTER TABLE ONLY lm_topo250.lansyta
ADD CONSTRAINT lansyta_lanskod_key UNIQUE (lanskod);
--
--- Name: lansyta lansyta_objektidentitet_key; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: lansyta lansyta_objektidentitet_key; Type: CONSTRAINT; Schema: lm_topo250; Owner: geodata
--
-ALTER TABLE ONLY postgis.lansyta
+ALTER TABLE ONLY lm_topo250.lansyta
ADD CONSTRAINT lansyta_objektidentitet_key UNIQUE (objektidentitet);
--
--- Name: lansyta lansyta_pkey; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: lansyta lansyta_pkey; Type: CONSTRAINT; Schema: lm_topo250; Owner: geodata
--
-ALTER TABLE ONLY postgis.lansyta
+ALTER TABLE ONLY lm_topo250.lansyta
ADD CONSTRAINT lansyta_pkey PRIMARY KEY (ogc_fid);
--
--- Name: mrr:bearbetningskoncessioner_applied mrr:bearbetningskoncessioner_applied_DiaryNr_key; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: pagaende_naturreservatsbildning pagaende_naturreservatsbildning_pkey; Type: CONSTRAINT; Schema: lst; Owner: geodata
+--
+
+ALTER TABLE ONLY lst.pagaende_naturreservatsbildning
+ ADD CONSTRAINT pagaende_naturreservatsbildning_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: riksintresse_obruten_kust riksintresse_obruten_kust_pkey; Type: CONSTRAINT; Schema: lst; Owner: geodata
+--
+
+ALTER TABLE ONLY lst.riksintresse_obruten_kust
+ ADD CONSTRAINT riksintresse_obruten_kust_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: riksintresse_obrutet_fjall riksintresse_obrutet_fjall_ORIGINALID_key; Type: CONSTRAINT; Schema: lst; Owner: geodata
+--
+
+ALTER TABLE ONLY lst.riksintresse_obrutet_fjall
+ ADD CONSTRAINT "riksintresse_obrutet_fjall_ORIGINALID_key" UNIQUE ("ORIGINALID");
+
+
+--
+-- Name: riksintresse_obrutet_fjall riksintresse_obrutet_fjall_pkey; Type: CONSTRAINT; Schema: lst; Owner: geodata
+--
+
+ALTER TABLE ONLY lst.riksintresse_obrutet_fjall
+ ADD CONSTRAINT riksintresse_obrutet_fjall_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: riksintresse_rorligt_friluftsliv riksintresse_rorligt_friluftsliv_pkey; Type: CONSTRAINT; Schema: lst; Owner: geodata
+--
+
+ALTER TABLE ONLY lst.riksintresse_rorligt_friluftsliv
+ ADD CONSTRAINT riksintresse_rorligt_friluftsliv_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: riksintresse_skyddade_vattendrag riksintresse_skyddade_vattendrag_ORIGINALID_key; Type: CONSTRAINT; Schema: lst; Owner: geodata
+--
+
+ALTER TABLE ONLY lst.riksintresse_skyddade_vattendrag
+ ADD CONSTRAINT "riksintresse_skyddade_vattendrag_ORIGINALID_key" UNIQUE ("ORIGINALID");
+
+
+--
+-- Name: riksintresse_skyddade_vattendrag riksintresse_skyddade_vattendrag_pkey; Type: CONSTRAINT; Schema: lst; Owner: geodata
+--
+
+ALTER TABLE ONLY lst.riksintresse_skyddade_vattendrag
+ ADD CONSTRAINT riksintresse_skyddade_vattendrag_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: dammar dammar_DammID_key; Type: CONSTRAINT; Schema: misc; Owner: geodata
+--
+
+ALTER TABLE ONLY misc.dammar
+ ADD CONSTRAINT "dammar_DammID_key" UNIQUE ("DammID");
+
+
+--
+-- Name: dammar dammar_pkey; Type: CONSTRAINT; Schema: misc; Owner: geodata
+--
+
+ALTER TABLE ONLY misc.dammar
+ ADD CONSTRAINT dammar_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: gigafactories gigafactories_pkey; Type: CONSTRAINT; Schema: misc; Owner: geodata
+--
+
+ALTER TABLE ONLY misc.gigafactories
+ ADD CONSTRAINT gigafactories_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: bearbetningskoncessioner_ansokta bearbetningskoncessioner_ansokta_diarynr_key; Type: CONSTRAINT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.bearbetningskoncessioner_ansokta
+ ADD CONSTRAINT bearbetningskoncessioner_ansokta_diarynr_key UNIQUE (diarynr);
+
+
+--
+-- Name: bearbetningskoncessioner_ansokta bearbetningskoncessioner_ansokta_name_key; Type: CONSTRAINT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.bearbetningskoncessioner_ansokta
+ ADD CONSTRAINT bearbetningskoncessioner_ansokta_name_key UNIQUE (name);
+
+
+--
+-- Name: bearbetningskoncessioner_ansokta bearbetningskoncessioner_ansokta_pkey; Type: CONSTRAINT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.bearbetningskoncessioner_ansokta
+ ADD CONSTRAINT bearbetningskoncessioner_ansokta_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: bearbetningskoncessioner_beviljade bearbetningskoncessioner_beviljade_licenceid_key; Type: CONSTRAINT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.bearbetningskoncessioner_beviljade
+ ADD CONSTRAINT bearbetningskoncessioner_beviljade_licenceid_key UNIQUE (licenceid);
+
+
+--
+-- Name: bearbetningskoncessioner_beviljade bearbetningskoncessioner_beviljade_name_key; Type: CONSTRAINT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.bearbetningskoncessioner_beviljade
+ ADD CONSTRAINT bearbetningskoncessioner_beviljade_name_key UNIQUE (name);
+
+
+--
+-- Name: bearbetningskoncessioner_beviljade bearbetningskoncessioner_beviljade_pkey; Type: CONSTRAINT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.bearbetningskoncessioner_beviljade
+ ADD CONSTRAINT bearbetningskoncessioner_beviljade_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: bearbetningskoncessioner_forfallna bearbetningskoncessioner_forfallna_name_key; Type: CONSTRAINT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.bearbetningskoncessioner_forfallna
+ ADD CONSTRAINT bearbetningskoncessioner_forfallna_name_key UNIQUE (name);
+
+
+--
+-- Name: bearbetningskoncessioner_forfallna bearbetningskoncessioner_forfallna_pkey; Type: CONSTRAINT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.bearbetningskoncessioner_forfallna
+ ADD CONSTRAINT bearbetningskoncessioner_forfallna_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: markanvisningar_bk_ansokta markanvisningar_bk_ansokta_diarynr_key; Type: CONSTRAINT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.markanvisningar_bk_ansokta
+ ADD CONSTRAINT markanvisningar_bk_ansokta_diarynr_key UNIQUE (diarynr);
+
+
+--
+-- Name: markanvisningar_bk_ansokta markanvisningar_bk_ansokta_name_key; Type: CONSTRAINT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.markanvisningar_bk_ansokta
+ ADD CONSTRAINT markanvisningar_bk_ansokta_name_key UNIQUE (name);
+
+
+--
+-- Name: markanvisningar_bk_ansokta markanvisningar_bk_ansokta_pkey; Type: CONSTRAINT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.markanvisningar_bk_ansokta
+ ADD CONSTRAINT markanvisningar_bk_ansokta_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: markanvisningar_bk_beviljade markanvisningar_bk_beviljade_licenceid_key; Type: CONSTRAINT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.markanvisningar_bk_beviljade
+ ADD CONSTRAINT markanvisningar_bk_beviljade_licenceid_key UNIQUE (licenceid);
+
+
+--
+-- Name: markanvisningar_bk_beviljade markanvisningar_bk_beviljade_pkey; Type: CONSTRAINT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.markanvisningar_bk_beviljade
+ ADD CONSTRAINT markanvisningar_bk_beviljade_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: ut_diamant_ansokta ut_diamant_ansokta_diarynr_key; Type: CONSTRAINT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.ut_diamant_ansokta
+ ADD CONSTRAINT ut_diamant_ansokta_diarynr_key UNIQUE (diarynr);
+
+
+--
+-- Name: ut_diamant_ansokta ut_diamant_ansokta_name_key; Type: CONSTRAINT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.ut_diamant_ansokta
+ ADD CONSTRAINT ut_diamant_ansokta_name_key UNIQUE (name);
+
+
+--
+-- Name: ut_diamant_ansokta ut_diamant_ansokta_pkey; Type: CONSTRAINT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.ut_diamant_ansokta
+ ADD CONSTRAINT ut_diamant_ansokta_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: ut_diamant_beviljade ut_diamant_beviljade_diarynr_key; Type: CONSTRAINT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.ut_diamant_beviljade
+ ADD CONSTRAINT ut_diamant_beviljade_diarynr_key UNIQUE (diarynr);
+
+
+--
+-- Name: ut_diamant_beviljade ut_diamant_beviljade_licenceid_key; Type: CONSTRAINT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.ut_diamant_beviljade
+ ADD CONSTRAINT ut_diamant_beviljade_licenceid_key UNIQUE (licenceid);
+
+
+--
+-- Name: ut_diamant_beviljade ut_diamant_beviljade_name_key; Type: CONSTRAINT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.ut_diamant_beviljade
+ ADD CONSTRAINT ut_diamant_beviljade_name_key UNIQUE (name);
+
+
+--
+-- Name: ut_diamant_beviljade ut_diamant_beviljade_pkey; Type: CONSTRAINT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.ut_diamant_beviljade
+ ADD CONSTRAINT ut_diamant_beviljade_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: ut_diamant_forbud ut_diamant_forbud_licenceid_key; Type: CONSTRAINT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.ut_diamant_forbud
+ ADD CONSTRAINT ut_diamant_forbud_licenceid_key UNIQUE (licenceid);
+
+
+--
+-- Name: ut_diamant_forbud ut_diamant_forbud_name_key; Type: CONSTRAINT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.ut_diamant_forbud
+ ADD CONSTRAINT ut_diamant_forbud_name_key UNIQUE (name);
+
+
+--
+-- Name: ut_diamant_forbud ut_diamant_forbud_pkey; Type: CONSTRAINT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.ut_diamant_forbud
+ ADD CONSTRAINT ut_diamant_forbud_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: ut_metaller_industrimineral_ansokta ut_metaller_industrimineral_ansokta_diarynr_key; Type: CONSTRAINT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.ut_metaller_industrimineral_ansokta
+ ADD CONSTRAINT ut_metaller_industrimineral_ansokta_diarynr_key UNIQUE (diarynr);
+
+
+--
+-- Name: ut_metaller_industrimineral_ansokta ut_metaller_industrimineral_ansokta_pkey; Type: CONSTRAINT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.ut_metaller_industrimineral_ansokta
+ ADD CONSTRAINT ut_metaller_industrimineral_ansokta_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: ut_metaller_industrimineral_beviljade ut_metaller_industrimineral_beviljade_diarynr_key; Type: CONSTRAINT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.ut_metaller_industrimineral_beviljade
+ ADD CONSTRAINT ut_metaller_industrimineral_beviljade_diarynr_key UNIQUE (diarynr);
+
+
+--
+-- Name: ut_metaller_industrimineral_beviljade ut_metaller_industrimineral_beviljade_licenceid_key; Type: CONSTRAINT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.ut_metaller_industrimineral_beviljade
+ ADD CONSTRAINT ut_metaller_industrimineral_beviljade_licenceid_key UNIQUE (licenceid);
+
+
+--
+-- Name: ut_metaller_industrimineral_beviljade ut_metaller_industrimineral_beviljade_name_key; Type: CONSTRAINT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.ut_metaller_industrimineral_beviljade
+ ADD CONSTRAINT ut_metaller_industrimineral_beviljade_name_key UNIQUE (name);
+
+
+--
+-- Name: ut_metaller_industrimineral_beviljade ut_metaller_industrimineral_beviljade_pkey; Type: CONSTRAINT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.ut_metaller_industrimineral_beviljade
+ ADD CONSTRAINT ut_metaller_industrimineral_beviljade_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: ut_metaller_industrimineral_forbud ut_metaller_industrimineral_forbud_licenceid_key; Type: CONSTRAINT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.ut_metaller_industrimineral_forbud
+ ADD CONSTRAINT ut_metaller_industrimineral_forbud_licenceid_key UNIQUE (licenceid);
+
+
+--
+-- Name: ut_metaller_industrimineral_forbud ut_metaller_industrimineral_forbud_name_key; Type: CONSTRAINT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.ut_metaller_industrimineral_forbud
+ ADD CONSTRAINT ut_metaller_industrimineral_forbud_name_key UNIQUE (name);
+
+
+--
+-- Name: ut_metaller_industrimineral_forbud ut_metaller_industrimineral_forbud_pkey; Type: CONSTRAINT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.ut_metaller_industrimineral_forbud
+ ADD CONSTRAINT ut_metaller_industrimineral_forbud_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: ut_metaller_industrimineral_forfallna ut_metaller_industrimineral_forfallna_licenceid_key; Type: CONSTRAINT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.ut_metaller_industrimineral_forfallna
+ ADD CONSTRAINT ut_metaller_industrimineral_forfallna_licenceid_key UNIQUE (licenceid);
+
+
+--
+-- Name: ut_metaller_industrimineral_forfallna ut_metaller_industrimineral_forfallna_pkey; Type: CONSTRAINT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.ut_metaller_industrimineral_forfallna
+ ADD CONSTRAINT ut_metaller_industrimineral_forfallna_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: ut_olja_gas_diamant_forfallna ut_olja_gas_diamant_forfallna_licenceid_key; Type: CONSTRAINT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.ut_olja_gas_diamant_forfallna
+ ADD CONSTRAINT ut_olja_gas_diamant_forfallna_licenceid_key UNIQUE (licenceid);
+
+
+--
+-- Name: ut_olja_gas_diamant_forfallna ut_olja_gas_diamant_forfallna_pkey; Type: CONSTRAINT; Schema: mrr; Owner: geodata
+--
+
+ALTER TABLE ONLY mrr.ut_olja_gas_diamant_forfallna
+ ADD CONSTRAINT ut_olja_gas_diamant_forfallna_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: naturvardsavtal naturvardsavtal_pkey; Type: CONSTRAINT; Schema: nvk; Owner: geodata
+--
+
+ALTER TABLE ONLY nvk.naturvardsavtal
+ ADD CONSTRAINT naturvardsavtal_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: riksintresse_friluftsliv riksintresse_friluftsliv_OMRADESNR_key; Type: CONSTRAINT; Schema: nvk; Owner: geodata
+--
+
+ALTER TABLE ONLY nvk.riksintresse_friluftsliv
+ ADD CONSTRAINT "riksintresse_friluftsliv_OMRADESNR_key" UNIQUE ("OMRADESNR");
+
+
+--
+-- Name: riksintresse_friluftsliv riksintresse_friluftsliv_pkey; Type: CONSTRAINT; Schema: nvk; Owner: geodata
+--
+
+ALTER TABLE ONLY nvk.riksintresse_friluftsliv
+ ADD CONSTRAINT riksintresse_friluftsliv_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: riksintresse_naturvard riksintresse_naturvard_pkey; Type: CONSTRAINT; Schema: nvk; Owner: geodata
+--
+
+ALTER TABLE ONLY nvk.riksintresse_naturvard
+ ADD CONSTRAINT riksintresse_naturvard_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: skyddsvard_statlig_skog skyddsvard_statlig_skog_pkey; Type: CONSTRAINT; Schema: nvk; Owner: geodata
+--
+
+ALTER TABLE ONLY nvk.skyddsvard_statlig_skog
+ ADD CONSTRAINT skyddsvard_statlig_skog_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: Biosfarsomraden Biosfarsomraden_NAMN_key; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Biosfarsomraden"
+ ADD CONSTRAINT "Biosfarsomraden_NAMN_key" UNIQUE ("NAMN");
+
+
+--
+-- Name: Biosfarsomraden Biosfarsomraden_pkey; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Biosfarsomraden"
+ ADD CONSTRAINT "Biosfarsomraden_pkey" PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: Biotopskydd Biotopskydd_Beteckn_key; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Biotopskydd"
+ ADD CONSTRAINT "Biotopskydd_Beteckn_key" UNIQUE ("Beteckn");
+
+
+--
+-- Name: Biotopskydd Biotopskydd_Uuid_key; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Biotopskydd"
+ ADD CONSTRAINT "Biotopskydd_Uuid_key" UNIQUE ("Uuid");
+
+
+--
+-- Name: Biotopskydd Biotopskydd_pkey; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Biotopskydd"
+ ADD CONSTRAINT "Biotopskydd_pkey" PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: Djur_och_vaxtskyddsomrade Djur_och_vaxtskyddsomrade_pkey; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Djur_och_vaxtskyddsomrade"
+ ADD CONSTRAINT "Djur_och_vaxtskyddsomrade_pkey" PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: HELCOM HELCOM_BSPA_ID_key; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."HELCOM"
+ ADD CONSTRAINT "HELCOM_BSPA_ID_key" UNIQUE ("BSPA_ID");
+
+
+--
+-- Name: HELCOM HELCOM_pkey; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."HELCOM"
+ ADD CONSTRAINT "HELCOM_pkey" PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: Interimistiskt_forbud Interimistiskt_forbud_NVRID_key; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Interimistiskt_forbud"
+ ADD CONSTRAINT "Interimistiskt_forbud_NVRID_key" UNIQUE ("NVRID");
+
+
+--
+-- Name: Interimistiskt_forbud Interimistiskt_forbud_pkey; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Interimistiskt_forbud"
+ ADD CONSTRAINT "Interimistiskt_forbud_pkey" PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: Kultureservat Kultureservat_NVRID_key; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Kultureservat"
+ ADD CONSTRAINT "Kultureservat_NVRID_key" UNIQUE ("NVRID");
+
+
+--
+-- Name: Kultureservat Kultureservat_pkey; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Kultureservat"
+ ADD CONSTRAINT "Kultureservat_pkey" PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: Landskapsbildsskyddsomrade Landskapsbildsskyddsomrade_NVRID_key; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Landskapsbildsskyddsomrade"
+ ADD CONSTRAINT "Landskapsbildsskyddsomrade_NVRID_key" UNIQUE ("NVRID");
+
+
+--
+-- Name: Landskapsbildsskyddsomrade Landskapsbildsskyddsomrade_pkey; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Landskapsbildsskyddsomrade"
+ ADD CONSTRAINT "Landskapsbildsskyddsomrade_pkey" PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: Nationalpark Nationalpark_NVRID_key; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Nationalpark"
+ ADD CONSTRAINT "Nationalpark_NVRID_key" UNIQUE ("NVRID");
+
+
+--
+-- Name: Nationalpark Nationalpark_pkey; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Nationalpark"
+ ADD CONSTRAINT "Nationalpark_pkey" PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: Naturminne_punkt Naturminne_punkt_NVRID_key; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Naturminne_punkt"
+ ADD CONSTRAINT "Naturminne_punkt_NVRID_key" UNIQUE ("NVRID");
+
+
+--
+-- Name: Naturminne_punkt Naturminne_punkt_pkey; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Naturminne_punkt"
+ ADD CONSTRAINT "Naturminne_punkt_pkey" PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: Naturminne_yta Naturminne_yta_NVRID_key; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Naturminne_yta"
+ ADD CONSTRAINT "Naturminne_yta_NVRID_key" UNIQUE ("NVRID");
+
+
+--
+-- Name: Naturminne_yta Naturminne_yta_pkey; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Naturminne_yta"
+ ADD CONSTRAINT "Naturminne_yta_pkey" PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: Naturreservat Naturreservat_pkey; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Naturreservat"
+ ADD CONSTRAINT "Naturreservat_pkey" PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: Naturvardsomrade Naturvardsomrade_NVRID_key; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Naturvardsomrade"
+ ADD CONSTRAINT "Naturvardsomrade_NVRID_key" UNIQUE ("NVRID");
+
+
+--
+-- Name: Naturvardsomrade Naturvardsomrade_pkey; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Naturvardsomrade"
+ ADD CONSTRAINT "Naturvardsomrade_pkey" PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: OSPAR OSPAR_MPA_ID_key; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."OSPAR"
+ ADD CONSTRAINT "OSPAR_MPA_ID_key" UNIQUE ("MPA_ID");
+
+
+--
+-- Name: OSPAR OSPAR_MPA_NAMN_key; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."OSPAR"
+ ADD CONSTRAINT "OSPAR_MPA_NAMN_key" UNIQUE ("MPA_NAMN");
+
+
+--
+-- Name: OSPAR OSPAR_N2000_SITE_key; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."OSPAR"
+ ADD CONSTRAINT "OSPAR_N2000_SITE_key" UNIQUE ("N2000_SITE");
+
+
+--
+-- Name: OSPAR OSPAR_NAMN_N2000_key; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."OSPAR"
+ ADD CONSTRAINT "OSPAR_NAMN_N2000_key" UNIQUE ("NAMN_N2000");
+
+
+--
+-- Name: OSPAR OSPAR_pkey; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."OSPAR"
+ ADD CONSTRAINT "OSPAR_pkey" PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: Ovrigt_biotopskyddsomrade Ovrigt_biotopskyddsomrade_NVRID_key; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Ovrigt_biotopskyddsomrade"
+ ADD CONSTRAINT "Ovrigt_biotopskyddsomrade_NVRID_key" UNIQUE ("NVRID");
+
+
+--
+-- Name: Ovrigt_biotopskyddsomrade Ovrigt_biotopskyddsomrade_pkey; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Ovrigt_biotopskyddsomrade"
+ ADD CONSTRAINT "Ovrigt_biotopskyddsomrade_pkey" PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: Ramsar Ramsar_NAMN_key; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Ramsar"
+ ADD CONSTRAINT "Ramsar_NAMN_key" UNIQUE ("NAMN");
+
+
+--
+-- Name: Ramsar Ramsar_RAMSAR_ID_key; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Ramsar"
+ ADD CONSTRAINT "Ramsar_RAMSAR_ID_key" UNIQUE ("RAMSAR_ID");
+
+
+--
+-- Name: Ramsar Ramsar_pkey; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Ramsar"
+ ADD CONSTRAINT "Ramsar_pkey" PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: SCI_Rikstackande SCI_Rikstackande_SITE_CODE_key; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."SCI_Rikstackande"
+ ADD CONSTRAINT "SCI_Rikstackande_SITE_CODE_key" UNIQUE ("SITE_CODE");
+
+
+--
+-- Name: SCI_Rikstackande SCI_Rikstackande_pkey; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."SCI_Rikstackande"
+ ADD CONSTRAINT "SCI_Rikstackande_pkey" PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: SPA_Rikstackande SPA_Rikstackande_NAMN_key; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."SPA_Rikstackande"
+ ADD CONSTRAINT "SPA_Rikstackande_NAMN_key" UNIQUE ("NAMN");
+
+
+--
+-- Name: SPA_Rikstackande SPA_Rikstackande_SITE_CODE_key; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."SPA_Rikstackande"
+ ADD CONSTRAINT "SPA_Rikstackande_SITE_CODE_key" UNIQUE ("SITE_CODE");
+
+
+--
+-- Name: SPA_Rikstackande SPA_Rikstackande_pkey; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."SPA_Rikstackande"
+ ADD CONSTRAINT "SPA_Rikstackande_pkey" PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: Tilltradesforbud Tilltradesforbud_pkey; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Tilltradesforbud"
+ ADD CONSTRAINT "Tilltradesforbud_pkey" PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: Varldsarv Varldsarv_NAMN_key; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Varldsarv"
+ ADD CONSTRAINT "Varldsarv_NAMN_key" UNIQUE ("NAMN");
+
+
+--
+-- Name: Varldsarv Varldsarv_pkey; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Varldsarv"
+ ADD CONSTRAINT "Varldsarv_pkey" PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: Vattenskyddsomrade Vattenskyddsomrade_pkey; Type: CONSTRAINT; Schema: nvr; Owner: geodata
+--
+
+ALTER TABLE ONLY nvr."Vattenskyddsomrade"
+ ADD CONSTRAINT "Vattenskyddsomrade_pkey" PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: metadata metadata_schema_name_table_name_key; Type: CONSTRAINT; Schema: ogr_system_tables; Owner: geodata
+--
+
+ALTER TABLE ONLY ogr_system_tables.metadata
+ ADD CONSTRAINT metadata_schema_name_table_name_key UNIQUE (schema_name, table_name);
+
+
+--
+-- Name: layercache layercache_layername_key; Type: CONSTRAINT; Schema: public; Owner: geodata
+--
+
+ALTER TABLE ONLY public.layercache
+ ADD CONSTRAINT layercache_layername_key UNIQUE (layername);
+
+
+--
+-- Name: layercache layercache_pkey; Type: CONSTRAINT; Schema: public; Owner: geodata
+--
+
+ALTER TABLE ONLY public.layercache
+ ADD CONSTRAINT layercache_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: betesomrade betesomrade_SAMEBY_ID_key; Type: CONSTRAINT; Schema: sametinget; Owner: geodata
+--
+
+ALTER TABLE ONLY sametinget.betesomrade
+ ADD CONSTRAINT "betesomrade_SAMEBY_ID_key" UNIQUE ("SAMEBY_ID");
+
+
+--
+-- Name: betesomrade betesomrade_pkey; Type: CONSTRAINT; Schema: sametinget; Owner: geodata
+--
+
+ALTER TABLE ONLY sametinget.betesomrade
+ ADD CONSTRAINT betesomrade_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: flyttled flyttled_GlobalID_key; Type: CONSTRAINT; Schema: sametinget; Owner: geodata
+--
+
+ALTER TABLE ONLY sametinget.flyttled
+ ADD CONSTRAINT "flyttled_GlobalID_key" UNIQUE ("GlobalID");
+
+
+--
+-- Name: flyttled flyttled_pkey; Type: CONSTRAINT; Schema: sametinget; Owner: geodata
+--
+
+ALTER TABLE ONLY sametinget.flyttled
+ ADD CONSTRAINT flyttled_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: riksintresse_rennaringen riksintresse_rennaringen_GlobalID_key; Type: CONSTRAINT; Schema: sametinget; Owner: geodata
+--
+
+ALTER TABLE ONLY sametinget.riksintresse_rennaringen
+ ADD CONSTRAINT "riksintresse_rennaringen_GlobalID_key" UNIQUE ("GlobalID");
+
+
+--
+-- Name: riksintresse_rennaringen_karnomrade riksintresse_rennaringen_karnomrade_GlobalID_key; Type: CONSTRAINT; Schema: sametinget; Owner: geodata
+--
+
+ALTER TABLE ONLY sametinget.riksintresse_rennaringen_karnomrade
+ ADD CONSTRAINT "riksintresse_rennaringen_karnomrade_GlobalID_key" UNIQUE ("GlobalID");
+
+
+--
+-- Name: riksintresse_rennaringen_karnomrade riksintresse_rennaringen_karnomrade_pkey; Type: CONSTRAINT; Schema: sametinget; Owner: geodata
+--
+
+ALTER TABLE ONLY sametinget.riksintresse_rennaringen_karnomrade
+ ADD CONSTRAINT riksintresse_rennaringen_karnomrade_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: riksintresse_rennaringen riksintresse_rennaringen_pkey; Type: CONSTRAINT; Schema: sametinget; Owner: geodata
+--
+
+ALTER TABLE ONLY sametinget.riksintresse_rennaringen
+ ADD CONSTRAINT riksintresse_rennaringen_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: atervatningsavtal atervatningsavtal_Uuid_key; Type: CONSTRAINT; Schema: sks; Owner: geodata
+--
+
+ALTER TABLE ONLY sks.atervatningsavtal
+ ADD CONSTRAINT "atervatningsavtal_Uuid_key" UNIQUE ("Uuid");
+
+
+--
+-- Name: atervatningsavtal atervatningsavtal_pkey; Type: CONSTRAINT; Schema: sks; Owner: geodata
+--
+
+ALTER TABLE ONLY sks.atervatningsavtal
+ ADD CONSTRAINT atervatningsavtal_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: avverk_anmald avverk_anmald_OBJECTID_key; Type: CONSTRAINT; Schema: sks; Owner: geodata
+--
+
+ALTER TABLE ONLY sks.avverk_anmald
+ ADD CONSTRAINT "avverk_anmald_OBJECTID_key" UNIQUE ("OBJECTID");
+
+
+--
+-- Name: avverk_anmald avverk_anmald_pkey; Type: CONSTRAINT; Schema: sks; Owner: geodata
+--
+
+ALTER TABLE ONLY sks.avverk_anmald
+ ADD CONSTRAINT avverk_anmald_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: avverk_utford avverk_utford_Beteckn_key; Type: CONSTRAINT; Schema: sks; Owner: geodata
+--
+
+ALTER TABLE ONLY sks.avverk_utford
+ ADD CONSTRAINT "avverk_utford_Beteckn_key" UNIQUE ("Beteckn");
+
+
+--
+-- Name: avverk_utford avverk_utford_OBJECTID_key; Type: CONSTRAINT; Schema: sks; Owner: geodata
+--
+
+ALTER TABLE ONLY sks.avverk_utford
+ ADD CONSTRAINT "avverk_utford_OBJECTID_key" UNIQUE ("OBJECTID");
+
+
+--
+-- Name: avverk_utford avverk_utford_pkey; Type: CONSTRAINT; Schema: sks; Owner: geodata
+--
+
+ALTER TABLE ONLY sks.avverk_utford
+ ADD CONSTRAINT avverk_utford_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: naturvarde naturvarde_Beteckn_key; Type: CONSTRAINT; Schema: sks; Owner: geodata
+--
+
+ALTER TABLE ONLY sks.naturvarde
+ ADD CONSTRAINT "naturvarde_Beteckn_key" UNIQUE ("Beteckn");
+
+
+--
+-- Name: naturvarde naturvarde_ObjectId_key; Type: CONSTRAINT; Schema: sks; Owner: geodata
+--
+
+ALTER TABLE ONLY sks.naturvarde
+ ADD CONSTRAINT "naturvarde_ObjectId_key" UNIQUE ("ObjectId");
+
+
+--
+-- Name: naturvarde naturvarde_pkey; Type: CONSTRAINT; Schema: sks; Owner: geodata
+--
+
+ALTER TABLE ONLY sks.naturvarde
+ ADD CONSTRAINT naturvarde_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: naturvardsavtal naturvardsavtal_Beteckn_key; Type: CONSTRAINT; Schema: sks; Owner: geodata
+--
+
+ALTER TABLE ONLY sks.naturvardsavtal
+ ADD CONSTRAINT "naturvardsavtal_Beteckn_key" UNIQUE ("Beteckn");
+
+
+--
+-- Name: naturvardsavtal naturvardsavtal_Uuid_key; Type: CONSTRAINT; Schema: sks; Owner: geodata
+--
+
+ALTER TABLE ONLY sks.naturvardsavtal
+ ADD CONSTRAINT "naturvardsavtal_Uuid_key" UNIQUE ("Uuid");
+
+
+--
+-- Name: naturvardsavtal naturvardsavtal_pkey; Type: CONSTRAINT; Schema: sks; Owner: geodata
+--
+
+ALTER TABLE ONLY sks.naturvardsavtal
+ ADD CONSTRAINT naturvardsavtal_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: nyckelbiotop nyckelbiotop_Beteckn_key; Type: CONSTRAINT; Schema: sks; Owner: geodata
+--
+
+ALTER TABLE ONLY sks.nyckelbiotop
+ ADD CONSTRAINT "nyckelbiotop_Beteckn_key" UNIQUE ("Beteckn");
+
+
+--
+-- Name: nyckelbiotop nyckelbiotop_pkey; Type: CONSTRAINT; Schema: sks; Owner: geodata
+--
+
+ALTER TABLE ONLY sks.nyckelbiotop
+ ADD CONSTRAINT nyckelbiotop_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: nyckelbiotop_storskogsbruk nyckelbiotop_storskogsbruk_objectid_key; Type: CONSTRAINT; Schema: sks; Owner: geodata
+--
+
+ALTER TABLE ONLY sks.nyckelbiotop_storskogsbruk
+ ADD CONSTRAINT nyckelbiotop_storskogsbruk_objectid_key UNIQUE (objectid);
+
+
+--
+-- Name: nyckelbiotop_storskogsbruk nyckelbiotop_storskogsbruk_pkey; Type: CONSTRAINT; Schema: sks; Owner: geodata
+--
+
+ALTER TABLE ONLY sks.nyckelbiotop_storskogsbruk
+ ADD CONSTRAINT nyckelbiotop_storskogsbruk_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: sumpskog sumpskog_OBJECTID_key; Type: CONSTRAINT; Schema: sks; Owner: geodata
+--
+
+ALTER TABLE ONLY sks.sumpskog
+ ADD CONSTRAINT "sumpskog_OBJECTID_key" UNIQUE ("OBJECTID");
+
+
+--
+-- Name: sumpskog sumpskog_pkey; Type: CONSTRAINT; Schema: sks; Owner: geodata
+--
+
+ALTER TABLE ONLY sks.sumpskog
+ ADD CONSTRAINT sumpskog_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: ledningar ledningar_pkey; Type: CONSTRAINT; Schema: svk; Owner: geodata
+--
+
+ALTER TABLE ONLY svk.ledningar
+ ADD CONSTRAINT ledningar_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: stationsomraden stationsomraden_pkey; Type: CONSTRAINT; Schema: svk; Owner: geodata
+--
+
+ALTER TABLE ONLY svk.stationsomraden
+ ADD CONSTRAINT stationsomraden_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: stolpar stolpar_pkey; Type: CONSTRAINT; Schema: svk; Owner: geodata
+--
+
+ALTER TABLE ONLY svk.stolpar
+ ADD CONSTRAINT stolpar_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: transmissionsnatsprojekt transmissionsnatsprojekt_pkey; Type: CONSTRAINT; Schema: svk; Owner: geodata
+--
+
+ALTER TABLE ONLY svk.transmissionsnatsprojekt
+ ADD CONSTRAINT transmissionsnatsprojekt_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: havsbaserad_vindkraft havsbaserad_vindkraft_OmrID_key; Type: CONSTRAINT; Schema: vbk; Owner: geodata
+--
+
+ALTER TABLE ONLY vbk.havsbaserad_vindkraft
+ ADD CONSTRAINT "havsbaserad_vindkraft_OmrID_key" UNIQUE ("OmrID");
+
+
+--
+-- Name: havsbaserad_vindkraft havsbaserad_vindkraft_pkey; Type: CONSTRAINT; Schema: vbk; Owner: geodata
+--
+
+ALTER TABLE ONLY vbk.havsbaserad_vindkraft
+ ADD CONSTRAINT havsbaserad_vindkraft_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: projekteringsomraden projekteringsomraden_OmrID_key; Type: CONSTRAINT; Schema: vbk; Owner: geodata
+--
+
+ALTER TABLE ONLY vbk.projekteringsomraden
+ ADD CONSTRAINT "projekteringsomraden_OmrID_key" UNIQUE ("OmrID");
+
+
+--
+-- Name: projekteringsomraden projekteringsomraden_pkey; Type: CONSTRAINT; Schema: vbk; Owner: geodata
+--
+
+ALTER TABLE ONLY vbk.projekteringsomraden
+ ADD CONSTRAINT projekteringsomraden_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: vindkraftverk vindkraftverk_VerkID_key; Type: CONSTRAINT; Schema: vbk; Owner: geodata
+--
+
+ALTER TABLE ONLY vbk.vindkraftverk
+ ADD CONSTRAINT "vindkraftverk_VerkID_key" UNIQUE ("VerkID");
+
+
+--
+-- Name: vindkraftverk vindkraftverk_pkey; Type: CONSTRAINT; Schema: vbk; Owner: geodata
+--
+
+ALTER TABLE ONLY vbk.vindkraftverk
+ ADD CONSTRAINT vindkraftverk_pkey PRIMARY KEY (ogc_fid);
+
+
+--
+-- Name: kommunyta_sub_kommunkod_idx; Type: INDEX; Schema: lm_topo250; Owner: geodata
+--
+
+CREATE INDEX kommunyta_sub_kommunkod_idx ON lm_topo250.kommunyta_sub USING btree (kommunkod);
+
+
+--
+-- Name: kommunyta_sub_wkb_geometry_geom_idx; Type: INDEX; Schema: lm_topo250; Owner: geodata
+--
+
+CREATE INDEX kommunyta_sub_wkb_geometry_geom_idx ON lm_topo250.kommunyta_sub USING gist (wkb_geometry);
+
+
+--
+-- Name: kommunyta_wkb_geometry_geom_idx; Type: INDEX; Schema: lm_topo250; Owner: geodata
+--
+
+CREATE INDEX kommunyta_wkb_geometry_geom_idx ON lm_topo250.kommunyta USING gist (wkb_geometry);
+
+
+--
+-- Name: lansyta_sub_lanskod_idx; Type: INDEX; Schema: lm_topo250; Owner: geodata
--
-ALTER TABLE ONLY postgis."mrr:bearbetningskoncessioner_applied"
- ADD CONSTRAINT "mrr:bearbetningskoncessioner_applied_DiaryNr_key" UNIQUE ("DiaryNr");
+CREATE INDEX lansyta_sub_lanskod_idx ON lm_topo250.lansyta_sub USING btree (lanskod);
--
--- Name: mrr:bearbetningskoncessioner_applied mrr:bearbetningskoncessioner_applied_Name_key; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: lansyta_sub_wkb_geometry_geom_idx; Type: INDEX; Schema: lm_topo250; Owner: geodata
--
-ALTER TABLE ONLY postgis."mrr:bearbetningskoncessioner_applied"
- ADD CONSTRAINT "mrr:bearbetningskoncessioner_applied_Name_key" UNIQUE ("Name");
+CREATE INDEX lansyta_sub_wkb_geometry_geom_idx ON lm_topo250.lansyta_sub USING gist (wkb_geometry);
--
--- Name: mrr:bearbetningskoncessioner_applied mrr:bearbetningskoncessioner_applied_pkey; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: lansyta_wkb_geometry_geom_idx; Type: INDEX; Schema: lm_topo250; Owner: geodata
--
-ALTER TABLE ONLY postgis."mrr:bearbetningskoncessioner_applied"
- ADD CONSTRAINT "mrr:bearbetningskoncessioner_applied_pkey" PRIMARY KEY (ogc_fid);
+CREATE INDEX lansyta_wkb_geometry_geom_idx ON lm_topo250.lansyta USING gist (wkb_geometry);
--
--- Name: mrr:bearbetningskoncessioner_approved mrr:bearbetningskoncessioner_approved_DiaryNr_key; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: pagaende_naturreservatsbildning_wkb_geometry_geom_idx; Type: INDEX; Schema: lst; Owner: geodata
--
-ALTER TABLE ONLY postgis."mrr:bearbetningskoncessioner_approved"
- ADD CONSTRAINT "mrr:bearbetningskoncessioner_approved_DiaryNr_key" UNIQUE ("DiaryNr");
+CREATE INDEX pagaende_naturreservatsbildning_wkb_geometry_geom_idx ON lst.pagaende_naturreservatsbildning USING gist (wkb_geometry);
--
--- Name: mrr:bearbetningskoncessioner_approved mrr:bearbetningskoncessioner_approved_Name_key; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: riksintresse_obruten_kust_wkb_geometry_geom_idx; Type: INDEX; Schema: lst; Owner: geodata
--
-ALTER TABLE ONLY postgis."mrr:bearbetningskoncessioner_approved"
- ADD CONSTRAINT "mrr:bearbetningskoncessioner_approved_Name_key" UNIQUE ("Name");
+CREATE INDEX riksintresse_obruten_kust_wkb_geometry_geom_idx ON lst.riksintresse_obruten_kust USING gist (wkb_geometry);
--
--- Name: mrr:bearbetningskoncessioner_approved mrr:bearbetningskoncessioner_approved_pkey; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: riksintresse_obrutet_fjall_wkb_geometry_geom_idx; Type: INDEX; Schema: lst; Owner: geodata
--
-ALTER TABLE ONLY postgis."mrr:bearbetningskoncessioner_approved"
- ADD CONSTRAINT "mrr:bearbetningskoncessioner_approved_pkey" PRIMARY KEY (ogc_fid);
+CREATE INDEX riksintresse_obrutet_fjall_wkb_geometry_geom_idx ON lst.riksintresse_obrutet_fjall USING gist (wkb_geometry);
--
--- Name: mrr:markanvisningar mrr:markanvisningar_DiaryNr_key; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: riksintresse_rorligt_friluftsliv_wkb_geometry_geom_idx; Type: INDEX; Schema: lst; Owner: geodata
--
-ALTER TABLE ONLY postgis."mrr:markanvisningar"
- ADD CONSTRAINT "mrr:markanvisningar_DiaryNr_key" UNIQUE ("DiaryNr");
+CREATE INDEX riksintresse_rorligt_friluftsliv_wkb_geometry_geom_idx ON lst.riksintresse_rorligt_friluftsliv USING gist (wkb_geometry);
--
--- Name: mrr:markanvisningar mrr:markanvisningar_pkey; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: riksintresse_skyddade_vattendrag_wkb_geometry_geom_idx; Type: INDEX; Schema: lst; Owner: geodata
--
-ALTER TABLE ONLY postgis."mrr:markanvisningar"
- ADD CONSTRAINT "mrr:markanvisningar_pkey" PRIMARY KEY (ogc_fid);
+CREATE INDEX riksintresse_skyddade_vattendrag_wkb_geometry_geom_idx ON lst.riksintresse_skyddade_vattendrag USING gist (wkb_geometry);
--
--- Name: mrr:mineral_applied mrr:mineral_applied_DiaryNr_key; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: dammar_wkb_geometry_geom_idx; Type: INDEX; Schema: misc; Owner: geodata
--
-ALTER TABLE ONLY postgis."mrr:mineral_applied"
- ADD CONSTRAINT "mrr:mineral_applied_DiaryNr_key" UNIQUE ("DiaryNr");
+CREATE INDEX dammar_wkb_geometry_geom_idx ON misc.dammar USING gist (wkb_geometry);
--
--- Name: mrr:mineral_applied mrr:mineral_applied_Name_key; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: gigafactories_wkb_geometry_geom_idx; Type: INDEX; Schema: misc; Owner: geodata
--
-ALTER TABLE ONLY postgis."mrr:mineral_applied"
- ADD CONSTRAINT "mrr:mineral_applied_Name_key" UNIQUE ("Name");
+CREATE INDEX gigafactories_wkb_geometry_geom_idx ON misc.gigafactories USING gist (wkb_geometry);
--
--- Name: mrr:mineral_applied mrr:mineral_applied_pkey; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: bearbetningskoncessioner_ansokta_wkb_geometry_geom_idx; Type: INDEX; Schema: mrr; Owner: geodata
--
-ALTER TABLE ONLY postgis."mrr:mineral_applied"
- ADD CONSTRAINT "mrr:mineral_applied_pkey" PRIMARY KEY (ogc_fid);
+CREATE INDEX bearbetningskoncessioner_ansokta_wkb_geometry_geom_idx ON mrr.bearbetningskoncessioner_ansokta USING gist (wkb_geometry);
--
--- Name: mrr:mineral_approved mrr:mineral_approved_DiaryNr_key; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: bearbetningskoncessioner_beviljade_wkb_geometry_geom_idx; Type: INDEX; Schema: mrr; Owner: geodata
--
-ALTER TABLE ONLY postgis."mrr:mineral_approved"
- ADD CONSTRAINT "mrr:mineral_approved_DiaryNr_key" UNIQUE ("DiaryNr");
+CREATE INDEX bearbetningskoncessioner_beviljade_wkb_geometry_geom_idx ON mrr.bearbetningskoncessioner_beviljade USING gist (wkb_geometry);
--
--- Name: mrr:mineral_approved mrr:mineral_approved_LicenceID_key; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: bearbetningskoncessioner_forfallna_wkb_geometry_geom_idx; Type: INDEX; Schema: mrr; Owner: geodata
--
-ALTER TABLE ONLY postgis."mrr:mineral_approved"
- ADD CONSTRAINT "mrr:mineral_approved_LicenceID_key" UNIQUE ("LicenceID");
+CREATE INDEX bearbetningskoncessioner_forfallna_wkb_geometry_geom_idx ON mrr.bearbetningskoncessioner_forfallna USING gist (wkb_geometry);
--
--- Name: mrr:mineral_approved mrr:mineral_approved_Name_key; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: markanvisningar_bk_ansokta_wkb_geometry_geom_idx; Type: INDEX; Schema: mrr; Owner: geodata
--
-ALTER TABLE ONLY postgis."mrr:mineral_approved"
- ADD CONSTRAINT "mrr:mineral_approved_Name_key" UNIQUE ("Name");
+CREATE INDEX markanvisningar_bk_ansokta_wkb_geometry_geom_idx ON mrr.markanvisningar_bk_ansokta USING gist (wkb_geometry);
--
--- Name: mrr:mineral_approved mrr:mineral_approved_pkey; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: markanvisningar_bk_beviljade_wkb_geometry_geom_idx; Type: INDEX; Schema: mrr; Owner: geodata
--
-ALTER TABLE ONLY postgis."mrr:mineral_approved"
- ADD CONSTRAINT "mrr:mineral_approved_pkey" PRIMARY KEY (ogc_fid);
+CREATE INDEX markanvisningar_bk_beviljade_wkb_geometry_geom_idx ON mrr.markanvisningar_bk_beviljade USING gist (wkb_geometry);
--
--- Name: mrr:olja_gas_diamant_applied mrr:olja_gas_diamant_applied_DiaryNr_key; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: ut_diamant_ansokta_wkb_geometry_geom_idx; Type: INDEX; Schema: mrr; Owner: geodata
--
-ALTER TABLE ONLY postgis."mrr:olja_gas_diamant_applied"
- ADD CONSTRAINT "mrr:olja_gas_diamant_applied_DiaryNr_key" UNIQUE ("DiaryNr");
+CREATE INDEX ut_diamant_ansokta_wkb_geometry_geom_idx ON mrr.ut_diamant_ansokta USING gist (wkb_geometry);
--
--- Name: mrr:olja_gas_diamant_applied mrr:olja_gas_diamant_applied_Name_key; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: ut_diamant_beviljade_wkb_geometry_geom_idx; Type: INDEX; Schema: mrr; Owner: geodata
--
-ALTER TABLE ONLY postgis."mrr:olja_gas_diamant_applied"
- ADD CONSTRAINT "mrr:olja_gas_diamant_applied_Name_key" UNIQUE ("Name");
+CREATE INDEX ut_diamant_beviljade_wkb_geometry_geom_idx ON mrr.ut_diamant_beviljade USING gist (wkb_geometry);
--
--- Name: mrr:olja_gas_diamant_applied mrr:olja_gas_diamant_applied_pkey; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: ut_diamant_forbud_wkb_geometry_geom_idx; Type: INDEX; Schema: mrr; Owner: geodata
--
-ALTER TABLE ONLY postgis."mrr:olja_gas_diamant_applied"
- ADD CONSTRAINT "mrr:olja_gas_diamant_applied_pkey" PRIMARY KEY (ogc_fid);
+CREATE INDEX ut_diamant_forbud_wkb_geometry_geom_idx ON mrr.ut_diamant_forbud USING gist (wkb_geometry);
--
--- Name: mrr:olja_gas_diamant_approved mrr:olja_gas_diamant_approved_DiaryNr_key; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: ut_metaller_industrimineral_ansokta_wkb_geometry_geom_idx; Type: INDEX; Schema: mrr; Owner: geodata
--
-ALTER TABLE ONLY postgis."mrr:olja_gas_diamant_approved"
- ADD CONSTRAINT "mrr:olja_gas_diamant_approved_DiaryNr_key" UNIQUE ("DiaryNr");
+CREATE INDEX ut_metaller_industrimineral_ansokta_wkb_geometry_geom_idx ON mrr.ut_metaller_industrimineral_ansokta USING gist (wkb_geometry);
--
--- Name: mrr:olja_gas_diamant_approved mrr:olja_gas_diamant_approved_LicenceID_key; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: ut_metaller_industrimineral_beviljade_wkb_geometry_geom_idx; Type: INDEX; Schema: mrr; Owner: geodata
--
-ALTER TABLE ONLY postgis."mrr:olja_gas_diamant_approved"
- ADD CONSTRAINT "mrr:olja_gas_diamant_approved_LicenceID_key" UNIQUE ("LicenceID");
+CREATE INDEX ut_metaller_industrimineral_beviljade_wkb_geometry_geom_idx ON mrr.ut_metaller_industrimineral_beviljade USING gist (wkb_geometry);
--
--- Name: mrr:olja_gas_diamant_approved mrr:olja_gas_diamant_approved_Name_key; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: ut_metaller_industrimineral_forbud_wkb_geometry_geom_idx; Type: INDEX; Schema: mrr; Owner: geodata
--
-ALTER TABLE ONLY postgis."mrr:olja_gas_diamant_approved"
- ADD CONSTRAINT "mrr:olja_gas_diamant_approved_Name_key" UNIQUE ("Name");
+CREATE INDEX ut_metaller_industrimineral_forbud_wkb_geometry_geom_idx ON mrr.ut_metaller_industrimineral_forbud USING gist (wkb_geometry);
--
--- Name: mrr:olja_gas_diamant_approved mrr:olja_gas_diamant_approved_pkey; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: ut_metaller_industrimineral_forfallna_wkb_geometry_geom_idx; Type: INDEX; Schema: mrr; Owner: geodata
--
-ALTER TABLE ONLY postgis."mrr:olja_gas_diamant_approved"
- ADD CONSTRAINT "mrr:olja_gas_diamant_approved_pkey" PRIMARY KEY (ogc_fid);
+CREATE INDEX ut_metaller_industrimineral_forfallna_wkb_geometry_geom_idx ON mrr.ut_metaller_industrimineral_forfallna USING gist (wkb_geometry);
--
--- Name: mrr:torvkoncessioner mrr:torvkoncessioner_DiaryNr_key; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: ut_olja_gas_diamant_forfallna_wkb_geometry_geom_idx; Type: INDEX; Schema: mrr; Owner: geodata
--
-ALTER TABLE ONLY postgis."mrr:torvkoncessioner"
- ADD CONSTRAINT "mrr:torvkoncessioner_DiaryNr_key" UNIQUE ("DiaryNr");
+CREATE INDEX ut_olja_gas_diamant_forfallna_wkb_geometry_geom_idx ON mrr.ut_olja_gas_diamant_forfallna USING gist (wkb_geometry);
--
--- Name: mrr:torvkoncessioner mrr:torvkoncessioner_Name_key; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: naturvardsavtal_wkb_geometry_geom_idx; Type: INDEX; Schema: nvk; Owner: geodata
--
-ALTER TABLE ONLY postgis."mrr:torvkoncessioner"
- ADD CONSTRAINT "mrr:torvkoncessioner_Name_key" UNIQUE ("Name");
+CREATE INDEX naturvardsavtal_wkb_geometry_geom_idx ON nvk.naturvardsavtal USING gist (wkb_geometry);
--
--- Name: mrr:torvkoncessioner mrr:torvkoncessioner_pkey; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: riksintresse_friluftsliv_wkb_geometry_geom_idx; Type: INDEX; Schema: nvk; Owner: geodata
--
-ALTER TABLE ONLY postgis."mrr:torvkoncessioner"
- ADD CONSTRAINT "mrr:torvkoncessioner_pkey" PRIMARY KEY (ogc_fid);
+CREATE INDEX riksintresse_friluftsliv_wkb_geometry_geom_idx ON nvk.riksintresse_friluftsliv USING gist (wkb_geometry);
--
--- Name: sks:AvverkAnm sks:AvverkAnm_Beteckn_key; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: riksintresse_naturvard_wkb_geometry_geom_idx; Type: INDEX; Schema: nvk; Owner: geodata
--
-ALTER TABLE ONLY postgis."sks:AvverkAnm"
- ADD CONSTRAINT "sks:AvverkAnm_Beteckn_key" UNIQUE ("Beteckn");
+CREATE INDEX riksintresse_naturvard_wkb_geometry_geom_idx ON nvk.riksintresse_naturvard USING gist (wkb_geometry);
--
--- Name: sks:AvverkAnm sks:AvverkAnm_OBJECTID_key; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: skyddsvard_statlig_skog_wkb_geometry_geom_idx; Type: INDEX; Schema: nvk; Owner: geodata
--
-ALTER TABLE ONLY postgis."sks:AvverkAnm"
- ADD CONSTRAINT "sks:AvverkAnm_OBJECTID_key" UNIQUE ("OBJECTID");
+CREATE INDEX skyddsvard_statlig_skog_wkb_geometry_geom_idx ON nvk.skyddsvard_statlig_skog USING gist (wkb_geometry);
--
--- Name: sks:AvverkAnm sks:AvverkAnm_pkey; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: Biosfarsomraden_wkb_geometry_geom_idx; Type: INDEX; Schema: nvr; Owner: geodata
--
-ALTER TABLE ONLY postgis."sks:AvverkAnm"
- ADD CONSTRAINT "sks:AvverkAnm_pkey" PRIMARY KEY (ogc_fid);
+CREATE INDEX "Biosfarsomraden_wkb_geometry_geom_idx" ON nvr."Biosfarsomraden" USING gist (wkb_geometry);
--
--- Name: sks:UtfordAvverk sks:UtfordAvverk_Beteckn_key; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: Biotopskydd_wkb_geometry_geom_idx; Type: INDEX; Schema: nvr; Owner: geodata
--
-ALTER TABLE ONLY postgis."sks:UtfordAvverk"
- ADD CONSTRAINT "sks:UtfordAvverk_Beteckn_key" UNIQUE ("Beteckn");
+CREATE INDEX "Biotopskydd_wkb_geometry_geom_idx" ON nvr."Biotopskydd" USING gist (wkb_geometry);
--
--- Name: sks:UtfordAvverk sks:UtfordAvverk_OBJECTID_key; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: Djur_och_vaxtskyddsomrade_wkb_geometry_geom_idx; Type: INDEX; Schema: nvr; Owner: geodata
--
-ALTER TABLE ONLY postgis."sks:UtfordAvverk"
- ADD CONSTRAINT "sks:UtfordAvverk_OBJECTID_key" UNIQUE ("OBJECTID");
+CREATE INDEX "Djur_och_vaxtskyddsomrade_wkb_geometry_geom_idx" ON nvr."Djur_och_vaxtskyddsomrade" USING gist (wkb_geometry);
--
--- Name: sks:UtfordAvverk sks:UtfordAvverk_pkey; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: HELCOM_wkb_geometry_geom_idx; Type: INDEX; Schema: nvr; Owner: geodata
--
-ALTER TABLE ONLY postgis."sks:UtfordAvverk"
- ADD CONSTRAINT "sks:UtfordAvverk_pkey" PRIMARY KEY (ogc_fid);
+CREATE INDEX "HELCOM_wkb_geometry_geom_idx" ON nvr."HELCOM" USING gist (wkb_geometry);
--
--- Name: vbk:havsbaserad_vindkraft vbk:havsbaserad_vindkraft_pkey; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: Interimistiskt_forbud_wkb_geometry_geom_idx; Type: INDEX; Schema: nvr; Owner: geodata
--
-ALTER TABLE ONLY postgis."vbk:havsbaserad_vindkraft"
- ADD CONSTRAINT "vbk:havsbaserad_vindkraft_pkey" PRIMARY KEY (ogc_fid);
+CREATE INDEX "Interimistiskt_forbud_wkb_geometry_geom_idx" ON nvr."Interimistiskt_forbud" USING gist (wkb_geometry);
--
--- Name: vbk:projekteringsomraden vbk:projekteringsomraden_OmrID_key; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: Kultureservat_wkb_geometry_geom_idx; Type: INDEX; Schema: nvr; Owner: geodata
--
-ALTER TABLE ONLY postgis."vbk:projekteringsomraden"
- ADD CONSTRAINT "vbk:projekteringsomraden_OmrID_key" UNIQUE ("OmrID");
+CREATE INDEX "Kultureservat_wkb_geometry_geom_idx" ON nvr."Kultureservat" USING gist (wkb_geometry);
--
--- Name: vbk:projekteringsomraden vbk:projekteringsomraden_pkey; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: Landskapsbildsskyddsomrade_wkb_geometry_geom_idx; Type: INDEX; Schema: nvr; Owner: geodata
--
-ALTER TABLE ONLY postgis."vbk:projekteringsomraden"
- ADD CONSTRAINT "vbk:projekteringsomraden_pkey" PRIMARY KEY (ogc_fid);
+CREATE INDEX "Landskapsbildsskyddsomrade_wkb_geometry_geom_idx" ON nvr."Landskapsbildsskyddsomrade" USING gist (wkb_geometry);
--
--- Name: vbk:vindkraftverk vbk:vindkraftverk_VerkID_key; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: Nationalpark_wkb_geometry_geom_idx; Type: INDEX; Schema: nvr; Owner: geodata
--
-ALTER TABLE ONLY postgis."vbk:vindkraftverk"
- ADD CONSTRAINT "vbk:vindkraftverk_VerkID_key" UNIQUE ("VerkID");
+CREATE INDEX "Nationalpark_wkb_geometry_geom_idx" ON nvr."Nationalpark" USING gist (wkb_geometry);
--
--- Name: vbk:vindkraftverk vbk:vindkraftverk_pkey; Type: CONSTRAINT; Schema: postgis; Owner: webmap_import
+-- Name: Naturminne_punkt_wkb_geometry_geom_idx; Type: INDEX; Schema: nvr; Owner: geodata
--
-ALTER TABLE ONLY postgis."vbk:vindkraftverk"
- ADD CONSTRAINT "vbk:vindkraftverk_pkey" PRIMARY KEY (ogc_fid);
+CREATE INDEX "Naturminne_punkt_wkb_geometry_geom_idx" ON nvr."Naturminne_punkt" USING gist (wkb_geometry);
--
--- Name: kommunyta_wkb_geometry_geom_idx; Type: INDEX; Schema: postgis; Owner: webmap_import
+-- Name: Naturminne_yta_wkb_geometry_geom_idx; Type: INDEX; Schema: nvr; Owner: geodata
--
-CREATE INDEX kommunyta_wkb_geometry_geom_idx ON postgis.kommunyta USING gist (wkb_geometry);
+CREATE INDEX "Naturminne_yta_wkb_geometry_geom_idx" ON nvr."Naturminne_yta" USING gist (wkb_geometry);
--
--- Name: lansyta_wkb_geometry_geom_idx; Type: INDEX; Schema: postgis; Owner: webmap_import
+-- Name: Naturreservat_wkb_geometry_geom_idx; Type: INDEX; Schema: nvr; Owner: geodata
--
-CREATE INDEX lansyta_wkb_geometry_geom_idx ON postgis.lansyta USING gist (wkb_geometry);
+CREATE INDEX "Naturreservat_wkb_geometry_geom_idx" ON nvr."Naturreservat" USING gist (wkb_geometry);
--
--- Name: mrr:bearbetningskoncessioner_applied_wkb_geometry_geom_idx; Type: INDEX; Schema: postgis; Owner: webmap_import
+-- Name: Naturvardsomrade_wkb_geometry_geom_idx; Type: INDEX; Schema: nvr; Owner: geodata
--
-CREATE INDEX "mrr:bearbetningskoncessioner_applied_wkb_geometry_geom_idx" ON postgis."mrr:bearbetningskoncessioner_applied" USING gist (wkb_geometry);
+CREATE INDEX "Naturvardsomrade_wkb_geometry_geom_idx" ON nvr."Naturvardsomrade" USING gist (wkb_geometry);
--
--- Name: mrr:bearbetningskoncessioner_approved_wkb_geometry_geom_idx; Type: INDEX; Schema: postgis; Owner: webmap_import
+-- Name: OSPAR_wkb_geometry_geom_idx; Type: INDEX; Schema: nvr; Owner: geodata
--
-CREATE INDEX "mrr:bearbetningskoncessioner_approved_wkb_geometry_geom_idx" ON postgis."mrr:bearbetningskoncessioner_approved" USING gist (wkb_geometry);
+CREATE INDEX "OSPAR_wkb_geometry_geom_idx" ON nvr."OSPAR" USING gist (wkb_geometry);
--
--- Name: mrr:markanvisningar_wkb_geometry_geom_idx; Type: INDEX; Schema: postgis; Owner: webmap_import
+-- Name: Ovrigt_biotopskyddsomrade_wkb_geometry_geom_idx; Type: INDEX; Schema: nvr; Owner: geodata
--
-CREATE INDEX "mrr:markanvisningar_wkb_geometry_geom_idx" ON postgis."mrr:markanvisningar" USING gist (wkb_geometry);
+CREATE INDEX "Ovrigt_biotopskyddsomrade_wkb_geometry_geom_idx" ON nvr."Ovrigt_biotopskyddsomrade" USING gist (wkb_geometry);
--
--- Name: mrr:mineral_applied_wkb_geometry_geom_idx; Type: INDEX; Schema: postgis; Owner: webmap_import
+-- Name: Ramsar_wkb_geometry_geom_idx; Type: INDEX; Schema: nvr; Owner: geodata
--
-CREATE INDEX "mrr:mineral_applied_wkb_geometry_geom_idx" ON postgis."mrr:mineral_applied" USING gist (wkb_geometry);
+CREATE INDEX "Ramsar_wkb_geometry_geom_idx" ON nvr."Ramsar" USING gist (wkb_geometry);
--
--- Name: mrr:mineral_approved_wkb_geometry_geom_idx; Type: INDEX; Schema: postgis; Owner: webmap_import
+-- Name: SCI_Rikstackande_wkb_geometry_geom_idx; Type: INDEX; Schema: nvr; Owner: geodata
--
-CREATE INDEX "mrr:mineral_approved_wkb_geometry_geom_idx" ON postgis."mrr:mineral_approved" USING gist (wkb_geometry);
+CREATE INDEX "SCI_Rikstackande_wkb_geometry_geom_idx" ON nvr."SCI_Rikstackande" USING gist (wkb_geometry);
--
--- Name: mrr:olja_gas_diamant_applied_wkb_geometry_geom_idx; Type: INDEX; Schema: postgis; Owner: webmap_import
+-- Name: SPA_Rikstackande_wkb_geometry_geom_idx; Type: INDEX; Schema: nvr; Owner: geodata
--
-CREATE INDEX "mrr:olja_gas_diamant_applied_wkb_geometry_geom_idx" ON postgis."mrr:olja_gas_diamant_applied" USING gist (wkb_geometry);
+CREATE INDEX "SPA_Rikstackande_wkb_geometry_geom_idx" ON nvr."SPA_Rikstackande" USING gist (wkb_geometry);
--
--- Name: mrr:olja_gas_diamant_approved_wkb_geometry_geom_idx; Type: INDEX; Schema: postgis; Owner: webmap_import
+-- Name: Tilltradesforbud_wkb_geometry_geom_idx; Type: INDEX; Schema: nvr; Owner: geodata
--
-CREATE INDEX "mrr:olja_gas_diamant_approved_wkb_geometry_geom_idx" ON postgis."mrr:olja_gas_diamant_approved" USING gist (wkb_geometry);
+CREATE INDEX "Tilltradesforbud_wkb_geometry_geom_idx" ON nvr."Tilltradesforbud" USING gist (wkb_geometry);
--
--- Name: mrr:torvkoncessioner_wkb_geometry_geom_idx; Type: INDEX; Schema: postgis; Owner: webmap_import
+-- Name: Varldsarv_wkb_geometry_geom_idx; Type: INDEX; Schema: nvr; Owner: geodata
--
-CREATE INDEX "mrr:torvkoncessioner_wkb_geometry_geom_idx" ON postgis."mrr:torvkoncessioner" USING gist (wkb_geometry);
+CREATE INDEX "Varldsarv_wkb_geometry_geom_idx" ON nvr."Varldsarv" USING gist (wkb_geometry);
--
--- Name: sks:AvverkAnm_wkb_geometry_geom_idx; Type: INDEX; Schema: postgis; Owner: webmap_import
+-- Name: Vattenskyddsomrade_wkb_geometry_geom_idx; Type: INDEX; Schema: nvr; Owner: geodata
--
-CREATE INDEX "sks:AvverkAnm_wkb_geometry_geom_idx" ON postgis."sks:AvverkAnm" USING gist (wkb_geometry);
+CREATE INDEX "Vattenskyddsomrade_wkb_geometry_geom_idx" ON nvr."Vattenskyddsomrade" USING gist (wkb_geometry);
--
--- Name: sks:UtfordAvverk_wkb_geometry_geom_idx; Type: INDEX; Schema: postgis; Owner: webmap_import
+-- Name: betesomrade_wkb_geometry_geom_idx; Type: INDEX; Schema: sametinget; Owner: geodata
--
-CREATE INDEX "sks:UtfordAvverk_wkb_geometry_geom_idx" ON postgis."sks:UtfordAvverk" USING gist (wkb_geometry);
+CREATE INDEX betesomrade_wkb_geometry_geom_idx ON sametinget.betesomrade USING gist (wkb_geometry);
--
--- Name: vbk:havsbaserad_vindkraft_wkb_geometry_geom_idx; Type: INDEX; Schema: postgis; Owner: webmap_import
+-- Name: flyttled_wkb_geometry_geom_idx; Type: INDEX; Schema: sametinget; Owner: geodata
--
-CREATE INDEX "vbk:havsbaserad_vindkraft_wkb_geometry_geom_idx" ON postgis."vbk:havsbaserad_vindkraft" USING gist (wkb_geometry);
+CREATE INDEX flyttled_wkb_geometry_geom_idx ON sametinget.flyttled USING gist (wkb_geometry);
--
--- Name: vbk:projekteringsomraden_wkb_geometry_geom_idx; Type: INDEX; Schema: postgis; Owner: webmap_import
+-- Name: riksintresse_rennaringen_karnomrade_wkb_geometry_geom_idx; Type: INDEX; Schema: sametinget; Owner: geodata
--
-CREATE INDEX "vbk:projekteringsomraden_wkb_geometry_geom_idx" ON postgis."vbk:projekteringsomraden" USING gist (wkb_geometry);
+CREATE INDEX riksintresse_rennaringen_karnomrade_wkb_geometry_geom_idx ON sametinget.riksintresse_rennaringen_karnomrade USING gist (wkb_geometry);
--
--- Name: vbk:vindkraftverk_wkb_geometry_geom_idx; Type: INDEX; Schema: postgis; Owner: webmap_import
+-- Name: riksintresse_rennaringen_wkb_geometry_geom_idx; Type: INDEX; Schema: sametinget; Owner: geodata
--
-CREATE INDEX "vbk:vindkraftverk_wkb_geometry_geom_idx" ON postgis."vbk:vindkraftverk" USING gist (wkb_geometry);
+CREATE INDEX riksintresse_rennaringen_wkb_geometry_geom_idx ON sametinget.riksintresse_rennaringen USING gist (wkb_geometry);
--
--- Name: DATABASE webmap; Type: ACL; Schema: -; Owner: postgres
+-- Name: atervatningsavtal_wkb_geometry_geom_idx; Type: INDEX; Schema: sks; Owner: geodata
--
-GRANT CONNECT ON DATABASE webmap TO webmap_import;
-GRANT CONNECT ON DATABASE webmap TO webmap_guest;
+CREATE INDEX atervatningsavtal_wkb_geometry_geom_idx ON sks.atervatningsavtal USING gist (wkb_geometry);
--
--- Name: SCHEMA postgis; Type: ACL; Schema: -; Owner: postgres
+-- Name: avverk_anmald_wkb_geometry_geom_idx; Type: INDEX; Schema: sks; Owner: geodata
--
-GRANT USAGE ON SCHEMA postgis TO webmap_import;
-GRANT USAGE ON SCHEMA postgis TO webmap_guest;
+CREATE INDEX avverk_anmald_wkb_geometry_geom_idx ON sks.avverk_anmald USING gist (wkb_geometry);
--
--- Name: TABLE geography_columns; Type: ACL; Schema: postgis; Owner: postgres
+-- Name: avverk_utford_wkb_geometry_geom_idx; Type: INDEX; Schema: sks; Owner: geodata
--
-GRANT SELECT ON TABLE postgis.geography_columns TO webmap_guest;
+CREATE INDEX avverk_utford_wkb_geometry_geom_idx ON sks.avverk_utford USING gist (wkb_geometry);
--
--- Name: TABLE geometry_columns; Type: ACL; Schema: postgis; Owner: postgres
+-- Name: naturvarde_wkb_geometry_geom_idx; Type: INDEX; Schema: sks; Owner: geodata
--
-GRANT SELECT ON TABLE postgis.geometry_columns TO webmap_guest;
+CREATE INDEX naturvarde_wkb_geometry_geom_idx ON sks.naturvarde USING gist (wkb_geometry);
--
--- Name: TABLE kommunyta; Type: ACL; Schema: postgis; Owner: webmap_import
+-- Name: naturvardsavtal_wkb_geometry_geom_idx; Type: INDEX; Schema: sks; Owner: geodata
--
-GRANT SELECT ON TABLE postgis.kommunyta TO webmap_guest;
+CREATE INDEX naturvardsavtal_wkb_geometry_geom_idx ON sks.naturvardsavtal USING gist (wkb_geometry);
--
--- Name: SEQUENCE kommunyta_ogc_fid_seq; Type: ACL; Schema: postgis; Owner: webmap_import
+-- Name: nyckelbiotop_storskogsbruk_wkb_geometry_geom_idx; Type: INDEX; Schema: sks; Owner: geodata
--
-GRANT SELECT,USAGE ON SEQUENCE postgis.kommunyta_ogc_fid_seq TO webmap_guest;
+CREATE INDEX nyckelbiotop_storskogsbruk_wkb_geometry_geom_idx ON sks.nyckelbiotop_storskogsbruk USING gist (wkb_geometry);
--
--- Name: TABLE lansyta; Type: ACL; Schema: postgis; Owner: webmap_import
+-- Name: nyckelbiotop_wkb_geometry_geom_idx; Type: INDEX; Schema: sks; Owner: geodata
--
-GRANT SELECT ON TABLE postgis.lansyta TO webmap_guest;
+CREATE INDEX nyckelbiotop_wkb_geometry_geom_idx ON sks.nyckelbiotop USING gist (wkb_geometry);
--
--- Name: SEQUENCE lansyta_ogc_fid_seq; Type: ACL; Schema: postgis; Owner: webmap_import
+-- Name: sumpskog_wkb_geometry_geom_idx; Type: INDEX; Schema: sks; Owner: geodata
--
-GRANT SELECT,USAGE ON SEQUENCE postgis.lansyta_ogc_fid_seq TO webmap_guest;
+CREATE INDEX sumpskog_wkb_geometry_geom_idx ON sks.sumpskog USING gist (wkb_geometry);
--
--- Name: TABLE "mrr:bearbetningskoncessioner_applied"; Type: ACL; Schema: postgis; Owner: webmap_import
+-- Name: ledningar_wkb_geometry_geom_idx; Type: INDEX; Schema: svk; Owner: geodata
--
-GRANT SELECT ON TABLE postgis."mrr:bearbetningskoncessioner_applied" TO webmap_guest;
+CREATE INDEX ledningar_wkb_geometry_geom_idx ON svk.ledningar USING gist (wkb_geometry);
--
--- Name: SEQUENCE "mrr:bearbetningskoncessioner_applied_ogc_fid_seq"; Type: ACL; Schema: postgis; Owner: webmap_import
+-- Name: stationsomraden_wkb_geometry_geom_idx; Type: INDEX; Schema: svk; Owner: geodata
--
-GRANT SELECT,USAGE ON SEQUENCE postgis."mrr:bearbetningskoncessioner_applied_ogc_fid_seq" TO webmap_guest;
+CREATE INDEX stationsomraden_wkb_geometry_geom_idx ON svk.stationsomraden USING gist (wkb_geometry);
--
--- Name: TABLE "mrr:bearbetningskoncessioner_approved"; Type: ACL; Schema: postgis; Owner: webmap_import
+-- Name: stolpar_wkb_geometry_geom_idx; Type: INDEX; Schema: svk; Owner: geodata
--
-GRANT SELECT ON TABLE postgis."mrr:bearbetningskoncessioner_approved" TO webmap_guest;
+CREATE INDEX stolpar_wkb_geometry_geom_idx ON svk.stolpar USING gist (wkb_geometry);
--
--- Name: SEQUENCE "mrr:bearbetningskoncessioner_approved_ogc_fid_seq"; Type: ACL; Schema: postgis; Owner: webmap_import
+-- Name: transmissionsnatsprojekt_wkb_geometry_geom_idx; Type: INDEX; Schema: svk; Owner: geodata
--
-GRANT SELECT,USAGE ON SEQUENCE postgis."mrr:bearbetningskoncessioner_approved_ogc_fid_seq" TO webmap_guest;
+CREATE INDEX transmissionsnatsprojekt_wkb_geometry_geom_idx ON svk.transmissionsnatsprojekt USING gist (wkb_geometry);
--
--- Name: TABLE "mrr:markanvisningar"; Type: ACL; Schema: postgis; Owner: webmap_import
+-- Name: havsbaserad_vindkraft_wkb_geometry_geom_idx; Type: INDEX; Schema: vbk; Owner: geodata
--
-GRANT SELECT ON TABLE postgis."mrr:markanvisningar" TO webmap_guest;
+CREATE INDEX havsbaserad_vindkraft_wkb_geometry_geom_idx ON vbk.havsbaserad_vindkraft USING gist (wkb_geometry);
--
--- Name: SEQUENCE "mrr:markanvisningar_ogc_fid_seq"; Type: ACL; Schema: postgis; Owner: webmap_import
+-- Name: projekteringsomraden_wkb_geometry_geom_idx; Type: INDEX; Schema: vbk; Owner: geodata
--
-GRANT SELECT,USAGE ON SEQUENCE postgis."mrr:markanvisningar_ogc_fid_seq" TO webmap_guest;
+CREATE INDEX projekteringsomraden_wkb_geometry_geom_idx ON vbk.projekteringsomraden USING gist (wkb_geometry);
--
--- Name: TABLE "mrr:mineral_applied"; Type: ACL; Schema: postgis; Owner: webmap_import
+-- Name: vindkraftverk_wkb_geometry_geom_idx; Type: INDEX; Schema: vbk; Owner: geodata
--
-GRANT SELECT ON TABLE postgis."mrr:mineral_applied" TO webmap_guest;
+CREATE INDEX vindkraftverk_wkb_geometry_geom_idx ON vbk.vindkraftverk USING gist (wkb_geometry);
--
--- Name: SEQUENCE "mrr:mineral_applied_ogc_fid_seq"; Type: ACL; Schema: postgis; Owner: webmap_import
+-- Name: kommunyta kommunyta_subdivide_trigger; Type: TRIGGER; Schema: lm_topo250; Owner: geodata
--
-GRANT SELECT,USAGE ON SEQUENCE postgis."mrr:mineral_applied_ogc_fid_seq" TO webmap_guest;
+CREATE TRIGGER kommunyta_subdivide_trigger AFTER INSERT OR DELETE OR UPDATE ON lm_topo250.kommunyta FOR EACH ROW EXECUTE FUNCTION lm_topo250.kommunyta_subdivide_func();
--
--- Name: TABLE "mrr:mineral_approved"; Type: ACL; Schema: postgis; Owner: webmap_import
+-- Name: lansyta lansyta_subdivide_trigger; Type: TRIGGER; Schema: lm_topo250; Owner: geodata
--
-GRANT SELECT ON TABLE postgis."mrr:mineral_approved" TO webmap_guest;
+CREATE TRIGGER lansyta_subdivide_trigger AFTER INSERT OR DELETE OR UPDATE ON lm_topo250.lansyta FOR EACH ROW EXECUTE FUNCTION lm_topo250.lansyta_subdivide_func();
--
--- Name: SEQUENCE "mrr:mineral_approved_ogc_fid_seq"; Type: ACL; Schema: postgis; Owner: webmap_import
+-- Name: kommunyta_sub kommunyta_sub_kommunkod_fkey; Type: FK CONSTRAINT; Schema: lm_topo250; Owner: geodata
--
-GRANT SELECT,USAGE ON SEQUENCE postgis."mrr:mineral_approved_ogc_fid_seq" TO webmap_guest;
+ALTER TABLE ONLY lm_topo250.kommunyta_sub
+ ADD CONSTRAINT kommunyta_sub_kommunkod_fkey FOREIGN KEY (kommunkod) REFERENCES lm_topo250.kommunyta(kommunkod) ON DELETE CASCADE;
--
--- Name: TABLE "mrr:olja_gas_diamant_applied"; Type: ACL; Schema: postgis; Owner: webmap_import
+-- Name: lansyta_sub lansyta_sub_lanskod_fkey; Type: FK CONSTRAINT; Schema: lm_topo250; Owner: geodata
--
-GRANT SELECT ON TABLE postgis."mrr:olja_gas_diamant_applied" TO webmap_guest;
+ALTER TABLE ONLY lm_topo250.lansyta_sub
+ ADD CONSTRAINT lansyta_sub_lanskod_fkey FOREIGN KEY (lanskod) REFERENCES lm_topo250.lansyta(lanskod) ON DELETE CASCADE;
--
--- Name: SEQUENCE "mrr:olja_gas_diamant_applied_ogc_fid_seq"; Type: ACL; Schema: postgis; Owner: webmap_import
+-- Name: DATABASE geodata; Type: ACL; Schema: -; Owner: postgres
--
-GRANT SELECT,USAGE ON SEQUENCE postgis."mrr:olja_gas_diamant_applied_ogc_fid_seq" TO webmap_guest;
+GRANT CONNECT ON DATABASE geodata TO geodata;
+GRANT CONNECT ON DATABASE geodata TO guest;
--
--- Name: TABLE "mrr:olja_gas_diamant_approved"; Type: ACL; Schema: postgis; Owner: webmap_import
+-- Name: SCHEMA lm_topo250; Type: ACL; Schema: -; Owner: postgres
--
-GRANT SELECT ON TABLE postgis."mrr:olja_gas_diamant_approved" TO webmap_guest;
+GRANT USAGE ON SCHEMA lm_topo250 TO geodata;
+GRANT USAGE ON SCHEMA lm_topo250 TO guest;
--
--- Name: SEQUENCE "mrr:olja_gas_diamant_approved_ogc_fid_seq"; Type: ACL; Schema: postgis; Owner: webmap_import
+-- Name: SCHEMA lst; Type: ACL; Schema: -; Owner: postgres
--
-GRANT SELECT,USAGE ON SEQUENCE postgis."mrr:olja_gas_diamant_approved_ogc_fid_seq" TO webmap_guest;
+GRANT USAGE ON SCHEMA lst TO geodata;
+GRANT USAGE ON SCHEMA lst TO guest;
--
--- Name: TABLE "mrr:torvkoncessioner"; Type: ACL; Schema: postgis; Owner: webmap_import
+-- Name: SCHEMA misc; Type: ACL; Schema: -; Owner: postgres
--
-GRANT SELECT ON TABLE postgis."mrr:torvkoncessioner" TO webmap_guest;
+GRANT USAGE ON SCHEMA misc TO geodata;
+GRANT USAGE ON SCHEMA misc TO guest;
--
--- Name: SEQUENCE "mrr:torvkoncessioner_ogc_fid_seq"; Type: ACL; Schema: postgis; Owner: webmap_import
+-- Name: SCHEMA mrr; Type: ACL; Schema: -; Owner: postgres
--
-GRANT SELECT,USAGE ON SEQUENCE postgis."mrr:torvkoncessioner_ogc_fid_seq" TO webmap_guest;
+GRANT USAGE ON SCHEMA mrr TO geodata;
+GRANT USAGE ON SCHEMA mrr TO guest;
--
--- Name: TABLE "sks:AvverkAnm"; Type: ACL; Schema: postgis; Owner: webmap_import
+-- Name: SCHEMA nvk; Type: ACL; Schema: -; Owner: postgres
--
-GRANT SELECT ON TABLE postgis."sks:AvverkAnm" TO webmap_guest;
+GRANT USAGE ON SCHEMA nvk TO geodata;
+GRANT USAGE ON SCHEMA nvk TO guest;
--
--- Name: SEQUENCE "sks:AvverkAnm_ogc_fid_seq"; Type: ACL; Schema: postgis; Owner: webmap_import
+-- Name: SCHEMA nvr; Type: ACL; Schema: -; Owner: postgres
--
-GRANT SELECT,USAGE ON SEQUENCE postgis."sks:AvverkAnm_ogc_fid_seq" TO webmap_guest;
+GRANT USAGE ON SCHEMA nvr TO geodata;
+GRANT USAGE ON SCHEMA nvr TO guest;
--
--- Name: TABLE "sks:UtfordAvverk"; Type: ACL; Schema: postgis; Owner: webmap_import
+-- Name: SCHEMA ogr_system_tables; Type: ACL; Schema: -; Owner: postgres
--
-GRANT SELECT ON TABLE postgis."sks:UtfordAvverk" TO webmap_guest;
+GRANT USAGE ON SCHEMA ogr_system_tables TO geodata;
+GRANT USAGE ON SCHEMA ogr_system_tables TO guest;
--
--- Name: SEQUENCE "sks:UtfordAvverk_ogc_fid_seq"; Type: ACL; Schema: postgis; Owner: webmap_import
+-- Name: SCHEMA public; Type: ACL; Schema: -; Owner: pg_database_owner
--
-GRANT SELECT,USAGE ON SEQUENCE postgis."sks:UtfordAvverk_ogc_fid_seq" TO webmap_guest;
+GRANT USAGE ON SCHEMA public TO geodata;
+GRANT USAGE ON SCHEMA public TO guest;
--
--- Name: TABLE spatial_ref_sys; Type: ACL; Schema: postgis; Owner: postgres
+-- Name: SCHEMA sametinget; Type: ACL; Schema: -; Owner: postgres
--
-GRANT SELECT ON TABLE postgis.spatial_ref_sys TO webmap_guest;
+GRANT USAGE ON SCHEMA sametinget TO geodata;
+GRANT USAGE ON SCHEMA sametinget TO guest;
--
--- Name: TABLE "vbk:havsbaserad_vindkraft"; Type: ACL; Schema: postgis; Owner: webmap_import
+-- Name: SCHEMA sks; Type: ACL; Schema: -; Owner: postgres
--
-GRANT SELECT ON TABLE postgis."vbk:havsbaserad_vindkraft" TO webmap_guest;
+GRANT USAGE ON SCHEMA sks TO geodata;
+GRANT USAGE ON SCHEMA sks TO guest;
--
--- Name: SEQUENCE "vbk:havsbaserad_vindkraft_ogc_fid_seq"; Type: ACL; Schema: postgis; Owner: webmap_import
+-- Name: SCHEMA svk; Type: ACL; Schema: -; Owner: postgres
--
-GRANT SELECT,USAGE ON SEQUENCE postgis."vbk:havsbaserad_vindkraft_ogc_fid_seq" TO webmap_guest;
+GRANT USAGE ON SCHEMA svk TO geodata;
+GRANT USAGE ON SCHEMA svk TO guest;
--
--- Name: TABLE "vbk:projekteringsomraden"; Type: ACL; Schema: postgis; Owner: webmap_import
+-- Name: SCHEMA vbk; Type: ACL; Schema: -; Owner: postgres
--
-GRANT SELECT ON TABLE postgis."vbk:projekteringsomraden" TO webmap_guest;
+GRANT USAGE ON SCHEMA vbk TO geodata;
+GRANT USAGE ON SCHEMA vbk TO guest;
--
--- Name: SEQUENCE "vbk:projekteringsomraden_ogc_fid_seq"; Type: ACL; Schema: postgis; Owner: webmap_import
+-- Name: FUNCTION get_counties(public.geometry); Type: ACL; Schema: public; Owner: postgres
--
-GRANT SELECT,USAGE ON SEQUENCE postgis."vbk:projekteringsomraden_ogc_fid_seq" TO webmap_guest;
+GRANT ALL ON FUNCTION public.get_counties(public.geometry) TO geodata;
+GRANT ALL ON FUNCTION public.get_counties(public.geometry) TO guest;
--
--- Name: TABLE "vbk:vindkraftverk"; Type: ACL; Schema: postgis; Owner: webmap_import
+-- Name: FUNCTION get_municipalities(public.geometry); Type: ACL; Schema: public; Owner: postgres
--
-GRANT SELECT ON TABLE postgis."vbk:vindkraftverk" TO webmap_guest;
+GRANT ALL ON FUNCTION public.get_municipalities(public.geometry) TO geodata;
+GRANT ALL ON FUNCTION public.get_municipalities(public.geometry) TO guest;
--
--- Name: SEQUENCE "vbk:vindkraftverk_ogc_fid_seq"; Type: ACL; Schema: postgis; Owner: webmap_import
+-- Name: TABLE kommunyta; Type: ACL; Schema: lm_topo250; Owner: geodata
--
-GRANT SELECT,USAGE ON SEQUENCE postgis."vbk:vindkraftverk_ogc_fid_seq" TO webmap_guest;
+GRANT SELECT ON TABLE lm_topo250.kommunyta TO guest;
--
+-- Name: SEQUENCE kommunyta_ogc_fid_seq; Type: ACL; Schema: lm_topo250; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE lm_topo250.kommunyta_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE kommunyta_sub; Type: ACL; Schema: lm_topo250; Owner: geodata
+--
+
+GRANT SELECT ON TABLE lm_topo250.kommunyta_sub TO guest;
+
+
+--
+-- Name: SEQUENCE kommunyta_sub_ogc_fid_seq; Type: ACL; Schema: lm_topo250; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE lm_topo250.kommunyta_sub_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE lansyta; Type: ACL; Schema: lm_topo250; Owner: geodata
+--
+
+GRANT SELECT ON TABLE lm_topo250.lansyta TO guest;
+
+
+--
+-- Name: SEQUENCE lansyta_ogc_fid_seq; Type: ACL; Schema: lm_topo250; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE lm_topo250.lansyta_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE lansyta_sub; Type: ACL; Schema: lm_topo250; Owner: geodata
+--
+
+GRANT SELECT ON TABLE lm_topo250.lansyta_sub TO guest;
+
+
+--
+-- Name: SEQUENCE lansyta_sub_ogc_fid_seq; Type: ACL; Schema: lm_topo250; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE lm_topo250.lansyta_sub_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE pagaende_naturreservatsbildning; Type: ACL; Schema: lst; Owner: geodata
+--
+
+GRANT SELECT ON TABLE lst.pagaende_naturreservatsbildning TO guest;
+
+
+--
+-- Name: SEQUENCE pagaende_naturreservatsbildning_ogc_fid_seq; Type: ACL; Schema: lst; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE lst.pagaende_naturreservatsbildning_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE riksintresse_obruten_kust; Type: ACL; Schema: lst; Owner: geodata
+--
+
+GRANT SELECT ON TABLE lst.riksintresse_obruten_kust TO guest;
+
+
+--
+-- Name: SEQUENCE riksintresse_obruten_kust_ogc_fid_seq; Type: ACL; Schema: lst; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE lst.riksintresse_obruten_kust_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE riksintresse_obrutet_fjall; Type: ACL; Schema: lst; Owner: geodata
+--
+
+GRANT SELECT ON TABLE lst.riksintresse_obrutet_fjall TO guest;
+
+
+--
+-- Name: SEQUENCE riksintresse_obrutet_fjall_ogc_fid_seq; Type: ACL; Schema: lst; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE lst.riksintresse_obrutet_fjall_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE riksintresse_rorligt_friluftsliv; Type: ACL; Schema: lst; Owner: geodata
+--
+
+GRANT SELECT ON TABLE lst.riksintresse_rorligt_friluftsliv TO guest;
+
+
+--
+-- Name: SEQUENCE riksintresse_rorligt_friluftsliv_ogc_fid_seq; Type: ACL; Schema: lst; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE lst.riksintresse_rorligt_friluftsliv_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE riksintresse_skyddade_vattendrag; Type: ACL; Schema: lst; Owner: geodata
+--
+
+GRANT SELECT ON TABLE lst.riksintresse_skyddade_vattendrag TO guest;
+
+
+--
+-- Name: SEQUENCE riksintresse_skyddade_vattendrag_ogc_fid_seq; Type: ACL; Schema: lst; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE lst.riksintresse_skyddade_vattendrag_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE dammar; Type: ACL; Schema: misc; Owner: geodata
+--
+
+GRANT SELECT ON TABLE misc.dammar TO guest;
+
+
+--
+-- Name: SEQUENCE dammar_ogc_fid_seq; Type: ACL; Schema: misc; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE misc.dammar_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE gigafactories; Type: ACL; Schema: misc; Owner: geodata
+--
+
+GRANT SELECT ON TABLE misc.gigafactories TO guest;
+
+
+--
+-- Name: SEQUENCE gigafactories_ogc_fid_seq; Type: ACL; Schema: misc; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE misc.gigafactories_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE bearbetningskoncessioner_ansokta; Type: ACL; Schema: mrr; Owner: geodata
+--
+
+GRANT SELECT ON TABLE mrr.bearbetningskoncessioner_ansokta TO guest;
+
+
+--
+-- Name: SEQUENCE bearbetningskoncessioner_ansokta_ogc_fid_seq; Type: ACL; Schema: mrr; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE mrr.bearbetningskoncessioner_ansokta_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE bearbetningskoncessioner_beviljade; Type: ACL; Schema: mrr; Owner: geodata
+--
+
+GRANT SELECT ON TABLE mrr.bearbetningskoncessioner_beviljade TO guest;
+
+
+--
+-- Name: SEQUENCE bearbetningskoncessioner_beviljade_ogc_fid_seq; Type: ACL; Schema: mrr; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE mrr.bearbetningskoncessioner_beviljade_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE bearbetningskoncessioner_forfallna; Type: ACL; Schema: mrr; Owner: geodata
+--
+
+GRANT SELECT ON TABLE mrr.bearbetningskoncessioner_forfallna TO guest;
+
+
+--
+-- Name: SEQUENCE bearbetningskoncessioner_forfallna_ogc_fid_seq; Type: ACL; Schema: mrr; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE mrr.bearbetningskoncessioner_forfallna_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE markanvisningar_bk_ansokta; Type: ACL; Schema: mrr; Owner: geodata
+--
+
+GRANT SELECT ON TABLE mrr.markanvisningar_bk_ansokta TO guest;
+
+
+--
+-- Name: SEQUENCE markanvisningar_bk_ansokta_ogc_fid_seq; Type: ACL; Schema: mrr; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE mrr.markanvisningar_bk_ansokta_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE markanvisningar_bk_beviljade; Type: ACL; Schema: mrr; Owner: geodata
+--
+
+GRANT SELECT ON TABLE mrr.markanvisningar_bk_beviljade TO guest;
+
+
+--
+-- Name: SEQUENCE markanvisningar_bk_beviljade_ogc_fid_seq; Type: ACL; Schema: mrr; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE mrr.markanvisningar_bk_beviljade_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE ut_diamant_ansokta; Type: ACL; Schema: mrr; Owner: geodata
+--
+
+GRANT SELECT ON TABLE mrr.ut_diamant_ansokta TO guest;
+
+
+--
+-- Name: SEQUENCE ut_diamant_ansokta_ogc_fid_seq; Type: ACL; Schema: mrr; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE mrr.ut_diamant_ansokta_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE ut_diamant_beviljade; Type: ACL; Schema: mrr; Owner: geodata
+--
+
+GRANT SELECT ON TABLE mrr.ut_diamant_beviljade TO guest;
+
+
+--
+-- Name: SEQUENCE ut_diamant_beviljade_ogc_fid_seq; Type: ACL; Schema: mrr; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE mrr.ut_diamant_beviljade_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE ut_diamant_forbud; Type: ACL; Schema: mrr; Owner: geodata
+--
+
+GRANT SELECT ON TABLE mrr.ut_diamant_forbud TO guest;
+
+
+--
+-- Name: SEQUENCE ut_diamant_forbud_ogc_fid_seq; Type: ACL; Schema: mrr; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE mrr.ut_diamant_forbud_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE ut_metaller_industrimineral_ansokta; Type: ACL; Schema: mrr; Owner: geodata
+--
+
+GRANT SELECT ON TABLE mrr.ut_metaller_industrimineral_ansokta TO guest;
+
+
+--
+-- Name: SEQUENCE ut_metaller_industrimineral_ansokta_ogc_fid_seq; Type: ACL; Schema: mrr; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE mrr.ut_metaller_industrimineral_ansokta_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE ut_metaller_industrimineral_beviljade; Type: ACL; Schema: mrr; Owner: geodata
+--
+
+GRANT SELECT ON TABLE mrr.ut_metaller_industrimineral_beviljade TO guest;
+
+
+--
+-- Name: SEQUENCE ut_metaller_industrimineral_beviljade_ogc_fid_seq; Type: ACL; Schema: mrr; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE mrr.ut_metaller_industrimineral_beviljade_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE ut_metaller_industrimineral_forbud; Type: ACL; Schema: mrr; Owner: geodata
+--
+
+GRANT SELECT ON TABLE mrr.ut_metaller_industrimineral_forbud TO guest;
+
+
+--
+-- Name: SEQUENCE ut_metaller_industrimineral_forbud_ogc_fid_seq; Type: ACL; Schema: mrr; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE mrr.ut_metaller_industrimineral_forbud_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE ut_metaller_industrimineral_forfallna; Type: ACL; Schema: mrr; Owner: geodata
+--
+
+GRANT SELECT ON TABLE mrr.ut_metaller_industrimineral_forfallna TO guest;
+
+
+--
+-- Name: SEQUENCE ut_metaller_industrimineral_forfallna_ogc_fid_seq; Type: ACL; Schema: mrr; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE mrr.ut_metaller_industrimineral_forfallna_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE ut_olja_gas_diamant_forfallna; Type: ACL; Schema: mrr; Owner: geodata
+--
+
+GRANT SELECT ON TABLE mrr.ut_olja_gas_diamant_forfallna TO guest;
+
+
+--
+-- Name: SEQUENCE ut_olja_gas_diamant_forfallna_ogc_fid_seq; Type: ACL; Schema: mrr; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE mrr.ut_olja_gas_diamant_forfallna_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE naturvardsavtal; Type: ACL; Schema: nvk; Owner: geodata
+--
+
+GRANT SELECT ON TABLE nvk.naturvardsavtal TO guest;
+
+
+--
+-- Name: SEQUENCE naturvardsavtal_ogc_fid_seq; Type: ACL; Schema: nvk; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE nvk.naturvardsavtal_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE riksintresse_friluftsliv; Type: ACL; Schema: nvk; Owner: geodata
+--
+
+GRANT SELECT ON TABLE nvk.riksintresse_friluftsliv TO guest;
+
+
+--
+-- Name: SEQUENCE riksintresse_friluftsliv_ogc_fid_seq; Type: ACL; Schema: nvk; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE nvk.riksintresse_friluftsliv_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE riksintresse_naturvard; Type: ACL; Schema: nvk; Owner: geodata
+--
+
+GRANT SELECT ON TABLE nvk.riksintresse_naturvard TO guest;
+
+
+--
+-- Name: SEQUENCE riksintresse_naturvard_ogc_fid_seq; Type: ACL; Schema: nvk; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE nvk.riksintresse_naturvard_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE skyddsvard_statlig_skog; Type: ACL; Schema: nvk; Owner: geodata
+--
+
+GRANT SELECT ON TABLE nvk.skyddsvard_statlig_skog TO guest;
+
+
+--
+-- Name: SEQUENCE skyddsvard_statlig_skog_ogc_fid_seq; Type: ACL; Schema: nvk; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE nvk.skyddsvard_statlig_skog_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE "Biosfarsomraden"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT ON TABLE nvr."Biosfarsomraden" TO guest;
+
+
+--
+-- Name: SEQUENCE "Biosfarsomraden_ogc_fid_seq"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE nvr."Biosfarsomraden_ogc_fid_seq" TO guest;
+
+
+--
+-- Name: TABLE "Biotopskydd"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT ON TABLE nvr."Biotopskydd" TO guest;
+
+
+--
+-- Name: SEQUENCE "Biotopskydd_ogc_fid_seq"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE nvr."Biotopskydd_ogc_fid_seq" TO guest;
+
+
+--
+-- Name: TABLE "Djur_och_vaxtskyddsomrade"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT ON TABLE nvr."Djur_och_vaxtskyddsomrade" TO guest;
+
+
+--
+-- Name: SEQUENCE "Djur_och_vaxtskyddsomrade_ogc_fid_seq"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE nvr."Djur_och_vaxtskyddsomrade_ogc_fid_seq" TO guest;
+
+
+--
+-- Name: TABLE "HELCOM"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT ON TABLE nvr."HELCOM" TO guest;
+
+
+--
+-- Name: SEQUENCE "HELCOM_ogc_fid_seq"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE nvr."HELCOM_ogc_fid_seq" TO guest;
+
+
+--
+-- Name: TABLE "Interimistiskt_forbud"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT ON TABLE nvr."Interimistiskt_forbud" TO guest;
+
+
+--
+-- Name: SEQUENCE "Interimistiskt_forbud_ogc_fid_seq"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE nvr."Interimistiskt_forbud_ogc_fid_seq" TO guest;
+
+
+--
+-- Name: TABLE "Kultureservat"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT ON TABLE nvr."Kultureservat" TO guest;
+
+
+--
+-- Name: SEQUENCE "Kultureservat_ogc_fid_seq"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE nvr."Kultureservat_ogc_fid_seq" TO guest;
+
+
+--
+-- Name: TABLE "Landskapsbildsskyddsomrade"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT ON TABLE nvr."Landskapsbildsskyddsomrade" TO guest;
+
+
+--
+-- Name: SEQUENCE "Landskapsbildsskyddsomrade_ogc_fid_seq"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE nvr."Landskapsbildsskyddsomrade_ogc_fid_seq" TO guest;
+
+
+--
+-- Name: TABLE "Nationalpark"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT ON TABLE nvr."Nationalpark" TO guest;
+
+
+--
+-- Name: SEQUENCE "Nationalpark_ogc_fid_seq"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE nvr."Nationalpark_ogc_fid_seq" TO guest;
+
+
+--
+-- Name: TABLE "Naturminne_punkt"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT ON TABLE nvr."Naturminne_punkt" TO guest;
+
+
+--
+-- Name: SEQUENCE "Naturminne_punkt_ogc_fid_seq"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE nvr."Naturminne_punkt_ogc_fid_seq" TO guest;
+
+
+--
+-- Name: TABLE "Naturminne_yta"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT ON TABLE nvr."Naturminne_yta" TO guest;
+
+
+--
+-- Name: SEQUENCE "Naturminne_yta_ogc_fid_seq"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE nvr."Naturminne_yta_ogc_fid_seq" TO guest;
+
+
+--
+-- Name: TABLE "Naturreservat"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT ON TABLE nvr."Naturreservat" TO guest;
+
+
+--
+-- Name: SEQUENCE "Naturreservat_ogc_fid_seq"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE nvr."Naturreservat_ogc_fid_seq" TO guest;
+
+
+--
+-- Name: TABLE "Naturvardsomrade"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT ON TABLE nvr."Naturvardsomrade" TO guest;
+
+
+--
+-- Name: SEQUENCE "Naturvardsomrade_ogc_fid_seq"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE nvr."Naturvardsomrade_ogc_fid_seq" TO guest;
+
+
+--
+-- Name: TABLE "OSPAR"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT ON TABLE nvr."OSPAR" TO guest;
+
+
+--
+-- Name: SEQUENCE "OSPAR_ogc_fid_seq"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE nvr."OSPAR_ogc_fid_seq" TO guest;
+
+
+--
+-- Name: TABLE "Ovrigt_biotopskyddsomrade"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT ON TABLE nvr."Ovrigt_biotopskyddsomrade" TO guest;
+
+
+--
+-- Name: SEQUENCE "Ovrigt_biotopskyddsomrade_ogc_fid_seq"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE nvr."Ovrigt_biotopskyddsomrade_ogc_fid_seq" TO guest;
+
+
+--
+-- Name: TABLE "Ramsar"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT ON TABLE nvr."Ramsar" TO guest;
+
+
+--
+-- Name: SEQUENCE "Ramsar_ogc_fid_seq"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE nvr."Ramsar_ogc_fid_seq" TO guest;
+
+
+--
+-- Name: TABLE "SCI_Rikstackande"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT ON TABLE nvr."SCI_Rikstackande" TO guest;
+
+
+--
+-- Name: SEQUENCE "SCI_Rikstackande_ogc_fid_seq"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE nvr."SCI_Rikstackande_ogc_fid_seq" TO guest;
+
+
+--
+-- Name: TABLE "SPA_Rikstackande"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT ON TABLE nvr."SPA_Rikstackande" TO guest;
+
+
+--
+-- Name: SEQUENCE "SPA_Rikstackande_ogc_fid_seq"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE nvr."SPA_Rikstackande_ogc_fid_seq" TO guest;
+
+
+--
+-- Name: TABLE "Tilltradesforbud"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT ON TABLE nvr."Tilltradesforbud" TO guest;
+
+
+--
+-- Name: SEQUENCE "Tilltradesforbud_ogc_fid_seq"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE nvr."Tilltradesforbud_ogc_fid_seq" TO guest;
+
+
+--
+-- Name: TABLE "Varldsarv"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT ON TABLE nvr."Varldsarv" TO guest;
+
+
+--
+-- Name: SEQUENCE "Varldsarv_ogc_fid_seq"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE nvr."Varldsarv_ogc_fid_seq" TO guest;
+
+
+--
+-- Name: TABLE "Vattenskyddsomrade"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT ON TABLE nvr."Vattenskyddsomrade" TO guest;
+
+
+--
+-- Name: SEQUENCE "Vattenskyddsomrade_ogc_fid_seq"; Type: ACL; Schema: nvr; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE nvr."Vattenskyddsomrade_ogc_fid_seq" TO guest;
+
+
+--
+-- Name: TABLE metadata; Type: ACL; Schema: ogr_system_tables; Owner: geodata
+--
+
+GRANT SELECT ON TABLE ogr_system_tables.metadata TO guest;
+
+
+--
+-- Name: SEQUENCE metadata_id_seq; Type: ACL; Schema: ogr_system_tables; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE ogr_system_tables.metadata_id_seq TO guest;
+
+
+--
+-- Name: TABLE geography_columns; Type: ACL; Schema: public; Owner: postgres
+--
+
+GRANT SELECT ON TABLE public.geography_columns TO guest;
+
+
+--
+-- Name: TABLE geometry_columns; Type: ACL; Schema: public; Owner: postgres
+--
+
+GRANT SELECT ON TABLE public.geometry_columns TO guest;
+
+
+--
+-- Name: TABLE layercache; Type: ACL; Schema: public; Owner: geodata
+--
+
+GRANT SELECT ON TABLE public.layercache TO guest;
+
+
+--
+-- Name: SEQUENCE layercache_ogc_fid_seq; Type: ACL; Schema: public; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE public.layercache_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE spatial_ref_sys; Type: ACL; Schema: public; Owner: postgres
+--
+
+GRANT SELECT ON TABLE public.spatial_ref_sys TO guest;
+
+
+--
+-- Name: TABLE betesomrade; Type: ACL; Schema: sametinget; Owner: geodata
+--
+
+GRANT SELECT ON TABLE sametinget.betesomrade TO guest;
+
+
+--
+-- Name: SEQUENCE betesomrade_ogc_fid_seq; Type: ACL; Schema: sametinget; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE sametinget.betesomrade_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE flyttled; Type: ACL; Schema: sametinget; Owner: geodata
+--
+
+GRANT SELECT ON TABLE sametinget.flyttled TO guest;
+
+
+--
+-- Name: SEQUENCE flyttled_ogc_fid_seq; Type: ACL; Schema: sametinget; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE sametinget.flyttled_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE riksintresse_rennaringen; Type: ACL; Schema: sametinget; Owner: geodata
+--
+
+GRANT SELECT ON TABLE sametinget.riksintresse_rennaringen TO guest;
+
+
+--
+-- Name: TABLE riksintresse_rennaringen_karnomrade; Type: ACL; Schema: sametinget; Owner: geodata
+--
+
+GRANT SELECT ON TABLE sametinget.riksintresse_rennaringen_karnomrade TO guest;
+
+
+--
+-- Name: SEQUENCE riksintresse_rennaringen_karnomrade_ogc_fid_seq; Type: ACL; Schema: sametinget; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE sametinget.riksintresse_rennaringen_karnomrade_ogc_fid_seq TO guest;
+
+
+--
+-- Name: SEQUENCE riksintresse_rennaringen_ogc_fid_seq; Type: ACL; Schema: sametinget; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE sametinget.riksintresse_rennaringen_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE atervatningsavtal; Type: ACL; Schema: sks; Owner: geodata
+--
+
+GRANT SELECT ON TABLE sks.atervatningsavtal TO guest;
+
+
+--
+-- Name: SEQUENCE atervatningsavtal_ogc_fid_seq; Type: ACL; Schema: sks; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE sks.atervatningsavtal_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE avverk_anmald; Type: ACL; Schema: sks; Owner: geodata
+--
+
+GRANT SELECT ON TABLE sks.avverk_anmald TO guest;
+
+
+--
+-- Name: SEQUENCE avverk_anmald_ogc_fid_seq; Type: ACL; Schema: sks; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE sks.avverk_anmald_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE avverk_utford; Type: ACL; Schema: sks; Owner: geodata
+--
+
+GRANT SELECT ON TABLE sks.avverk_utford TO guest;
+
+
+--
+-- Name: SEQUENCE avverk_utford_ogc_fid_seq; Type: ACL; Schema: sks; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE sks.avverk_utford_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE naturvarde; Type: ACL; Schema: sks; Owner: geodata
+--
+
+GRANT SELECT ON TABLE sks.naturvarde TO guest;
+
+
+--
+-- Name: SEQUENCE naturvarde_ogc_fid_seq; Type: ACL; Schema: sks; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE sks.naturvarde_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE naturvardsavtal; Type: ACL; Schema: sks; Owner: geodata
+--
+
+GRANT SELECT ON TABLE sks.naturvardsavtal TO guest;
+
+
+--
+-- Name: SEQUENCE naturvardsavtal_ogc_fid_seq; Type: ACL; Schema: sks; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE sks.naturvardsavtal_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE nyckelbiotop; Type: ACL; Schema: sks; Owner: geodata
+--
+
+GRANT SELECT ON TABLE sks.nyckelbiotop TO guest;
+
+
+--
+-- Name: SEQUENCE nyckelbiotop_ogc_fid_seq; Type: ACL; Schema: sks; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE sks.nyckelbiotop_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE nyckelbiotop_storskogsbruk; Type: ACL; Schema: sks; Owner: geodata
+--
+
+GRANT SELECT ON TABLE sks.nyckelbiotop_storskogsbruk TO guest;
+
+
+--
+-- Name: SEQUENCE nyckelbiotop_storskogsbruk_ogc_fid_seq; Type: ACL; Schema: sks; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE sks.nyckelbiotop_storskogsbruk_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE sumpskog; Type: ACL; Schema: sks; Owner: geodata
+--
+
+GRANT SELECT ON TABLE sks.sumpskog TO guest;
+
+
+--
+-- Name: SEQUENCE sumpskog_ogc_fid_seq; Type: ACL; Schema: sks; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE sks.sumpskog_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE ledningar; Type: ACL; Schema: svk; Owner: geodata
+--
+
+GRANT SELECT ON TABLE svk.ledningar TO guest;
+
+
+--
+-- Name: SEQUENCE ledningar_ogc_fid_seq; Type: ACL; Schema: svk; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE svk.ledningar_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE stationsomraden; Type: ACL; Schema: svk; Owner: geodata
+--
+
+GRANT SELECT ON TABLE svk.stationsomraden TO guest;
+
+
+--
+-- Name: SEQUENCE stationsomraden_ogc_fid_seq; Type: ACL; Schema: svk; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE svk.stationsomraden_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE stolpar; Type: ACL; Schema: svk; Owner: geodata
+--
+
+GRANT SELECT ON TABLE svk.stolpar TO guest;
+
+
+--
+-- Name: SEQUENCE stolpar_ogc_fid_seq; Type: ACL; Schema: svk; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE svk.stolpar_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE transmissionsnatsprojekt; Type: ACL; Schema: svk; Owner: geodata
+--
+
+GRANT SELECT ON TABLE svk.transmissionsnatsprojekt TO guest;
+
+
+--
+-- Name: SEQUENCE transmissionsnatsprojekt_ogc_fid_seq; Type: ACL; Schema: svk; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE svk.transmissionsnatsprojekt_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE havsbaserad_vindkraft; Type: ACL; Schema: vbk; Owner: geodata
+--
+
+GRANT SELECT ON TABLE vbk.havsbaserad_vindkraft TO guest;
+
+
+--
+-- Name: SEQUENCE havsbaserad_vindkraft_ogc_fid_seq; Type: ACL; Schema: vbk; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE vbk.havsbaserad_vindkraft_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE projekteringsomraden; Type: ACL; Schema: vbk; Owner: geodata
+--
+
+GRANT SELECT ON TABLE vbk.projekteringsomraden TO guest;
+
+
+--
+-- Name: SEQUENCE projekteringsomraden_ogc_fid_seq; Type: ACL; Schema: vbk; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE vbk.projekteringsomraden_ogc_fid_seq TO guest;
+
+
+--
+-- Name: TABLE vindkraftverk; Type: ACL; Schema: vbk; Owner: geodata
+--
+
+GRANT SELECT ON TABLE vbk.vindkraftverk TO guest;
+
+
+--
+-- Name: SEQUENCE vindkraftverk_ogc_fid_seq; Type: ACL; Schema: vbk; Owner: geodata
+--
+
+GRANT SELECT,USAGE ON SEQUENCE vbk.vindkraftverk_ogc_fid_seq TO guest;
+
+
+--
+-- Name: ogr_system_tables_event_trigger_for_metadata; Type: EVENT TRIGGER; Schema: -; Owner: postgres
+--
+
+CREATE EVENT TRIGGER ogr_system_tables_event_trigger_for_metadata ON sql_drop
+ EXECUTE FUNCTION ogr_system_tables.event_trigger_function_for_metadata();
+
+
+ALTER EVENT TRIGGER ogr_system_tables_event_trigger_for_metadata OWNER TO postgres;
+
+--
-- PostgreSQL database dump complete
--
+\unrestrict XTQKLfyJjEgwGyWj4y8ogFznWaICeqXkLOw7GUT2TnBjUqJHf8BrjygbLvfZun2
+
diff --git a/webmap-cgi b/webmap-cgi
new file mode 100755
index 0000000..f6b78f4
--- /dev/null
+++ b/webmap-cgi
@@ -0,0 +1,295 @@
+#!/usr/bin/python3
+
+#----------------------------------------------------------------------
+# Webmap CGI (Common Gateway Interface) for the Klimatanalys Norr project
+# Copyright © 2025 Guilhem Moulin <info@guilhem.se>
+#
+# 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 <https://www.gnu.org/licenses/>.
+#----------------------------------------------------------------------
+
+# pylint: disable=invalid-name, missing-module-docstring, fixme
+# pylint: enable=invalid-name
+
+import sys
+from os import path as os_path
+from json import load as json_load, JSONDecodeError
+import logging
+from typing import Final, Iterator
+import atexit
+
+from psycopg import connect, RawCursor # pylint: disable=import-error
+
+import common
+from common import escape_identifier, getEscapedTableNamePG, getQualifiedLayerName
+
+def get_table_map() -> dict[tuple[str, str], str]:
+ """Get mapping of pairs (MVT group name, layername) to table name."""
+ ret = {}
+ config = common.load_config()
+ layer_groups = config.get('layer-groups', {})
+ layers = config.get('layers', {})
+ layernames = set(layers.keys())
+ for groupname, patterns in layer_groups.items():
+ for layername in common.layers_in_group(groupname, patterns, layernames):
+ exportdef = layers[layername].get('publish', None)
+ if exportdef is None:
+ continue
+ if isinstance(exportdef, str):
+ exportdef = [ exportdef ]
+ for layername_mvt in exportdef:
+ k = (groupname, layername_mvt)
+ if k in ret:
+ raise RuntimeError(f'Duplicate key {k}')
+ ret[k] = layername
+ return ret
+
+def get_query_map(layernames : set[str]) -> dict[str,bytes]:
+ """Get GeoJSON-producing query map."""
+ ret = {}
+ # pylint: disable-next=no-member
+ with PG_CONN.cursor(binary=True, scrollable=False, withhold=False) as cur:
+ for layername in layernames:
+ (schema_name, table_name) = getQualifiedLayerName(layername)
+ if schema_name is None:
+ raise RuntimeError(f'Layername {layername} is not qualified')
+ cur.execute('SELECT f_geometry_column, coord_dimension, srid, type '
+ 'FROM public.geometry_columns '
+ 'WHERE f_table_schema = $1 AND f_table_name = $2',
+ params=(schema_name, table_name),
+ prepare=False)
+ resp = cur.fetchone()
+ if resp is None:
+ continue
+ geom_cols = [ resp[0] ]
+ geom_dim = resp[1]
+ force2d = geom_dim > 2
+ geom_type = resp[3]
+ geom_srid = resp[2]
+ if geom_srid != 3006:
+ # If the SRS isn't projected and/or isn't in meter units then ST_Area() resp.
+ # ST_Length() aren't in m² resp. m. We could reproject, but since the target
+ # SRS is SWEREF 99 we just warn on mismatch
+ logging.warning('Geometry column "%s" in table "%s" has SRID %d != 3006',
+ geom_cols[0], layername, geom_srid)
+ if geom_type in ('POLYGON', 'MULTIPOLYGON',
+ 'POLYGONM', 'MULTIPOLYGONM'):
+ d = 2 # surface
+ elif geom_type in ('LINESTRING', 'MULTILINESTRING',
+ 'LINESTRINGM', 'MULTILINESTRINGM'):
+ d = 1 # curve
+ elif geom_type in ('POINT', 'MULTIPOINT',
+ 'POINTM', 'MULTIPOINTM'):
+ d = 0 # point
+ else:
+ logging.warning('Geometry column "%s" in table "%s" has unknown type %s',
+ geom_cols[0], layername, geom_type)
+ d = -1
+
+ resp = cur.fetchone()
+ if resp is not None:
+ logging.warning('Table "%s" has multiple geometry colums, '
+ 'only considering "%s" (%s, SRID=%d, dim=%d)',
+ layername, geom_cols[0], geom_type, geom_srid, geom_dim)
+ while resp is not None:
+ geom_cols.append( resp[0] )
+ resp = cur.fetchone()
+
+ # https://wiki.postgresql.org/wiki/Retrieve_primary_key_columns
+ cur.execute('SELECT a.attname, format_type(a.atttypid, a.atttypmod) AS data_type '
+ 'FROM pg_index i '
+ 'JOIN pg_attribute a '
+ ' ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey) '
+ 'WHERE i.indrelid = $1::regclass AND i.indisprimary',
+ params=(getEscapedTableNamePG(layername),),
+ prepare=False)
+ resp = cur.fetchone()
+ if resp is None:
+ logging.warning('Table "%s" has no PRIMARY KEY, ignoring', layername)
+ continue
+ pkey_col = resp[0]
+ if resp[1] not in ('integer', 'bigint'):
+ logging.warning('Table "%s" PRIMARY KEY "%s" has invalid type %s, ignoring',
+ layername, pkey_col, resp[1])
+ continue
+ resp = cur.fetchone()
+ if resp is not None:
+ logging.warning('Table "%s" PRIMARY KEY spans over multiple columns, ignoring',
+ layername)
+ continue
+
+ column_names = []
+ cur.execute('SELECT column_name FROM information_schema.columns '
+ 'WHERE table_schema = $1 AND table_name = $2',
+ params=(schema_name, table_name),
+ prepare=False)
+ # never empty since the we know the table exists and has a primary key
+ resp = cur.fetchone()
+ while resp is not None:
+ c = resp[0]
+ # pylint: disable-next=too-many-boolean-expressions
+ if (c in ('layer_group', 'layer') or
+ (c == 'ogc_fid' and pkey_col != c) or
+ (d == 2 and c in ('geom_area', 'geom_perimeter')) or
+ (d == 1 and c == 'geom_length')):
+ logging.warning('Duplicate column name "%s"', c)
+ if c != pkey_col and c not in geom_cols:
+ column_names.append(c)
+ resp = cur.fetchone()
+
+ query = 'WITH feature AS ('
+ query += 'SELECT m.' + escape_identifier(pkey_col) + ' AS ogc_fid,'
+ for column_name in column_names:
+ query += 'm.' + escape_identifier(column_name) + ','
+ if force2d:
+ geom_col2d_esc = 'ST_Force2D(m.' + escape_identifier(geom_cols[0]) + ')'
+ else:
+ geom_col2d_esc = 'm.' + escape_identifier(geom_cols[0])
+ if d == 2:
+ query += 'ST_Area(' + geom_col2d_esc +') AS geom_area,'
+ query += 'ST_Perimeter(' + geom_col2d_esc +') AS geom_perimeter,'
+ elif d == 1:
+ query += 'ST_Length(' + geom_col2d_esc +') AS geom_length,'
+ query += '$1 AS layer_group,$2 AS layer '
+ query += 'FROM ' + getEscapedTableNamePG(layername) + ' m '
+ query += 'WHERE m.' + escape_identifier(pkey_col) + ' = $3'
+ query += ') '
+ query += 'SELECT json_serialize(to_json(feature) RETURNING bytea) FROM feature'
+ # The query never returns more than one row since we filter on a single FID.
+ # TODO: batch queries using ANY[] or an IN set (the # consummer will then need
+ # to re-order the response)
+ ret[layername] = query.encode('utf-8')
+ return ret
+
+
+STATUS_OK : Final[str] = '200 OK'
+STATUS_BAD_REQUEST : Final[str] = '400 Bad Request'
+STATUS_NOT_ALLOWED : Final[str] = '405 Method Not Allowed'
+STATUS_INTERNAL_SERVER_ERROR : Final[str] = '500 Internal Server Error'
+
+EMPTY_RESPONSE_HEADERS : Final[list[tuple[str,str]]] = [
+ ('Content-Type', 'text/plain'),
+ ('Content-Length', '0'),
+]
+CONTENT_TYPE_JSON : Final[tuple[str,str]] = ('Content-Type', 'application/json; charset=UTF-8')
+
+MAX_FEATURE_COUNT : Final[int] = 500
+def application(env, start_response) -> Iterator[bytes]:
+ """Main application."""
+ if env['REQUEST_METHOD'].upper() != 'POST':
+ logging.error('Invalid request method %s', env['REQUEST_METHOD'])
+ start_response(STATUS_NOT_ALLOWED, EMPTY_RESPONSE_HEADERS)
+ return
+
+ content_type = env.get('CONTENT_TYPE', '').lower()
+ if content_type != 'application/json' and not content_type.startswith('application/json;'):
+ logging.error('Invalid Content-Type: %s', content_type)
+ start_response(STATUS_BAD_REQUEST, EMPTY_RESPONSE_HEADERS)
+ return
+
+ first = True
+ try:
+ body = json_load(env['wsgi.input'])
+ if not isinstance(body, list):
+ raise ValueError
+
+ start_response(STATUS_OK, [CONTENT_TYPE_JSON])
+ if not body:
+ yield b'[]'
+ return
+
+ if len(body) > MAX_FEATURE_COUNT:
+ logging.warning('Query has too many feature requests (%d), truncating to %d',
+ len(body), MAX_FEATURE_COUNT)
+ body = body[:MAX_FEATURE_COUNT]
+
+ # pylint: disable-next=no-member
+ with PG_CONN.cursor(binary=True, scrollable=False, withhold=False) as cur:
+ for item in body:
+ if not isinstance(item, dict):
+ raise ValueError
+ layer_group = item.get('layer_group', None)
+ layer = item.get('layer', None)
+ if not isinstance(layer_group, str) or not isinstance(layer, str):
+ raise ValueError
+ query = QUERY_MAP[TABLE_MAP[(layer_group, layer)]]
+ fid = item.get('fid', None)
+ if not isinstance(fid, int):
+ raise ValueError
+ cur.execute(query, params=(layer_group, layer, fid))
+ resp = cur.fetchone()
+ if resp is None:
+ continue # no match for this tuple
+ if first:
+ yield b'['
+ first = False
+ else:
+ yield b','
+ yield resp[0]
+ # the query never returns more than one row since we filter on a single FID
+ if first:
+ yield b'[]' # no match, empty response
+ first = False
+ else:
+ yield b']'
+
+ except (JSONDecodeError, LookupError, UnicodeDecodeError, ValueError) as exc:
+ logging.exception('Invalid request body')
+ # start_response(,,sys.exc_info()) should work here, but doesn't
+ # because of https://github.com/unbit/uwsgi/issues/2278
+ if first:
+ start_response(STATUS_BAD_REQUEST, EMPTY_RESPONSE_HEADERS)
+ else:
+ # headers already sent, can't do better; the client will get a 200 status
+ # code, but fail to parse the payload as JSON anyway
+ exc_info = sys.exc_info()
+ raise exc_info[1].with_traceback(exc_info[2]) from exc
+ except Exception as exc: # pylint: disable=broad-exception-caught
+ logging.exception('Internal Server Error')
+ if first:
+ start_response(STATUS_INTERNAL_SERVER_ERROR, EMPTY_RESPONSE_HEADERS)
+ else:
+ exc_info = sys.exc_info()
+ raise exc_info[1].with_traceback(exc_info[2]) from exc
+
+# We could use a psycopg_pool.ConnectionPool() but that would be
+# overkill since we only have 2 workers and no threads. So each worker
+# simply opens a (single) connection to PostgreSQL at launch time.
+# Use autocommit to avoid starting a transaction, cf.
+# https://www.psycopg.org/psycopg3/docs/basic/transactions.html#autocommit-transactions
+PG_CONN = connect('postgresql://guest@/geodata',
+ autocommit=True,
+ prepare_threshold=0,
+ cursor_factory=RawCursor)
+
+@atexit.register
+def handler():
+ """Gracefully close the connection before terminating the worker"""
+ # avoid "AttributeError: 'NoneType' object has no attribute 'connection_summary'"
+ # when destructing the object
+ PG_CONN.close() # pylint: disable=no-member
+
+common.init_logger(app=os_path.basename(__file__), level=logging.INFO)
+TABLE_MAP : Final[dict[tuple[str, str], str]] = get_table_map()
+QUERY_MAP : Final[dict[str, bytes]] = get_query_map(set(TABLE_MAP.values()))
+
+PG_CONN.execute( # pylint: disable=no-member
+ 'SET statement_timeout TO 15000', # 15s
+ prepare=False)
+
+# drop functions and modules we don't need anymore
+del common
+del sys.modules['common']
+del get_query_map
+del get_table_map
+del os_path
diff --git a/webmap-download-mrr.py b/webmap-download-mrr.py
deleted file mode 100644
index 2477f8a..0000000
--- a/webmap-download-mrr.py
+++ /dev/null
@@ -1,669 +0,0 @@
-#----------------------------------------------------------------------
-# Backend utilities for the Klimatanalys Norr project (download MRR layers)
-# Copyright © 2024 Guilhem Moulin <info@guilhem.se>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU 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 General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <https://www.gnu.org/licenses/>.
-#----------------------------------------------------------------------
-
-# Unfortunately SGU/Bergsstaten doesn't offer MRR layer files to
-# download, cf.
-#
-# https://www.sgu.se/produkter-och-tjanster/geologiska-data/vara-data-per-amnesomrade/berggrundsgeologiska-data/mineralrattigheter/
-#
-# but it has an online webmap (WMS) at
-#
-# https://apps.sgu.se/kartvisare/kartvisare-mineralrattigheter.html
-#
-# so we add a dedicated module to probe and fetch features from it.
-
-from os import O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_CLOEXEC, O_TMPFILE
-import os
-from pathlib import Path
-from time import time, sleep, monotonic as time_monotonic
-import re
-import logging
-import requests
-import itertools
-import random
-import json
-from math import sqrt
-from hashlib import sha256
-from lxml import etree
-
-from osgeo import gdal, ogr
-gdal.UseExceptions()
-
-import common
-
-LAST_UPDATED = 'Last updated'
-class WMS:
- def __init__(self, headers={}, session=requests, url=None, version='1.1.1'):
- self.req_count = 0
- self.headers = headers
- self.session = session
- self.url = url
- self.version = version
-
- def __del__(self):
- self.print_req_count()
-
- def print_req_count(self, elapsed=None):
- if self.req_count is None or self.url is None:
- return
- elif elapsed is None:
- logging.info('%d WMS requests sent to %s', self.req_count, self.url)
- else:
- logging.info('%d WMS requests (%.2f\u202Freq/s) sent to %s', self.req_count,
- self.req_count/elapsed, self.url)
-
- # Send a request to the WMS server
- def req(self, request, content_type=None, params={}, max_tries=10, timeout=10):
- params2 = {
- 'SERVICE': 'WMS',
- 'VERSION': self.version,
- 'REQUEST': request,
- } | params
- for i in itertools.count(1):
- try:
- r = self.session.get(self.url,
- headers = self.headers,
- params = params2,
- timeout = timeout,
- )
- except (requests.Timeout, requests.ConnectionError) as e:
- if i < max_tries:
- logging.error('Timeout')
- continue
- raise e
- self.req_count += 1
- if i < max_tries and r.status_code in [requests.codes.bad_gateway, requests.codes.gateway_timeout]:
- logging.error(r.status_code)
- sleep(30)
- continue
- r.raise_for_status()
- if content_type is not None:
- content_type2 = r.headers.get('Content-Type')
- content_type2 = content_type2.split(';')[0] if content_type2 is not None else None
- if content_type2 is None or content_type2 != content_type:
- raise Exception(f'Content-Type mismatch: expected {content_type}, got {content_type2}')
- return r
-
- # Return metadata for the given feature
- def getFeatureInfo(self, x, y, layer, res=.25):
- content_type = 'application/json'
- width = height = 101 # value from https://apps.sgu.se/kartvisare/kartvisare-mineralrattigheter.html
- half_width = res * width/2
- half_height = res * height/2
- x1 = x - half_width
- x2 = x + half_width
- y1 = y - half_height
- y2 = y + half_height
- bbox = [x1, y1, x2, y2]
-
- max_count = 300
- r = self.req('GetFeatureInfo', content_type=content_type, params={
- 'LAYERS': layer,
- 'FORMAT': 'image/png',
- 'TRANSPARENT': 'true',
- 'TILED': 'false',
- 'WIDTH': width,
- 'HEIGHT': height,
- 'QUERY_LAYERS': layer,
- 'INFO_FORMAT': content_type,
- 'FEATURE_COUNT': max_count,
- 'X': 50,
- 'Y': 50,
- 'BBOX': ','.join(map(str, bbox)),
- 'SRS': common.config['SRS'],
- })
- data = r.json()
- if data.get('type', '') != 'FeatureCollection':
- raise Exception(f'Did not return a feature collection')
- if data.get('features', None) is None:
- raise Exception(f'Missing features list')
- if len(data.get('features')) >= max_count:
- logging.warning('Returned max number of features (%d), possibly missing some!', max_count)
- return data
-
- # Refine a geometry at the given resolution.
- # Return the iteration count at which the feature was found (or None if it was not found) along
- # with a dictionary `fingerprint:feature` found along the way.
- def refineGeometry(self, layername, fpr, feature, res=1, crs=None, max_tries=1024, features={}):
- geojson = json.dumps(feature.get('geometry'))
- geom = ogr.CreateGeometryFromJson(geojson)
- if geom is None:
- raise Exception(f'Invalid GeoJSON geometry')
- triangulation = triangulate(geom.MakeValid())
- i = 0
- while fpr not in features and i < max_tries:
- x, y = getRandomPoint(triangulation)
- data = self.getFeatureInfo(x, y, layername, res=res)
- crs2 = data.get('crs', None)
- features2 = data['features']
- if ((crs is None and crs2 is not None) or (crs is not None and crs2 is None)
- or (crs is not None and crs2 is not None and crs != crs2)):
- if len(features2) > 0:
- # the server should never return different CRSs
- raise Exception(f'{json.dumps(crs)} != {json.dumps(crs2)}')
- for feature2 in features2:
- fpr2, feature2 = mkFeature(feature2, layername)
- features[fpr2] = feature2
- i += 1
- if fpr not in features:
- return None, features
- return i, features
-
- # Refine geometries at the given resolution, modifying features in place
- def refineGeometries(self, features, layername, res=1, crs=None, max_tries=1024, progress=None):
- feature_count = len(features)
- features2 = {}
- pbar = None
- stats = {}
- try:
- if progress is not None:
- pbar = progress(total=feature_count, leave=False, unit='')
- for fpr, feature in features.items():
- i, _ = self.refineGeometry(layername, fpr, feature,
- res=res, crs=crs, max_tries=max_tries, features=features2)
- if i is None:
- i = '-'
- stats[i] = stats.get(i, 0) + 1
- if pbar is not None:
- pbar.update(1)
- finally:
- if pbar is not None:
- pbar.close()
-
- features.update(features2)
-
- # show refinement stats
- if stats.get(0, 0) + stats.get(1, 0) == feature_count:
- details = 'all on first attempt'
- else:
- details = []
- for ks, vs in sorted(stats.items(), key=lambda item: max_count+1 if item[0] == '-' else item[0]):
- if ks == '-':
- msg = f'{vs}× FAILED'
- elif len(details) > 0:
- msg = f'{vs}× {ks}'
- elif ks == 1:
- msg = f'{vs}× after 1 attempt'
- else:
- msg = f'{vs}× after {ks} attempts'
- details.append(msg)
- details = ', '.join(details)
- w = 'geometry' if feature_count == 1 else 'geometries'
- logging.info('Refined %d %s at resolution %s (%s)', feature_count, w, str(res), details)
-
- # Guess whether the cached layer at path is up to date
- def is_uptodate(self, layername, path, dir_fd=None,
- oldsvg_fp=None, newsvg='',
- max_age=864000):
- try:
- fd = os.open(path, O_RDONLY, dir_fd=dir_fd)
- except (OSError, ValueError):
- # couldn't open cached file
- logging.debug('%s is stale: open() failed', path)
- return False
-
- try:
- try:
- st = os.fstat(fd)
- svg_st = os.fstat(oldsvg_fp.fileno())
- except (OSError, ValueError):
- logging.debug('%s is stale: fstat() failed', path)
- return False
-
- if st.st_mtime < svg_st.st_mtime:
- # writing SVG is racy so always assume that a younger SVG
- # means a stale GeoJSON
- logging.debug('%s is stale: SVG is younger (%f < %f)', path,
- st.st_mtime, svg_st.st_mtime)
- return False
-
- try:
- oldsvg = oldsvg_fp.read()
- finally:
- # seek back to the begining (we then truncate and write the SVG)
- oldsvg_fp.seek(0)
- if newsvg is None or oldsvg != newsvg:
- logging.debug('%s is stale: SVG differs', path)
- return False
-
- if max_age is not None:
- current_time = time()
- mtime = max(st.st_ctime, st.st_mtime)
- if max_age + mtime < current_time:
- # always consider files older than max_age as stale
- logging.debug('%s is stale: too old (%f + %f < %f)', path,
- max_age, mtime, current_time)
- return False
-
- with os.fdopen(fd, mode='rb', closefd=False) as fp:
- try:
- # load cached geojson
- data = json.load(fp)
- except json.JSONDecodeError:
- logging.warning('%s is stale: not a valid JSON file', path)
- return False
- finally:
- os.close(fd)
-
- # more checks on the GeoJSON content
- if (not isinstance(data, dict) or 'type' not in data or data['type'] != 'FeatureCollection'
- or 'features' not in data or not isinstance(data['features'], list)):
- logging.warning('%s: not a valid GeoJSON file', path)
- return False
-
- crs = data.get('crs', None)
- data = data['features']
- if len(data) == 0:
- # always assume empty cached files are stale
- logging.debug('%s is stale: has no features', path)
- return False
-
- data = random.choice(data) # random features
- if (not isinstance(data, dict) or 'type' not in data or data['type'] != 'Feature'
- or 'geometry' not in data or not isinstance(data['geometry'], dict)):
- logging.warning('%s: not a valid GeoJSON file', path)
- return False
-
- last_updated = data['properties'].get(LAST_UPDATED, None)
- if last_updated is None or last_updated == '':
- logging.debug('%s is stale: %s has no "%s" value', path,
- json.dumps(data), LAST_UPDATED)
- return False
-
- # check whether the randomly chosen feature is still there and that
- # its "Last updated" value has not changed
- # (this check comes last as it is potentially expensive)
- fpr, data = mkFeature(data, layername)
- found, features = self.refineGeometry(layername, fpr, data, res=.25, crs=crs, max_tries=10)
- if not found:
- logging.debug('%s is stale: could not find feature %s', path, json.dumps(data))
- return False
-
- last_updated2 = features[fpr]['properties'].get(LAST_UPDATED, None)
- if last_updated2 is None or last_updated != last_updated2:
- logging.debug('%s is stale: "%s" values differ (%s != %s)',
- path, LAST_UPDATED, last_updated, last_updated2)
- return False
-
- # assume the cached file is up to date
- logging.debug('is_uptodate(%s, %s, …) == True', layername, path)
- return True
-
- def getFeatures(self, layername, path_strings, gt, progress=None):
- crs = None
- max_probe_count = 3
- probes = []
- for d in path_strings:
- d0 = d
- m = POINT0_RE.match(d)
- if m is None:
- raise Exception(f"Can't parse <path>'s \"d\" attribute value: \"{d0}\"")
- d = d.removeprefix(m.group())
- x = float(m.group(1))
- y = float(m.group(2))
- path = [ [x, y] ]
-
- # get first part of the path (until the pen is moved)
- while True:
- m = POINT_RE.match(d)
- if m is None:
- break
- d = d.removeprefix(m.group())
- x = float(m.group(1))
- y = float(m.group(2))
- if path[-1] != [x, y]:
- path.append([x, y])
- if d.startswith('Z') and len(path) > 0:
- if path[0] != path[-1]:
- path.append(path[0])
- d = d.removeprefix("Z")
- logging.debug('d="%s" -> path=%s, rest="%s"', d0, path, d)
-
- # convert to an outer ring
- ring0 = ogr.Geometry(ogr.wkbLinearRing)
- for px, py in path:
- x, y = gdal.ApplyGeoTransform(gt, px, py)
- ring0.AddPoint_2D(x, y)
-
- poly0 = ogr.Geometry(ogr.wkbPolygon)
- poly0.AddGeometry(ring0)
-
- # randomly probe once per 10km² (1000ha), but not more than max_probe_count
- probe_count = poly0.GetArea() / 1e7
- if probe_count < 1:
- probe_count = 1
- elif probe_count > max_probe_count:
- probe_count = max_probe_count
- else:
- probe_count = round(probe_count)
-
- probes.append( (poly0.MakeValid(), probe_count) )
-
- if len(probes) == 0:
- self.req_count = None # don't print request count
- return {}, crs
-
- features = {}
- probe_count_sum = sum([n for _, n in probes])
- pbar = None
- try:
- if progress is not None:
- pbar = progress(total=probe_count_sum, leave=False, unit='')
- for geom, probe_count in probes:
- triangulation = triangulate(geom)
-
- # always try the centroid first (later fallback to a random
- # point if the centroid is not in geom)
- x, y = nearCentroidWithin(geom)
-
- # crude probing and add feature(s) found along the way
- for i in range(probe_count):
- if i > 0 or x is None or y is None:
- x, y = getRandomPoint(triangulation)
-
- data = self.getFeatureInfo(x, y, layername, res=1024)
- crs2 = data.get('crs', None)
- data = data['features']
- if crs2 is not None:
- if crs is None:
- crs = crs2
- elif crs != crs2 and len(data) > 0:
- # the server should never return different CRSs
- raise Exception(f'{json.dumps(crs)} != {json.dumps(crs2)}')
-
- for feature in data:
- fpr, feature = mkFeature(feature, layername)
- features[fpr] = feature
- data = None
-
- if pbar is not None:
- pbar.update(1)
- geom = None
- finally:
- del probes[:]
- if pbar is not None:
- pbar.close()
-
- logging.info('Found %d unique feature(s) after crude probing', len(features))
- return features, crs
-
-# Triangulate the input geometry
-def triangulate(geom):
- geomType = geom.GetGeometryType()
- if geomType == ogr.wkbPolygon or geomType == ogr.wkbMultiPolygon or geomType == ogr.wkbGeometryCollection:
- if geom.Area() < 1e-9:
- # degenerate polygon
- return geom.Boundary()
- elif geomType == ogr.wkbLineString or geomType == ogr.wkbMultiLineString:
- return geom
- elif geomType == ogr.wkbPoint or geomType == ogr.wkbMultiPoint:
- return geom
- else:
- raise Exception(f'Invalid geometry type: {geom}')
-
- triangulation = geom.DelaunayTriangulation(dfTolerance=0., bOnlyEdges=False)
- triangulation2 = ogr.Geometry(ogr.wkbGeometryCollection)
- for i in range(triangulation.GetGeometryCount()):
- triangle = triangulation.GetGeometryRef(i)
- if geom.Contains(triangle):
- triangulation2.AddGeometry(triangle)
- return triangulation2
-
-# Return the centroid (modulo rounding) if is within the input geometry,
-# and None, None otherwise
-def nearCentroidWithin(geom, decimals=2):
- centroid = geom.Centroid()
- if centroid.GetGeometryType() != ogr.wkbPoint:
- raise Exception(f'{centroid} is not a point')
- x, y = centroid.GetPoint_2D(0)
- if decimals is not None:
- x = round(x, decimals)
- y = round(y, decimals)
- pt = ogr.Geometry(ogr.wkbPoint)
- pt.AddPoint_2D(x, y)
- if pt.Within(geom):
- return x, y
- else:
- return None, None
-
-# Get a random point within the given geometry
-# The geometry needs to be triangulated first for speed, see
-# see https://dev.to/bogdanalexandru/generating-random-points-within-a-polygon-in-unity-nce
-def getRandomPoint(triangulation, decimals=2, max_tries=1024):
- # special cases if source is a degenerate polygon
- geomType = triangulation.GetGeometryType()
- if geomType == ogr.wkbMultiPoint:
- if triangulation.GetGeometryCount() == 0:
- raise Exception(f'Empty {triangulation}')
- i = random.randrange(0, triangulation.GetGeometryCount())
- pt = triangulation.GetGeometryRef(i)
- return pt.GetX(), pt.GetY()
- elif geomType == ogr.wkbLineString:
- i = random.uniform(0, triangulation.Length())
- pt = triangulation.Value(i)
- return pt.GetX(), pt.GetY()
- elif geomType == ogr.wkbMultiLineString:
- lengths = []
- for i in range(triangulation.GetGeometryCount()):
- line = triangulation.GetGeometryRef(i)
- lengths.append(line.Length())
- k = random.choices(range(triangulation.GetGeometryCount()), weights=lengths, k=1)[0]
- line = triangulation.GetGeometryRef(k)
- i = random.uniform(0, line.Length())
- pt = line.Value(i)
- return pt.GetX(), pt.GetY()
- elif geomType != ogr.wkbGeometryCollection:
- raise Exception(f'Not a GeometryCollection {triangulation}')
-
- areas = []
- for i in range(triangulation.GetGeometryCount()):
- triangle = triangulation.GetGeometryRef(i)
- areas.append(triangle.GetArea())
-
- for i in range(max_tries):
- # pick a random triangle (weighted by area)
- k = random.choices(range(triangulation.GetGeometryCount()), weights=areas, k=1)[0]
- triangle = triangulation.GetGeometryRef(k)
-
- ring = triangle.GetGeometryRef(0)
- if triangle.GetGeometryType() != ogr.wkbPolygon or triangle.GetGeometryCount() != 1 or ring.GetPointCount() != 4:
- raise Exception('Not a triangle')
-
- x0, y0 = ring.GetPoint_2D(0)
- x1, y1 = ring.GetPoint_2D(1)
- x2, y2 = ring.GetPoint_2D(2)
-
- # pick a random point inside that triangle
- r1 = random.uniform(0, 1)
- r2 = random.uniform(0, 1)
- sqrt_r1 = sqrt(r1)
- sqrt_r2 = sqrt(r2)
-
- x = (1 - sqrt_r1) * x0 + sqrt_r1 * (1 - r2) * x1 + sqrt_r1 * r2 * x2
- y = (1 - sqrt_r1) * y0 + sqrt_r1 * (1 - r2) * y1 + sqrt_r1 * r2 * y2
- if decimals is not None:
- x = round(x, decimals)
- y = round(y, decimals)
- pt = ogr.Geometry(ogr.wkbPoint)
- pt.AddPoint_2D(x, y)
- if pt.Within(triangulation):
- return x, y
- # might need to retry due to rounding
- raise Exception(f"Couldn't find point within geometry pt={pt} triangle={triangle} k={k} triangulation={triangulation}")
-
-# Return a feature along with its "signature"
-def mkFeature(feature, layername):
- properties = feature.get('properties', None)
- if properties is None:
- raise Exception(f'Feature lacks "properties" attributes')
- fid = feature.pop('id', None)
- if fid is not None and layername is not None and not fid.startswith(layername.removeprefix('MRR:')):
- raise Exception(f'Unexpected ID {fid} for layer {layername}')
-
- properties2 = properties.copy()
- properties2.pop(LAST_UPDATED, None) # always ignore "Last updated" values
- properties2 = json.dumps(properties2, ensure_ascii=False, sort_keys=True, separators=(',', ':'))
- fpr = sha256(properties2.encode('utf-8') + b'\x00' + layername.encode('utf-8'))
- return fpr.hexdigest(), {
- # RFC 7946 sec. 3.2
- 'type': 'Feature',
- 'geometry': feature.get('geometry'),
- 'properties': properties,
- }
-
-FLOAT_RE = r'(?:[0-9]+(?:\.[0-9]*)?|\.[0-9]+)'
-PATH_RE = re.compile(r'^M\s*' +
- FLOAT_RE + r'\s+' + FLOAT_RE + r'\s+' +
- r'(?:L\s*' + FLOAT_RE + r'\s+' + FLOAT_RE + r'\s+)+' +
- r'(?:[ZM]|$)')
-POINT0_RE = re.compile(r'^M\s*(' + FLOAT_RE + r')\s+(' + FLOAT_RE + r')\s+')
-POINT_RE = re.compile(r'^L\s*(' + FLOAT_RE + r')\s+(' + FLOAT_RE + r')(?:\s+|$)')
-
-def download(dl, dest, dir_fd=None, headers={}, session=requests, progress=None):
- dest_path = Path(dest)
- if dest_path.suffix.lower() != '.geojson':
- # mostly to check that nothing ends in .svg
- raise Exception(f'{dest} must end with .geojson')
- dest_tmp = str(dest_path.with_stem(f'.{dest_path.stem}.new'))
- try:
- # delete any leftover
- os.unlink(dest_tmp, dir_fd=dir_fd)
- except FileNotFoundError:
- pass
-
- layername = dl['layername']
- logging.info(f'Processing layer %s…', layername)
- headers.pop('If-Modified-Since', None) # never send If-Modified-Since headers
-
- start = time_monotonic()
- wms = WMS(
- url='https://maps3.sgu.se/geoserver/wms',
- version='1.1.1',
- headers=headers,
- session=session,
- )
-
- # download the SVG from the WMS server and try to parse it to list
- # all features; an alternative would be to download a PNG and probe
- # every single non-transparent pixel, but it's very slow (and not
- # kind to the WMS server) due to the sheer amount of such pixels
- bbox = common.config['extent']
- res = 256
- image_format = 'image/svg+xml'
- r = wms.req('GetMap', content_type=image_format, params={
- 'LAYERS': layername,
- 'FORMAT': image_format,
- 'TRANSPARENT': 'true',
- 'TILED': 'false',
- 'WIDTH': f'{(bbox[2]-bbox[0])/res:.0f}',
- 'HEIGHT': f'{(bbox[3]-bbox[1])/res:.0f}',
- 'BBOX': ','.join(map(str, bbox)),
- 'SRS': common.config['SRS'],
- })
-
- svg_path = str(dest_path.with_suffix('.svg'))
- svg_fd = os.open(svg_path, O_RDWR|O_CREAT|O_CLOEXEC, mode=0o644, dir_fd=dir_fd)
- try:
- with os.fdopen(svg_fd, mode='wb+', closefd=False) as fp:
- if wms.is_uptodate(layername, dest, dir_fd=dir_fd,
- oldsvg_fp=fp, newsvg=r.content):
- logging.info('%s appears to be up to date, skipping', dest)
- wms.req_count = None # don't print request count
- return
-
- # not atomic, but not a big deal (only used for comparison and mismatch
- # causes the layer to be downloaded again); it's not possible to write
- # the .geojson and the .svg in the same transaction anyway
- fp.truncate()
- fp.write(r.content)
- finally:
- os.close(svg_fd)
-
- # https://gdal.org/tutorials/geotransforms_tut.html
- gt = [bbox[0], res, 0, bbox[3], 0, -res]
-
- ns = 'http://www.w3.org/2000/svg'
- tree = etree.XML(r.content)
-
- # parse SVG paths (approximation):
- # https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths#line_commands
- path_strings = set()
- for elem in tree.iterfind(f'.//{{{ns}}}path'):
- if elem.getparent().tag == f'{{{ns}}}clipPath':
- continue
- d = elem.attrib.get('d')
- if d is None:
- logging.error('<path> element has no "d" attribute')
- continue
- m = PATH_RE.match(d)
- if m is None:
- logging.error("Can't parse <path>'s \"d\" attribute value: \"%s\"", d)
- continue
- path_strings.add(d)
- logging.info('Found %d unique SVG path(s)', len(path_strings))
-
- features, crs = wms.getFeatures(layername, path_strings, gt, progress=progress)
-
- # refine geometries
- if len(features) > 0:
- #resolutions = [128, 16, 2, .25]
- resolutions = [16, .25]
- for res in resolutions:
- wms.refineGeometries(features, layername, crs=crs, res=res, progress=progress)
- logging.info('Found %d unique feature(s) after refinement', len(features))
-
- features = {
- 'type': 'FeatureCollection',
- 'name': layername,
- 'crs': crs,
- 'features': list(features.values()),
- }
-
- # write the destination GeoJSON file
- fd = os.open(os.path.dirname(dest), O_WRONLY|O_CLOEXEC|O_TMPFILE, mode=0o644, dir_fd=dir_fd)
- try:
- with os.fdopen(fd, mode='w', closefd=False) as fp:
- json.dump(features, fp, ensure_ascii=False, separators=(',', ':'))
- st = os.fstat(fd)
- size = st.st_size
- feature_count = len(features['features'])
-
- # XXX unfortunately there is no way for linkat() to clobber the destination,
- # so we use a temporary file; it's racy, but thanks to O_TMPFILE better
- # (shorter race) than if we were dumping chunks in a named file descriptor
- os.link(f'/proc/self/fd/{fd}', dest_tmp, dst_dir_fd=dir_fd, follow_symlinks=True)
- finally:
- os.close(fd)
-
- try:
- # atomic rename (ensures output is never partially written)
- os.rename(dest_tmp, dest, src_dir_fd=dir_fd, dst_dir_fd=dir_fd)
- except (OSError, ValueError) as e:
- try:
- os.unlink(dest_tmp, dir_fd=dir_fd)
- finally:
- raise e
-
- elapsed = time_monotonic() - start
- wms.print_req_count(elapsed=elapsed)
- wms.req_count = None
- logging.info('%s: Fetched %d features (%s) in %s (%.2f\u202Ffeat/s, %s/s)', dest,
- feature_count, common.format_bytes(size),
- common.format_time(elapsed),
- feature_count/elapsed,
- common.format_bytes(int(size/elapsed)))
diff --git a/webmap-import b/webmap-import
deleted file mode 100755
index c1d07a3..0000000
--- a/webmap-import
+++ /dev/null
@@ -1,1323 +0,0 @@
-#!/usr/bin/python3
-
-#----------------------------------------------------------------------
-# Backend utilities for the Klimatanalys Norr project (extract/import layers)
-# Copyright © 2024 Guilhem Moulin <info@guilhem.se>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU 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 General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <https://www.gnu.org/licenses/>.
-#----------------------------------------------------------------------
-
-import os
-import logging
-import argparse
-import tempfile
-import re
-import math
-from fnmatch import fnmatchcase
-from pathlib import Path
-
-from osgeo import gdal, ogr, osr
-from osgeo.gdalconst import (
- OF_VECTOR as GDAL_OF_VECTOR,
- OF_ALL as GDAL_OF_ALL,
- OF_READONLY as GDAL_OF_READONLY,
- OF_UPDATE as GDAL_OF_UPDATE,
- OF_VERBOSE_ERROR as GDAL_OF_VERBOSE_ERROR,
- CE_None as GDAL_CE_None,
- DCAP_CREATE as GDAL_DCAP_CREATE,
- DCAP_VECTOR as GDAL_DCAP_VECTOR,
- DCAP_DEFAULT_FIELDS as GDAL_DCAP_DEFAULT_FIELDS,
- DCAP_NOTNULL_FIELDS as GDAL_DCAP_NOTNULL_FIELDS,
- DCAP_UNIQUE_FIELDS as GDAL_DCAP_UNIQUE_FIELDS,
-)
-import osgeo.gdalconst as gdalconst
-gdal.UseExceptions()
-
-import common
-
-# Wrapper around gdal.MajorObject.GetMetadataItem(name)
-def getMetadataItem(o, k):
- v = o.GetMetadataItem(k)
- if v is not None and isinstance(v, str):
- return v.upper() == 'YES'
- else:
- return False
-
-# Return kwargs and driver for OpenEx()
-def setOpenExArgs(option_dict, flags=0):
- kwargs = { 'nOpenFlags': GDAL_OF_VECTOR | flags }
-
- fmt = option_dict.get('format', None)
- if fmt is None:
- drv = None
- else:
- drv = gdal.GetDriverByName(fmt)
- if drv is None:
- raise Exception(f'Unknown driver name "{fmt}"')
- elif not getMetadataItem(drv, GDAL_DCAP_VECTOR):
- raise Exception(f'Driver "{drv.ShortName}" has no vector capabilities')
- kwargs['allowed_drivers'] = [ drv.ShortName ]
-
- oo = option_dict.get('open-options', None)
- if oo is not None:
- kwargs['open_options'] = [ k + '=' + str(v) for k, v in oo.items() ]
- return kwargs, drv
-
-# Open and return the output DS. It is created if create=False or
-# create-options is a non-empty dictionary.
-def openOutputDS(def_dict):
- path = def_dict['path']
- kwargs, drv = setOpenExArgs(def_dict, flags=GDAL_OF_UPDATE|GDAL_OF_VERBOSE_ERROR)
- try:
- logging.debug('OpenEx(%s, %s)', path, str(kwargs))
- return gdal.OpenEx(path, **kwargs)
- except RuntimeError as e:
- if not (gdal.GetLastErrorType() >= gdalconst.CE_Failure and
- gdal.GetLastErrorNo() == gdalconst.CPLE_OpenFailed):
- # not an open error
- raise e
-
- dso2 = None
- try:
- dso2 = gdal.OpenEx(path, nOpenFlags=GDAL_OF_ALL | GDAL_OF_UPDATE)
- except Exception:
- pass
- if dso2 is not None:
- # path exists but can't be open with OpenEx(path, **kwargs)
- raise e
-
- try:
- dso2 = gdal.OpenEx(path, nOpenFlags=GDAL_OF_ALL)
- except Exception:
- pass
- if dso2 is not None:
- # path exists but can't be open with OpenEx(path, **kwargs)
- raise e
-
- dsco = def_dict.get('create-options', None)
- if not def_dict.get('create', False) and dsco is None:
- # not configured for creation
- raise e
- if drv is None or not getMetadataItem(drv, GDAL_DCAP_CREATE):
- # not capable of creation
- raise e
-
- if 'open_options' in kwargs:
- # like ogr2ogr(1)
- logging.warning('Destination\'s open options ignored ' +
- 'when creating the output datasource')
-
- kwargs2 = { 'eType': gdal.GDT_Unknown }
- if dsco is not None:
- kwargs2['options'] = [ k + '=' + str(v) for k, v in dsco.items() ]
-
- logging.debug('Create(%s, %s, eType=%s%s)', drv.ShortName, path, kwargs2['eType'],
- ', options=' + str(kwargs2['options']) if 'options' in kwargs2 else '')
- # XXX racy, a GDAL equivalent of O_EXCL would be nice
- return drv.Create(path, 0, 0, 0, **kwargs2)
-
-# cf. ogr/ogrgeometry.cpp:OGRFromOGCGeomType()
-def fromGeomTypeName(name):
- name = name.upper()
-
- isMeasured = False
- if name.endswith('M'):
- isMeasured = True
- name = name.removesuffix('M')
-
- convertTo3D = False
- if name.endswith('Z'):
- convertTo3D = True
- name = name.removesuffix('Z')
-
- if name == 'POINT':
- eGType = ogr.wkbPoint
- elif name == 'LINESTRING':
- eGType = ogr.wkbLineString
- elif name == 'POLYGON':
- eGType = ogr.wkbPolygon
- elif name == 'MULTIPOINT':
- eGType = ogr.wkbMultiPoint
- elif name == 'MULTILINESTRING':
- eGType = ogr.wkbMultiLineString
- elif name == 'MULTIPOLYGON':
- eGType = ogr.wkbMultiPolygon
- elif name == 'GEOMETRYCOLLECTION':
- eGType = ogr.wkbGeometryCollection
- elif name == 'CIRCULARSTRING':
- eGType = ogr.wkbCircularString
- elif name == 'COMPOUNDCURVE':
- eGType = ogr.wkbCompoundCurve
- elif name == 'CURVEPOLYGON':
- eGType = ogr.wkbCurvePolygon
- elif name == 'MULTICURVE':
- eGType = ogr.wkbMultiCurve
- elif name == 'MULTISURFACE':
- eGType = ogr.wkbMultiSurface
- elif name == 'TRIANGLE':
- eGType = ogr.wkbTriangle
- elif name == 'POLYHEDRALSURFACE':
- eGType = ogr.wkbPolyhedralSurface
- elif name == 'TIN':
- eGType = ogr.wkbTIN
- elif name == 'CURVE':
- eGType = ogr.wkbCurve
- elif name == 'SURFACE':
- eGType = ogr.wkbSurface
- else:
- eGType = ogr.wkbUnknown
-
- if convertTo3D:
- eGType = ogr.GT_SetZ(eGType)
-
- if isMeasured:
- eGType = ogr.GT_SetM(eGType)
-
- return eGType
-
-# Parse geometry type, cf. ogr2ogr_lib.cpp
-def parseGeomType(name):
- if name is None:
- return ogr.wkbUnknown
- name2 = name.upper()
-
- is3D = False
- if name2.endswith('25D'):
- name2 = name2[:-3] # alias
- is3D = True
- elif name2.endswith('Z'):
- name2 = name2[:-1]
- is3D = True
-
- if name2 == 'NONE':
- eGType = ogr.wkbNone
- elif name2 == 'GEOMETRY':
- eGType = ogr.wkbUnknown
- else:
- eGType = fromGeomTypeName(name2)
- if eGType == ogr.wkbUnknown:
- raise Exception(f'Unknown geometry type "{name}"')
-
- if eGType != ogr.wkbNone and is3D:
- eGType = ogr.GT_SetZ(eGType)
-
- return eGType
-
-# cf. ogr/ogr_core.h's enum OGRFieldType;
-def parseFieldType(name):
- if name is None:
- raise Exception('parseFieldType(None)')
- name2 = name.lower()
- if name2 == 'integer':
- # simple 32bit integer
- return ogr.OFTInteger
- elif name2 == 'integerlist':
- # List of 32bit integers
- return ogr.OFTIntegerList
- elif name2 == 'real':
- # Double Precision floating point
- return ogr.OFTReal
- elif name2 == 'reallist':
- # List of doubles
- return ogr.OFTRealList
- elif name2 == 'string':
- # String of ASCII chars
- return ogr.OFTString
- elif name2 == 'stringlist':
- # Array of strings
- return ogr.OFTStringList
- elif name2 == 'binary':
- # Raw Binary data
- return ogr.OFTBinary
- elif name2 == 'date':
- # Date
- return ogr.OFTDate
- elif name2 == 'time':
- # Time
- return ogr.OFTTime
- elif name2 == 'datetime':
- # Date and Time
- return ogr.OFTDateTime
- elif name2 == 'integer64':
- # Single 64bit integer
- return ogr.OFTInteger64
- elif name2 == 'integer64list':
- # List of 64bit integers
- return ogr.OFTInteger64List
- else:
- raise Exception(f'Unknown field type "{name}"')
-
-# cf. ogr/ogr_core.h's enum OGRFieldSubType;
-def parseSubFieldType(name):
- if name is None:
- raise Exception('parseSubFieldType(None)')
- name2 = name.lower()
- if name2 == 'none':
- # No subtype. This is the default value.
- return ogr.OFSTNone
- elif name2 == 'bool':
- # Boolean integer. Only valid for OFTInteger and OFTIntegerList.
- return ogr.OFSTBoolean
- elif name2 == 'int16':
- # Signed 16-bit integer. Only valid for OFTInteger and OFTIntegerList.
- return ogr.OFSTInt16
- elif name2 == 'float32':
- # Single precision (32 bit) floating point. Only valid for OFTReal and OFTRealList.
- return ogr.OFSTFloat32
- elif name2 == 'json':
- # JSON content. Only valid for OFTString.
- return ogr.OFSTJSON
- elif name2 == 'uuid':
- # UUID string representation. Only valid for OFTString.
- return ogr.OFSTUUID
- else:
- raise Exception(f'Unknown field subtype "{name}"')
-
-# Parse timezone
-TZ_RE = re.compile(r'(?:UTC\b)?([\+\-]?)([0-9][0-9]):?([0-9][0-9])', flags=re.IGNORECASE)
-def parseTimeZone(tz):
- if tz is None:
- raise Exception('parseTimeZone(None)')
- tz2 = tz.lower()
- if tz2 == 'none':
- return ogr.TZFLAG_UNKNOWN
- elif tz2 == 'local':
- return ogr.TZFLAG_LOCALTIME
- elif tz2 == 'utc' or tz2 == 'gmt':
- return ogr.TZFLAG_UTC
-
- m = TZ_RE.fullmatch(tz)
- if m is None:
- raise Exception(f'Invalid timezone "{tz}"')
- tzSign = m.group(1)
- tzHour = int(m.group(2))
- tzMinute = int(m.group(3))
- if tzHour > 14 or tzMinute >= 60 or tzMinute % 15 != 0:
- raise Exception(f'Invalid timezone "{tz}"')
- tzFlag = tzHour*4 + int(tzMinute/15)
- if tzSign == '-':
- tzFlag = 100 - tzFlag
- else:
- tzFlag += 100
- return tzFlag
-
-# Pretty-print timezone flag, cf.
-# ogr/ogrutils.cpp:OGRGetISO8601DateTime()
-def formatTZFlag(tzFlag):
- if tzFlag is None:
- raise Exception('printTimeZone(None)')
- if tzFlag == ogr.TZFLAG_UNKNOWN:
- return 'none'
- elif tzFlag == ogr.TZFLAG_LOCALTIME:
- return 'local'
- elif tzFlag == ogr.TZFLAG_UTC:
- return 'UTC'
-
- tzOffset = abs(tzFlag - 100) * 15;
- tzHour = int(tzOffset / 60);
- tzMinute = int(tzOffset % 60);
- tzSign = '+' if tzFlag > 100 else '-'
- return f'{tzSign}{tzHour:02}{tzMinute:02}'
-
-def setFieldIf(cond, attrName, val, data, fldName, drvName, log=logging.warning):
- if cond:
- data[attrName] = val
- else:
- if isinstance(val, str):
- val2 = '"' + val + '"'
- else:
- val2 = str(val)
- log('Ignoring %s=%s on field "%s" (not supported by %s driver)',
- attrName, val2, fldName, drvName)
-
-# Validate layer creation options and schema. The schema is modified in
-# place with the parsed result.
-# (We need the driver of the output dataset to determine capability on
-# constraints.)
-def validateSchema(layers, drvo=None, lco_defaults=None):
- # Cf. https://github.com/OSGeo/gdal/blob/master/NEWS.md
- if common.gdal_version_min(maj=3, min=7):
- # list of capability flags supported by the CreateField() API
- drvoFieldDefnFlags = drvo.GetMetadataItem(gdalconst.DMD_CREATION_FIELD_DEFN_FLAGS)
- drvoFieldDefnFlags = drvoFieldDefnFlags.split(' ') if drvoFieldDefnFlags is not None else []
- drvoSupportsFieldComment = 'Comment' in drvoFieldDefnFlags
- # GetTZFlag()/SetTZFlag() and OGR_TZFLAG_* constants added in 3.8.0
- hasTZFlagSupport = common.gdal_version_min(maj=3, min=8)
- else:
- # list of flags supported by the OGRLayer::AlterFieldDefn() API
- drvoFieldDefnFlags = drvo.GetMetadataItem(gdalconst.DMD_ALTER_FIELD_DEFN_FLAGS)
- drvoFieldDefnFlags = drvoFieldDefnFlags.split(' ') if drvoFieldDefnFlags is not None else []
- # GetComment()/SetComment() added in 3.7.0
- drvoSupportsFieldComment = False
- hasTZFlagSupport = False
-
- # cache driver capabilities
- drvoSupportsFieldWidthPrecision = 'WidthPrecision' in drvoFieldDefnFlags
- drvoSupportsFieldNullable = 'Nullable' in drvoFieldDefnFlags and getMetadataItem(drvo, GDAL_DCAP_NOTNULL_FIELDS)
- drvoSupportsFieldUnique = 'Unique' in drvoFieldDefnFlags and getMetadataItem(drvo, GDAL_DCAP_UNIQUE_FIELDS)
- drvoSupportsFieldDefault = 'Default' in drvoFieldDefnFlags and getMetadataItem(drvo, GDAL_DCAP_DEFAULT_FIELDS)
- drvoSupportsFieldAlternativeName = 'AlternativeName' in drvoFieldDefnFlags
-
- for layername, layerdef in layers.items():
- create = layerdef.get('create', None)
- if create is None or len(create) < 1:
- logging.warning('Layer "%s" has no creation schema', layername)
- continue
-
- # prepend global layer creation options (dataset:create-layer-options)
- # and build the option=value list
- lco = create.get('options', None)
- if lco_defaults is not None or lco is not None:
- options = []
- if lco_defaults is not None:
- options += [ k + '=' + str(v) for k, v in lco_defaults.items() ]
- if lco is not None:
- options += [ k + '=' + str(v) for k, v in lco.items() ]
- create['options'] = options
-
- # parse geometry type
- create['geometry-type'] = parseGeomType(create.get('geometry-type', None))
-
- fields = create.get('fields', None)
- if fields is None:
- create['fields'] = []
- else:
- fields_set = set()
- for idx, fld_def in enumerate(fields):
- fld_name = fld_def.get('name', None)
- if fld_name is None or fld_name == '':
- raise Exception(f'Field #{idx} has no name')
- if fld_name in fields_set:
- raise Exception(f'Duplicate field "{fld_name}"')
- fields_set.add(fld_name)
-
- fld_def2 = { 'Name': fld_name }
- for k, v in fld_def.items():
- k2 = k.lower()
- if k2 == 'name':
- pass
- elif k2 == 'alternativename' or k2 == 'alias':
- setFieldIf(drvoSupportsFieldAlternativeName,
- 'AlternativeName', v, fld_def2, fld_name, drvo.ShortName,
- log=logging.debug)
- elif k2 == 'comment':
- setFieldIf(drvoSupportsFieldComment,
- 'Comment', v, fld_def2, fld_name, drvo.ShortName,
- log=logging.debug)
-
- elif k2 == 'type':
- fld_def2['Type'] = parseFieldType(v)
- elif k2 == 'subtype':
- fld_def2['SubType'] = parseSubFieldType(v)
- elif k2 == 'tz':
- if hasTZFlagSupport:
- fld_def2['TZFlag'] = parseTimeZone(v)
- else:
- logging.debug('Ignoring TZ="%s" on field "%s" (OGR v%s is too old)',
- v, fld_name, gdal.__version__)
- elif k2 == 'width' and v is not None and isinstance(v, int):
- setFieldIf(drvoSupportsFieldWidthPrecision,
- 'Width', v, fld_def2, fld_name, drvo.ShortName)
- elif k2 == 'precision' and v is not None and isinstance(v, int):
- setFieldIf(drvoSupportsFieldWidthPrecision,
- 'Precision', v, fld_def2, fld_name, drvo.ShortName)
-
- # constraints
- elif k2 == 'default':
- setFieldIf(drvoSupportsFieldDefault,
- 'Default', v, fld_def2, fld_name, drvo.ShortName)
- elif k2 == 'nullable' and v is not None and isinstance(v, bool):
- setFieldIf(drvoSupportsFieldNullable,
- 'Nullable', v, fld_def2, fld_name, drvo.ShortName)
- elif k2 == 'unique' and v is not None and isinstance(v, bool):
- setFieldIf(drvoSupportsFieldUnique,
- 'Unique', v, fld_def2, fld_name, drvo.ShortName)
- else:
- raise Exception(f'Field "{fld_name}" has unknown key "{k}"')
-
- fields[idx] = fld_def2
-
-# Return the decoded Spatial Reference System
-def getSRS(srs_str):
- if srs_str is None:
- return
- srs = osr.SpatialReference()
- if srs_str.startswith('EPSG:'):
- code = int(srs_str.removeprefix('EPSG:'))
- srs.ImportFromEPSG(code)
- else:
- raise Exception(f'Unknown SRS {srs_str}')
- logging.debug('Default SRS: "%s" (%s)', srs.ExportToProj4(), srs.GetName())
- return srs
-
-# Convert extent [minX, minY, maxX, maxY] into a polygon and assign the
-# given SRS. Like apps/ogr2ogr_lib.cpp, we segmentize the polygon to
-# make sure it is sufficiently densified when transforming to source
-# layer SRS for spatial filtering.
-def getExtent(extent, srs=None):
- if extent is None:
- return
-
- if not (isinstance(extent, list) or isinstance(extent, tuple)) or len(extent) != 4:
- raise Exception(f'Invalid extent {extent}')
- elif srs is None:
- raise Exception('Configured extent but no SRS')
-
- logging.debug('Configured extent in %s: %s',
- srs.GetName(), ', '.join(map(str, extent)))
-
- ring = ogr.Geometry(ogr.wkbLinearRing)
- ring.AddPoint_2D(extent[0], extent[1])
- ring.AddPoint_2D(extent[2], extent[1])
- ring.AddPoint_2D(extent[2], extent[3])
- ring.AddPoint_2D(extent[0], extent[3])
- ring.AddPoint_2D(extent[0], extent[1])
-
- polygon = ogr.Geometry(ogr.wkbPolygon)
- polygon.AddGeometry(ring)
-
- # we expressed extent as minX, minY, maxX, maxY (easting/northing
- # ordered, i.e., in traditional GIS order)
- srs2 = srs.Clone()
- srs2.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER)
- polygon.AssignSpatialReference(srs2)
- polygon.TransformTo(srs)
-
- segment_distance_metre = 10 * 1000
- if srs.IsGeographic():
- dfMaxLength = segment_distance_metre / math.radians(srs.GetSemiMajor())
- polygon.Segmentize(dfMaxLength)
- elif srs.IsProjected():
- dfMaxLength = segment_distance_metre / srs.GetLinearUnits()
- polygon.Segmentize(dfMaxLength)
-
- return polygon
-
-# Validate the output layer against the provided SRS and creation options
-def validateOutputLayer(lyr, srs=None, options=None):
- ok = True
-
- # ensure the output SRS is equivalent
- if srs is not None:
- srs2 = lyr.GetSpatialRef()
- # cf. apps/ogr2ogr_lib.cpp
- srs_options = [
- 'IGNORE_DATA_AXIS_TO_SRS_AXIS_MAPPING=YES',
- 'CRITERION=EQUIVALENT'
- ]
- if not srs.IsSame(srs2, srs_options):
- logging.warning('Output layer "%s" has SRS %s,\nexpected %s',
- lyr.GetName(),
- srs2.ExportToPrettyWkt(),
- srs.ExportToPrettyWkt())
- ok = False
-
- if options is None:
- return ok
-
- layerDefn = lyr.GetLayerDefn()
- n = layerDefn.GetGeomFieldCount()
- if n != 1:
- logging.warning('Output layer "%s" has %d != 1 geometry fields', layername, n)
-
- geom_type1 = lyr.GetGeomType()
- geom_type2 = options['geometry-type']
- if geom_type1 != geom_type2:
- logging.warning('Output layer "%s" has geometry type #%d (%s), expected #%d (%s)',
- lyr.GetName(),
- geom_type1, ogr.GeometryTypeToName(geom_type1),
- geom_type2, ogr.GeometryTypeToName(geom_type2))
- ok = False
-
- fields = options.get('fields', None)
- if fields is not None:
- for fld in fields:
- fldName = fld['Name']
-
- idx = layerDefn.GetFieldIndex(fldName)
- if idx < 0:
- logging.warning('Output layer "%s" has no field named "%s"',
- lyr.GetName(), fldName)
- ok = False
- continue
- defn = layerDefn.GetFieldDefn(idx)
-
- if 'AlternativeName' in fld:
- v1 = defn.GetAlternativeName()
- v2 = fld['AlternativeName']
- if v1 != v2:
- logging.warning('Field "%s" has AlternativeName="%s", expected "%s"',
- fldName, v1, v2)
- ok = False
-
- if 'Comment' in fld:
- v1 = defn.GetComment()
- v2 = fld['Comment']
- if v1 != v2:
- logging.warning('Field "%s" has Comment="%s", expected "%s"',
- fldName, v1, v2)
- ok = False
-
- if 'Type' in fld:
- v1 = defn.GetType()
- v2 = fld['Type']
- if v1 != v2:
- logging.warning('Field "%s" has Type=%d (%s), expected %d (%s)',
- fldName,
- v1, ogr.GetFieldTypeName(v1),
- v2, ogr.GetFieldTypeName(v2))
- ok = False
-
- if 'SubType' in fld:
- v1 = defn.GetSubType()
- v2 = fld['SubType']
- if v1 != v2:
- logging.warning('Field "%s" has SubType=%d (%s), expected %d (%s)',
- fldName,
- v1, ogr.GetFieldSubTypeName(v1),
- v2, ogr.GetFieldSubTypeName(v2))
- ok = False
-
- if 'TZFlag' in fld:
- v1 = defn.GetTZFlag()
- v2 = fld['TZFlag']
- if v1 != v2:
- logging.warning('Field "%s" has TZFlag=%d (%s), expected %d (%s)',
- fldName, v1, formatTZFlag(v1), v2, formatTZFlag(v2))
- ok = False
-
- if 'Precision' in fld:
- v1 = defn.GetPrecision()
- v2 = fld['Precision']
- if v1 != v2:
- logging.warning('Field "%s" has Precision=%d, expected %d',
- fldName, v1, v2)
- ok = False
-
- if 'Width' in fld:
- v1 = defn.GetWidth()
- v2 = fld['Width']
- if v1 != v2:
- logging.warning('Field "%s" has Width=%d, expected %d',
- fldName, v1, v2)
- ok = False
-
- if 'Default' in fld:
- v1 = defn.GetDefault()
- v2 = fld['Default']
- if v1 != v2:
- logging.warning('Field "%s" has Default="%s", expected "%s"',
- fldName, v1, v2)
- ok = False
-
- if 'Nullable' in fld:
- v1 = bool(defn.IsNullable())
- v2 = fld['Nullable']
- if v1 != v2:
- logging.warning('Field "%s" has Nullable=%s, expected %s',
- fldName, v1, v2)
- ok = False
-
- if 'Unique' in fld:
- v1 = bool(defn.IsUnique())
- v2 = fld['Unique']
- if v1 != v2:
- logging.warning('Field "%s" has Unique=%s, expected %s',
- fldName, v1, v2)
- ok = False
-
- return ok
-
-# Create output layer
-def createOutputLayer(ds, layername, srs=None, options=None):
- logging.info('Creating new destination layer "%s"', layername)
- geom_type = options['geometry-type']
- lco = options.get('options', None)
-
- drv = ds.GetDriver()
- if geom_type != ogr.wkbNone and drv.ShortName == 'PostgreSQL':
- # “Important to set to 2 for 2D layers as it has constraints on the geometry
- # dimension during loading.”
- # — https://gdal.org/drivers/vector/pg.html#layer-creation-options
- if ogr.GT_HasM(geom_type):
- if ogr.GT_HasZ(geom_type):
- dim = 'XYZM'
- else:
- dim = 'XYM'
- elif ogr.GT_HasZ(geom_type):
- dim = '3'
- else:
- dim = '2'
- if lco is None:
- lco = []
- lco = ['dim=' + dim] + lco # prepend dim=
-
- kwargs = { 'geom_type': geom_type }
- if srs is not None:
- kwargs['srs'] = srs
- if lco is not None:
- kwargs['options'] = lco
- logging.debug('CreateLayer(%s, geom_type="%s"%s%s)', layername,
- ogr.GeometryTypeToName(geom_type),
- ', srs="' + kwargs['srs'].GetName() + '"' if 'srs' in kwargs else '',
- ', options=' + str(kwargs['options']) if 'options' in kwargs else '')
- lyr = dso.CreateLayer(layername, **kwargs)
- if lyr is None:
- raise Exception(f'Could not create destination layer "{layername}"')
-
- fields = options['fields']
- if len(fields) > 0 and not lyr.TestCapability(ogr.OLCCreateField):
- raise Exception(f'Destination layer "{layername}" lacks field creation capability')
-
- # set up output schema
- for fld in fields:
- fldName = fld['Name']
- defn = ogr.FieldDefn()
- defn.SetName(fldName)
-
- if 'AlternativeName' in fld:
- v = fld['AlternativeName']
- logging.debug('Set AlternativeName="%s" on output field "%s"', str(v), fldName)
- defn.SetAlternativeName(v)
-
- if 'Comment' in fld:
- v = fld['Comment']
- logging.debug('Set Comment="%s" on output field "%s"', str(v), fldName)
- defn.SetComment(v)
-
- if 'Type' in fld:
- v = fld['Type']
- logging.debug('Set Type=%d (%s) on output field "%s"',
- v, ogr.GetFieldTypeName(v), fldName)
- defn.SetType(v)
-
- if 'SubType' in fld:
- v = fld['SubType']
- logging.debug('Set SubType=%d (%s) on output field "%s"',
- v, ogr.GetFieldSubTypeName(v), fldName)
- defn.SetSubType(v)
-
- if 'TZFlag' in fld:
- v = fld['TZFlag']
- logging.debug('Set TZFlag=%d (%s) on output field "%s"',
- v, formatTZFlag(v), fldName)
- defn.SetTZFlag(v)
-
- if 'Precision' in fld:
- v = fld['Precision']
- logging.debug('Set Precision=%d on output field "%s"', v, fldName)
- defn.SetPrecision(v)
-
- if 'Width' in fld:
- v = fld['Width']
- logging.debug('Set Width=%d on output field "%s"', v, fldName)
- defn.SetWidth(v)
-
- if 'Default' in fld:
- v = fld['Default']
- logging.debug('Set Default=%s on output field "%s"', v, fldName)
- defn.SetDefault(v)
-
- if 'Nullable' in fld:
- v = fld['Nullable']
- logging.debug('Set Nullable=%s on output field "%s"', v, fldName)
- defn.SetNullable(v)
-
- if 'Unique' in fld:
- v = fld['Unique']
- logging.debug('Set Unique=%s on output field "%s"', v, fldName)
- defn.SetUnique(v)
-
- if lyr.CreateField(defn, approx_ok=False) != GDAL_CE_None:
- raise Exception('Could not create field "{fldName}"')
- logging.debug('Added field "%s" to output layer "%s"', fldName, layername)
-
- # flush before calling StartTransaction() so we're not tryingn to
- # rollback changes on a non-existing table
- lyr.SyncToDisk()
- return lyr
-
-# Setup output field mapping, modifying the sources dictionary in place.
-def setOutputFieldMap(defn, sources):
- fieldMap = {}
- n = defn.GetFieldCount()
- for i in range(n):
- fld = defn.GetFieldDefn(i)
- fldName = fld.GetName()
- fieldMap[fldName] = i
-
- for source in sources:
- source_import = source['import']
-
- fieldMap2 = source_import.get('field-map', None)
- if fieldMap2 is None:
- fieldMap2 = fieldMap
- else:
- if isinstance(fieldMap2, list):
- # convert list to identity dictionary
- fieldMap2 = { fld: fld for fld in fieldMap2 }
-
- for ifld, ofld in fieldMap2.items():
- i = fieldMap.get(ofld, None)
- if i is None:
- raise Exception(f'Ouput layer has no field named "{ofld}"')
- fieldMap2[ifld] = i
- source_import['field-map'] = fieldMap2
-
- # validate field value mapping
- valueMap = source_import.get('value-map', None)
- if valueMap is not None:
- for fldName, rules in valueMap.items():
- if rules is None:
- continue
- if not isinstance(rules, list):
- rules = [rules]
- for idx, rule in enumerate(rules):
- if rule is None or not isinstance(rule, dict):
- raise Exception(f'Field "{fldName}" has invalid rule #{idx}: {rule}')
- if 'type' not in rule:
- ruleType = rule['type'] = 'literal'
- else:
- ruleType = rule['type']
- if ('replace' not in rule or 'with' not in rule or len(rule) != 3 or
- ruleType is None or ruleType not in ['literal', 'regex']):
- raise Exception(f'Field "{fldName}" has invalid rule #{idx}: {rule}')
- if ruleType == 'regex':
- rule['replace'] = re.compile(rule['replace'])
- rules[idx] = ( rule['replace'], rule['with'] )
-
-# Escape the given identifier, cf.
-# swig/python/gdal-utils/osgeo_utils/samples/validate_gpkg.py:_esc_id()
-def escapeIdentifier(identifier):
- if '\x00' in identifier:
- raise Exception(f'Invalid identifier "{identifier}"')
- # SQL:1999 delimited identifier
- return '"' + identifier.replace('"', '""') + '"'
-
-# Clear the given layer (wipe all its features)
-def clearLayer(ds, lyr):
- n = -1
- if lyr.TestCapability(ogr.OLCFastFeatureCount):
- n = lyr.GetFeatureCount(force=0)
- if n == 0:
- # nothing to clear, we're good
- return
- layername_esc = escapeIdentifier(lyr.GetName())
-
- # XXX GDAL <3.9 doesn't have lyr.GetDataset() so we pass the DS along with the layer
- drv = ds.GetDriver()
- if drv.ShortName == 'PostgreSQL':
- # https://www.postgresql.org/docs/15/sql-truncate.html
- query = 'TRUNCATE TABLE {table} CONTINUE IDENTITY RESTRICT'
- op = 'Truncating'
- else:
- query = 'DELETE FROM {table}'
- op = 'Clearing'
- logging.info('%s table %s (former feature count: %s)', op,
- layername_esc, str(n) if n >= 0 else 'unknown')
- ds.ExecuteSQL(query.format(table=layername_esc))
-
-# Extract an archive file into the given destination directory.
-def extractArchive(path, destdir, fmt=None, patterns=None, exact_matches=None):
- if fmt is None:
- suffix = path.suffix
- if suffix is None or suffix == '' or not suffix.startswith('.'):
- raise Exception(f'Could not infer archive format from "{path}"')
- fmt = suffix.removeprefix('.')
-
- fmt = fmt.lower()
- logging.debug('Unpacking %s archive %s into %s', fmt, path, destdir)
-
- if fmt == 'zip':
- from zipfile import ZipFile
- logging.debug('Opening %s as ZipFile', path)
- with ZipFile(path, mode='r') as z:
- namelist = listArchiveMembers(z.namelist(),
- patterns=patterns, exact_matches=exact_matches)
- z.extractall(path=destdir, members=namelist)
- else:
- raise Exception(f'Unknown archive format "{fmt}"')
-
-# List archive members matching the given parterns and/or exact matches
-def listArchiveMembers(namelist, patterns, exact_matches=None):
- if patterns is None and exact_matches is None:
- # if neither patterns nor exact_matches are given we'll extract the entire archive
- return namelist
- if patterns is None:
- patterns = []
- if exact_matches is None:
- exact_matches = []
-
- members = []
- for name in namelist:
- ok = False
- if name in exact_matches:
- # try exact matches first
- logging.debug('Listed archive member %s (exact match)', name)
- members.append(name)
- ok = True
- continue
- # if there are no exact matches, try patterns one by one in the supplied order
- for pat in patterns:
- if fnmatchcase(name, pat):
- logging.debug('Listed archive member %s (matching pattern "%s")', name, pat)
- members.append(name)
- ok = True
- break
- if not ok:
- logging.debug('Ignoring archive member %s', name)
- return members
-
-# Import a source layer
-def importSource(lyr, path=None, unar=None, args={}, cachedir=None, extent=None):
- if unar is None:
- return importSource2(lyr, str(path), args=args,
- basedir=cachedir, extent=extent)
-
- if cachedir is not None:
- path = cachedir.joinpath(path)
-
- ds_srcpath = Path(args['path'])
- if ds_srcpath.is_absolute():
- # treat absolute paths as relative to the archive root
- logging.warning('%s is absolute, removing leading anchor', ds_srcpath)
- ds_srcpath = ds_srcpath.relative_to(ds_srcpath.anchor)
- ds_srcpath = str(ds_srcpath)
-
- with tempfile.TemporaryDirectory() as tmpdir:
- logging.debug('Created temporary directory %s', tmpdir)
- extractArchive(path, tmpdir,
- fmt=unar.get('format', None),
- patterns=unar.get('patterns', None),
- exact_matches=[ds_srcpath])
- return importSource2(lyr, ds_srcpath, args=args,
- basedir=Path(tmpdir), extent=extent)
-
-# Validate field value mapping
-def setFieldMapValue(fld, idx, val):
- if val is None:
- if not fld.IsNullable():
- logging.warning('Field "%s" is not NULLable but remaps NULL', fld.GetName())
- return None
-
- fldType = fld.GetType()
- if fldType == ogr.OFTInteger or fldType == ogr.OFTInteger64:
- if isinstance(val, int):
- return val
- elif fldType == ogr.OFTString:
- if isinstance(val, str):
- return val
- elif fldType == ogr.OFTBinary:
- if isinstance(val, bytes):
- return val
- elif fldType == ogr.OFTReal:
- if isinstance(val, int):
- return float(val)
- elif isinstance(val, float):
- return val
-
- raise Exception(f'Field "{fld.GetName()}" mapping #{idx} has incompatible type for {ogr.GetFieldTypeName(fldType)}')
-
-# Import a source layer (already extracted)
-# This is more or less like ogr2ogr/GDALVectorTranslate() but we roll
-# out our own (slower) version because GDALVectorTranslate() insists in
-# calling StartTransaction() https://github.com/OSGeo/gdal/issues/3403
-# while we want a single transaction for the entire desination layer,
-# including truncation, source imports, and metadata changes.
-def importSource2(lyr_dst, path, args={}, basedir=None, extent=None):
- kwargs, _ = setOpenExArgs(args, flags=GDAL_OF_READONLY|GDAL_OF_VERBOSE_ERROR)
- path2 = path if basedir is None else str(basedir.joinpath(path))
-
- logging.debug('OpenEx(%s, %s)', path2, str(kwargs))
- ds = gdal.OpenEx(path2, **kwargs)
- if ds is None:
- raise Exception(f'Could not open {path2}')
-
- layername = args.get('layername', None)
- if layername is None:
- idx = 0
- lyr = ds.GetLayerByIndex(idx)
- msg = '#' + str(idx)
- if lyr is not None:
- layername = lyr.GetName()
- msg += ' ("' + layername + '")'
- else:
- lyr = ds.GetLayerByName(layername)
- msg = '"' + layername + '"'
- if lyr is None:
- raise Exception(f'Could not get requested layer {msg} from {path2}')
-
- logging.info('Importing layer %s from "%s"', msg, path)
- canIgnoreFields = lyr.TestCapability(ogr.OLCIgnoreFields)
-
- srs = lyr.GetSpatialRef()
- if srs is None:
- raise Exception('Source layer has no SRS')
-
- srs_dst = lyr_dst.GetSpatialRef()
- if srs_dst is None:
- logging.warning('Destination has no SRS, skipping coordinate transformation')
- ct = None
- elif srs_dst.IsSame(srs):
- logging.debug('Both source and destination have the same SRS (%s), skipping coordinate transformation',
- srs_dst.GetName())
- ct = None
- else:
- # TODO Use GetSupportedSRSList() and SetActiveSRS() with GDAL ≥3.7.0
- # when possible, see apps/ogr2ogr_lib.cpp
- logging.debug('Creating transforming from source SRS (%s) to destination SRS (%s)',
- srs.GetName(), srs_dst.GetName())
- ct = osr.CoordinateTransformation(srs, srs_dst)
- if ct is None:
- raise Exception(f'Could not create transformation from source SRS ({srs.GetName()}) '
- + f'to destination SRS ({srs_dst.GetName()})')
-
- defn = lyr.GetLayerDefn()
- geomFieldCount = defn.GetGeomFieldCount()
- if geomFieldCount != 1: # TODO Add support for multiple geometry fields
- logging.warning('Source layer "%s" has %d != 1 geometry fields', layername, geomFieldCount)
-
- fieldCount = defn.GetFieldCount()
- fieldMap = [-1] * fieldCount
- fields = args['field-map']
- fieldSet = set()
-
- for i in range(fieldCount):
- fld = defn.GetFieldDefn(i)
- fldName = fld.GetName()
- fieldMap[i] = v = fields.get(fldName, -1)
- fieldSet.add(fldName)
-
- if v < 0 and canIgnoreFields:
- # call SetIgnored() on unwanted source fields
- logging.debug('Set Ignored=True on output field "%s"', fldName)
- fld.SetIgnored(True)
-
- count0 = -1
- if lyr.TestCapability(ogr.OLCFastFeatureCount):
- count0 = lyr.GetFeatureCount(force=0)
-
- if count0 == 0 and len(fieldSet) == 0:
- # skip the below warning in some cases (e.g., GeoJSON source)
- logging.info('Source layer "%s" has no fields nor features, skipping', layername)
- return
-
- logging.debug('Field map: %s', str(fieldMap))
- for fld in fields:
- if not fld in fieldSet:
- logging.warning('Source layer "%s" has no field named "%s", ignoring', layername, fld)
-
- count1 = -1
- if args.get('spatial-filter', True) and extent is not None:
- if extent.GetSpatialReference().IsSame(srs):
- extent2 = extent
- else:
- extent2 = extent.Clone()
- if extent2.TransformTo(srs) != ogr.OGRERR_NONE:
- raise Exception(f'Could not transform extent {extent.ExportToWkt()} to {srs.GetName()}')
-
- #logging.debug('Applying extent: %s', extent2.ExportToWkt())
- lyr.SetSpatialFilter(extent2)
-
- if lyr.TestCapability(ogr.OLCFastFeatureCount):
- count1 = lyr.GetFeatureCount(force=0)
-
- if count0 >= 0:
- if count1 >= 0:
- logging.info('Source layer "%s" has %d features (of which %d within extent)',
- layername, count0, count1)
- else:
- logging.info('Source layer "%s" has %d features', layername, count0)
-
- # build a list of triplets (field index, replacement_for_null, [(from_value, to_value), …])
- valueMap = []
- for fldName, rules in args.get('value-map', {}).items():
- i = defn.GetFieldIndex(fldName)
- if i < 0:
- raise Exception(f'Source layer "{layername}" has no field named "{fldName}"')
- if fieldMap[i] < 0:
- logging.warning('Ignored source field "%s" has value map', fldName)
- continue
-
- hasNullReplacement = False
- nullReplacement = None
- mapping = []
- fld = defn.GetFieldDefn(i)
- for idx, (rFrom, rTo) in enumerate(rules):
- # use fld for both 'from' and 'to' (the types must match, casting is not allowed in the mapping)
- if rFrom is None:
- if hasNullReplacement:
- logging.warning('Field "%s" has duplicate NULL replacement', fld.GetName())
- else:
- setFieldMapValue(fld, idx, None) # validate NULL
- rTo = setFieldMapValue(fld, idx, rTo)
- hasNullReplacement = True
- nullReplacement = rTo
- elif isinstance(rFrom, re.Pattern):
- # validate but keep the rFrom regex
- setFieldMapValue(fld, idx, str(rFrom))
- rTo = setFieldMapValue(fld, idx, rTo)
- mapping.append( (rFrom, rTo, 1) )
- else:
- rFrom = setFieldMapValue(fld, idx, rFrom)
- rTo = setFieldMapValue(fld, idx, rTo)
- mapping.append( (rFrom, rTo, 0) )
-
- if nullReplacement is not None or len(mapping) > 0:
- valueMap.append( (i, nullReplacement, mapping) )
-
- bValueMap = len(valueMap) > 0
- defn = None
-
- defn_dst = lyr_dst.GetLayerDefn()
- eGType_dst = defn_dst.GetGeomType()
- eGType_dst_HasZ = ogr.GT_HasZ(eGType_dst)
- eGType_dst_HasM = ogr.GT_HasM(eGType_dst)
- dGeomIsUnknown = ogr.GT_Flatten(eGType_dst) == ogr.wkbUnknown
-
- if bValueMap:
- valueMapCounts = [0] * fieldCount
-
- featureCount = 0
- mismatch = {}
- feature = lyr.GetNextFeature()
- while feature is not None:
- if bValueMap:
- for i, nullReplacement, mapping in valueMap:
- if not feature.IsFieldSet(i):
- continue
- elif feature.IsFieldNull(i):
- if nullReplacement is not None:
- # replace NULL with non-NULL value
- feature.SetField(i, nullReplacement)
- valueMapCounts[i] += 1
- continue
-
- v = feature.GetField(i)
- for rFrom, rTo, rType in mapping:
- if rType == 0:
- # literal
- if v != rFrom:
- continue
- elif rType == 1:
- # regex
- m = rFrom.fullmatch(v)
- if m is None:
- continue
- elif rTo is not None:
- rTo = rTo.format(*m.groups())
- else:
- raise Exception(str(rType))
-
- if rTo is None:
- # replace non-NULL value with NULL
- feature.SetFieldNull(i)
- else:
- # replace non-NULL value with non-NULL value
- feature.SetField(i, rTo)
- valueMapCounts[i] += 1
- break
-
- feature2 = ogr.Feature(defn_dst)
- feature2.SetFromWithMap(feature, False, fieldMap)
-
- geom = feature2.GetGeometryRef()
- if ct is not None and geom.Transform(ct) != ogr.OGRERR_NONE:
- raise Exception('Could not apply coordinate transformation')
-
- eGType = geom.GetGeometryType()
- if eGType != eGType_dst and not dGeomIsUnknown:
- # Promote to multi, cf. apps/ogr2ogr_lib.cpp:ConvertType()
- eGType2 = eGType
- if eGType == ogr.wkbTriangle or eGType == ogr.wkbTIN or eGType == ogr.wkbPolyhedralSurface:
- eGType2 = ogr.wkbMultiPolygon
- elif not ogr.GT_IsSubClassOf(eGType, ogr.wkbGeometryCollection):
- eGType2 = ogr.GT_GetCollection(eGType)
-
- eGType2 = ogr.GT_SetModifier(eGType2, eGType_dst_HasZ, eGType_dst_HasM)
- if eGType2 == eGType_dst:
- mismatch[eGType] = mismatch.get(eGType, 0) + 1
- geom = ogr.ForceTo(geom, eGType_dst)
- # TODO call MakeValid()?
- else:
- raise Exception(f'Conversion from {ogr.GeometryTypeToName(eGType)} '
- f'to {ogr.GeometryTypeToName(eGType_dst)} not implemented')
- feature2.SetGeometryDirectly(geom)
-
- if lyr_dst.CreateFeature(feature2) != ogr.OGRERR_NONE:
- raise Exception(f'Could not transfer source feature #{feature.GetFID()}')
-
- featureCount += 1
- feature = lyr.GetNextFeature()
-
- if bValueMap:
- valueMapCounts = [ (lyr.GetLayerDefn().GetFieldDefn(i).GetName(), k) for i,k in enumerate(valueMapCounts) if k > 0 ]
-
- lyr = None
- logging.info('Imported %d features from source layer "%s"', featureCount, layername)
-
- if bValueMap:
- if len(valueMapCounts) > 0:
- valueMapCounts = ', '.join([ str(k) + '× "' + n + '"' for n,k in valueMapCounts ])
- else:
- valueMapCounts = '-'
- logging.info('Field substitutions: %s', valueMapCounts)
-
- if len(mismatch) > 0:
- mismatches = [ str(n) + '× ' + ogr.GeometryTypeToName(t)
- for t,n in sorted(mismatch.items(), key=lambda x: x[1]) ]
- logging.info('Forced conversion to %s: %s',
- ogr.GeometryTypeToName(eGType_dst), ', '.join(mismatches))
-
-
-if __name__ == '__main__':
- common.init_logger(app=os.path.basename(__file__), level=logging.INFO)
-
- parser = argparse.ArgumentParser(description='Extract and import GIS layers.')
- parser.add_argument('--cachedir', default=None,
- help=f'cache directory (default: {os.curdir})')
- parser.add_argument('--debug', action='count', default=0,
- help=argparse.SUPPRESS)
- parser.add_argument('groupname', nargs='*', help='group layer name(s) to process')
- args = parser.parse_args()
-
- if args.debug > 0:
- logging.getLogger().setLevel(logging.DEBUG)
- if args.debug > 1:
- gdal.ConfigurePythonLogging(enable_debug=True)
-
- common.load_config(groupnames=None if args.groupname == [] else args.groupname)
-
- # validate configuration
- if 'dataset' not in common.config:
- raise Exception('Configuration does not specify output dataset')
-
- layers = common.config.get('layers', {})
- for layername, layerdefs in layers.items():
- for idx, layerdef in enumerate(layerdefs['sources']):
- importdef = layerdef.get('import', None)
- if importdef is None:
- raise Exception(f'Output layer "{layername}" source #{idx} has no import definition')
-
- sourcedef = layerdef.get('source', None)
- unar = None if sourcedef is None else sourcedef.get('unar', None)
- src = None if sourcedef is None else sourcedef['cache'].get('path', None)
-
- ds_srcpath = importdef.get('path', None)
- if src is None and unar is None and ds_srcpath is not None:
- # fallback to importe:path if there is no unarchiving receipe
- src = Path(ds_srcpath)
- if unar is not None and ds_srcpath is None:
- raise Exception(f'Output layer "{layername}" source #{idx} has no import source path')
- if src is None:
- raise Exception(f'Output layer "{layername}" source #{idx} has no source path')
- layerdef['source'] = { 'path': src, 'unar': unar }
-
- # set global GDAL/OGR configuration options
- for pszKey, pszValue in common.config.get('GDALconfig', {}).items():
- logging.debug('gdal.SetConfigOption(%s, %s)', pszKey, pszValue)
- gdal.SetConfigOption(pszKey, pszValue)
-
- # open output dataset (possibly create it first)
- dso = openOutputDS(common.config['dataset'])
-
- validateSchema(layers,
- drvo=dso.GetDriver(),
- lco_defaults=common.config['dataset'].get('create-layer-options', None))
-
- # get configured Spatial Reference System and extent
- srs = getSRS(common.config.get('SRS', None))
- extent = getExtent(common.config.get('extent', None), srs=srs)
-
- cachedir = Path(args.cachedir) if args.cachedir is not None else None
- rv = 0
- for layername, layerdef in layers.items():
- sources = layerdef['sources']
- if sources is None or len(sources) < 1:
- logging.warning('Output layer "%s" has no definition, skipping', layername)
- continue
-
- logging.info('Processing output layer "%s"', layername)
- transaction = False
- try:
- # get output layer
- outLayerIsNotEmpty = True
- lco = layerdef.get('create', None)
- lyr = dso.GetLayerByName(layername)
- if lyr is not None:
- # TODO dso.DeleteLayer(layername) if --overwrite and dso.TestCapability(ogr.ODsCDeleteLayer)
- # (Sets OVERWRITE=YES for PostgreSQL and GPKG.)
- validateOutputLayer(lyr, srs=srs, options=lco)
- # TODO bail out if all source files are older than lyr's last_change
- elif not dso.TestCapability(ogr.ODsCCreateLayer):
- raise Exception(f'Output driver {dso.GetDriver().ShortName} does not support layer creation')
- elif lco is None or len(lco) < 1:
- raise Exception(f'Missing schema for new output layer "{layername}"')
- else:
- lyr = createOutputLayer(dso, layername, srs=srs, options=lco)
- outLayerIsNotEmpty = False
-
- if not lyr.TestCapability(ogr.OLCSequentialWrite):
- raise Exception(f'Output layer "{layername}" has no working CreateFeature() method')
-
- # setup output field mapping in the sources dictionary
- setOutputFieldMap(lyr.GetLayerDefn(), sources)
-
- # start transaction if possible
- if lyr.TestCapability(ogr.OLCTransactions):
- logging.debug('Starting transaction')
- transaction = lyr.StartTransaction() == ogr.OGRERR_NONE
- else:
- logging.warning('Unsafe update, output layer "%s" does not support transactions', layername)
-
- if outLayerIsNotEmpty:
- # clear non-empty output layer
- clearLayer(dso, lyr)
-
- description = layerdef.get('description', None)
- if description is not None and lyr.SetMetadataItem('DESCRIPTION', description) != GDAL_CE_None:
- logging.warning('Could not set description metadata')
-
- for source in sources:
- # import source layers
- importSource(lyr, **source['source'], args=source['import'],
- cachedir=cachedir, extent=extent)
-
- if transaction:
- # commit transaction
- logging.debug('Committing transaction')
- transaction = False
- if lyr.CommitTransaction() != ogr.OGRERR_NONE:
- logging.error('Could not commit transaction')
- rv = 1
-
- except Exception:
- if transaction:
- logging.error('Exception occured in transaction, rolling back')
- try:
- if lyr.RollbackTransaction() != ogr.OGRERR_NONE:
- logging.error('Could not rollback transaction')
- except RuntimeError:
- logging.exception('Could not rollback transaction')
- logging.exception('Could not import layer "%s"', layername)
- rv = 1
-
- finally:
- # close output layer
- lyr = None
-
- dso = None
- srs = None
- extent = None
- exit(rv)