mirror of
https://github.com/bringout/oca-technical.git
synced 2026-04-19 17:32:02 +02:00
Initial commit: OCA Technical packages (595 packages)
This commit is contained in:
commit
2cc02aac6e
24950 changed files with 2318079 additions and 0 deletions
45
odoo-bringout-oca-geospatial-base_geoengine/README.md
Normal file
45
odoo-bringout-oca-geospatial-base_geoengine/README.md
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
# Geospatial support for Odoo
|
||||
|
||||
Odoo addon: base_geoengine
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
pip install odoo-bringout-oca-geospatial-base_geoengine
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
This addon depends on:
|
||||
- base
|
||||
- web
|
||||
|
||||
## Manifest Information
|
||||
|
||||
- **Name**: Geospatial support for Odoo
|
||||
- **Version**: 16.0.1.2.0
|
||||
- **Category**: GeoBI
|
||||
- **License**: AGPL-3
|
||||
- **Installable**: True
|
||||
|
||||
## Source
|
||||
|
||||
Based on [OCA/geospatial](https://github.com/OCA/geospatial) branch 16.0, addon `base_geoengine`.
|
||||
|
||||
## License
|
||||
|
||||
This package maintains the original AGPL-3 license from the upstream Odoo project.
|
||||
|
||||
## Documentation
|
||||
|
||||
- Overview: doc/OVERVIEW.md
|
||||
- Architecture: doc/ARCHITECTURE.md
|
||||
- Models: doc/MODELS.md
|
||||
- Controllers: doc/CONTROLLERS.md
|
||||
- Wizards: doc/WIZARDS.md
|
||||
- Install: doc/INSTALL.md
|
||||
- Usage: doc/USAGE.md
|
||||
- Configuration: doc/CONFIGURATION.md
|
||||
- Dependencies: doc/DEPENDENCIES.md
|
||||
- Troubleshooting: doc/TROUBLESHOOTING.md
|
||||
- FAQ: doc/FAQ.md
|
||||
|
|
@ -0,0 +1,307 @@
|
|||
.. image:: https://odoo-community.org/readme-banner-image
|
||||
:target: https://odoo-community.org/get-involved?utm_source=readme
|
||||
:alt: Odoo Community Association
|
||||
|
||||
===========================
|
||||
Geospatial support for Odoo
|
||||
===========================
|
||||
|
||||
..
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!! This file is generated by oca-gen-addon-readme !!
|
||||
!! changes will be overwritten. !!
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!! source digest: sha256:2faa9b7de06a2c3c20d9bc960073bdc6638396bc987e338093331e0099278604
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
|
||||
:target: https://odoo-community.org/page/development-status
|
||||
:alt: Beta
|
||||
.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png
|
||||
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
|
||||
:alt: License: AGPL-3
|
||||
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fgeospatial-lightgray.png?logo=github
|
||||
:target: https://github.com/OCA/geospatial/tree/16.0/base_geoengine
|
||||
:alt: OCA/geospatial
|
||||
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
|
||||
:target: https://translation.odoo-community.org/projects/geospatial-16-0/geospatial-16-0-base_geoengine
|
||||
:alt: Translate me on Weblate
|
||||
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
|
||||
:target: https://runboat.odoo-community.org/builds?repo=OCA/geospatial&target_branch=16.0
|
||||
:alt: Try me on Runboat
|
||||
|
||||
|badge1| |badge2| |badge3| |badge4| |badge5|
|
||||
|
||||
GeoEngine is an Odoo module that adds spatial/GIS capabilites to Odoo. It will allow you to :
|
||||
|
||||
* Visualize and query your business information on map
|
||||
* Perform GeoBI and spatial query
|
||||
* Configure your spatial layers and spatial datasources
|
||||
* Extend Odoo models with spatial columns
|
||||
|
||||
GeoEngine relies on `OpenLayers <http://openlayers.org>`_ and `PostgGIS <http://postgis.refractions.net/>`_ technologies.
|
||||
|
||||
Postgis is used to store spatial information in databases. OpenLayer is used to represent spatial data in other words to show maps
|
||||
and the different spatial layers. The GeoEngine module acts as a data provider and as an OpenLayers configurator.
|
||||
It also provides a complete extension to Odoo ORM.
|
||||
|
||||
**Table of contents**
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
|
||||
To install this module, you need to have `PostGIS <http://postgis.net/>`_ installed.
|
||||
|
||||
On Ubuntu::
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo apt-get install postgis
|
||||
|
||||
The module also requires two additional python libs:
|
||||
|
||||
* `Shapely <http://pypi.python.org/pypi/Shapely>`_
|
||||
|
||||
* `geojson <http://pypi.python.org/pypi/geojson>`_
|
||||
|
||||
When you will install the module this two additional libs will be installed.
|
||||
|
||||
For a complete documentation please refer to the `public documenation <http://oca.github.io/geospatial/index.html>`_
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
Geoengine Demo
|
||||
==============
|
||||
|
||||
1. As a user/admin, when I am in the Geoengine Demo module and I go to the ZIP menu.
|
||||
When I click on an item in the list view, I get to the form view showing me the different
|
||||
information about the ZIP. We can see its ZIP, city, priority, total sales and his spatial
|
||||
representation.
|
||||
2. As a user, I can't modify the information in the form view.
|
||||
3. As an admin, I can modify the information in the form view. I can click on the bin button to clear
|
||||
the map and I can draw a new shape.
|
||||
4. As a user, when I go the "Retail machines" tab and there are no items to display, it does not
|
||||
show me anything.
|
||||
5. As an admin, when I go the "Retail machines" tab and there are no items to display, the list view of
|
||||
the retail machines suggests to me to add a new line.
|
||||
6. As a user/admin, if there are items to be displayed in the "Retail machines" tab then I can click on an
|
||||
item and the retail machines form view will be displayed. We can see its spatial representation by going
|
||||
to "The point" tab and its attributes in "Attributes" tab.
|
||||
7. As a user/admin, when I go to the geoengine zip view by clicking on the map button at the top right of the
|
||||
screen. The geoengine view appears with the first 80 results displayed on the map. The vector layers
|
||||
selected are those defined as "active on startup" by the admin. The selected raster layer is the first
|
||||
one that is not an overlay layer.
|
||||
8. As a user/admin, when I hover over an area on the map, the area changes its style.
|
||||
9. As a user/admin, when I click on an area, a popup appears an I can see the different information about the
|
||||
area. If I click on the cross, the popup will disappear. If I click somewhere else on the map, the
|
||||
popup will also disappear. If I click on the about button, then the form view will be displayed.
|
||||
10. As a user/admin, when I use the paging system, then the results displayed on the map are different
|
||||
(corresponding to the request).
|
||||
11. As a user/admin, if we use the search bar, we can search results by his zip or his city.
|
||||
12. As an admin, if I change the sequence of layers with the handle button then the change are persisted in database.
|
||||
13. As a user, if I change the sequence of layers with the handle button then the change are not persisted in database.
|
||||
There are just the changes in the display.
|
||||
14. As an admin, if I change the domain of a layer with the filter button then the change are persisted in database.
|
||||
15. As a user, if I change the domain of a layer with the filter button then the change are not persisted in database.
|
||||
There are just the changes in the display.
|
||||
16. As an admin, I have the possibility to edit the layer with its corresponding button.
|
||||
17. As a user/admin, I can open/close LayerPanel with its button.
|
||||
18. As a user/admin, I can open/close RecordsPanel with its button.
|
||||
19. As a user/admin, when I click on a record in RecordsPanel, a move is made on the map to the selected record.
|
||||
20. As a user/admin, when I click on a record in RecordsPanel, I can also click on the left magnifying glass to zoom on the record.
|
||||
21. As a user/admin, when I click on a record in RecordsPanel, I can also click on the right magnifying glass to get the original zoom.
|
||||
22. As a user/admin, I can use the search bar to search in the RecordsPanel.
|
||||
23. As an admin,If the geoengine view is in edit mode, I can create new records by drawing them in the view.
|
||||
24. As an admin, If the geoengine view is in edit mode, I can modify its spatial representation.
|
||||
|
||||
Geoengine Backend
|
||||
=================
|
||||
|
||||
1. As an admin, if I go into the configuration of the raster layers and it has elements, I can click
|
||||
on one and see its information.
|
||||
2. As an admin, if I want to create a new raster layer, I can click on "NEW" and fill out the form. The
|
||||
required fields for OpenStreetMap type are "Layer Name" and "Related View". If we want to have a
|
||||
WMTS (Web Map Tile Service) raster type. The required fields in addition to the precedents are "Service URL",
|
||||
"Matrix set","Format", "Projection" and "Resolutions". If we take WMS (Web Map Service) raster type, then the
|
||||
required fields are "Layer Name", "Related View", "Service URL", "Params", "Server Type".
|
||||
3. As an admin,if I go into the configuration of the vector layers and it has elements, I can click
|
||||
on one and see its information.
|
||||
4. As an admin, if I want to create a new vector layer, I can click on "NEW" and fill out the form. The
|
||||
required fields are "Layer Name", "Related View", "Geo field" and "Representation mode".
|
||||
|
||||
Changelog
|
||||
=========
|
||||
|
||||
16.0.1.0.0 (2023-03-20)
|
||||
========================
|
||||
|
||||
* LayerSwitcher has been removed as it was not really practical. A LayerPanel is now active.
|
||||
* The geo_search method is now deprecated and replaced by the standard odoo search method.
|
||||
* The widget "geo_edit_map" attribute is no longer necessary as the field is automatically detected by
|
||||
his type. We can also provide an option attribute that allows us to pass an opacity and a color as
|
||||
parameters.
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<form>
|
||||
<notebook colspan="4">
|
||||
<page string="Geometry">
|
||||
<field name="the_geom" options="{'opacity': 0.8, 'color': '#0000FF' }" />
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
|
||||
* The method geo_search is now deprecated. We now need to use the standard odoo search method.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
obj.search([("the_point","geo_intersect",{"dummy.zip.the_geom": [("id", "=", rec.id)]})])
|
||||
|
||||
* We can now pass to the geoengine view a template to display the information we want
|
||||
to see when clicking on a feature.
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<geoengine>
|
||||
<field name="name" />
|
||||
<field name="city" />
|
||||
<field name="total_sales" />
|
||||
<field name="the_geom" />
|
||||
<templates>
|
||||
<t t-name="info_box">
|
||||
<field name="city" widget="badge" />
|
||||
<ul>
|
||||
<li>ZIP : <field name="name" />
|
||||
</li>
|
||||
<li>Total Sales: <field name="total_sales" />
|
||||
</li>
|
||||
</ul>
|
||||
</t>
|
||||
</templates>
|
||||
</geoengine>
|
||||
|
||||
* We can now pass a model to use to a layer to display other information on the map.
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<record id="geoengine_vector_layer_hs_retail_machines" model="geoengine.vector.layer">
|
||||
<field name="model_id" ref="base_geoengine_demo.model_geoengine_demo_automatic_retailing_machine"/>
|
||||
<field name="model_domain">[('state', '=', 'hs')]</field>
|
||||
<field name="geo_field_id" ref="base_geoengine_demo.field_geoengine_demo_automatic_retailing_machine__the_point"/>
|
||||
<field name="name">HS retail machines</field>
|
||||
<field name="view_id" ref="ir_ui_view_resbetterzipgeoview0" />
|
||||
<field name="geo_repr">basic</field>
|
||||
<field name="attribute_field_id" ref="base_geoengine_demo.field_geoengine_demo_automatic_retailing_machine__name"/>
|
||||
<field name="begin_color">#FF0000</field>
|
||||
<field name="display_polygon_labels" eval="0" />
|
||||
<field name="layer_opacity">0.8</field>
|
||||
</record>
|
||||
|
||||
|
||||
* There is some new features in the LayerPanel.
|
||||
|
||||
1. If you are logged in as an admin, you have the possibility to edit the layer by clicking on the edit button. This will open a dialog box.
|
||||
Changes will appear in real time on the view.
|
||||
2. If you are logged in as an admin, you can also change the domain of the layer. If you are logged in as a user, changes will not be
|
||||
persisted in the database. Changes will appear in real time on the view.
|
||||
3. If you are logged in as an admin, you can also change the sequence of the layers by sliding them over each other. If you are logged in as a user, changes will not be
|
||||
persisted in the database.
|
||||
|
||||
* Widget domain is now implemented for geo field This means that the geo-operators are also implemented and that there is the possibility to add a sub-domain.
|
||||
If we want to add a domain that includes all the records that are displayed in the geoengine view (active_ids). We can use the two new operators :
|
||||
"in active_ids" and "not in active_ids". These will automatically replace the marker with ids. Note that the widget will indicate that the domain is invalid
|
||||
because of the marker.
|
||||
* Creation of the RecordsPanel. This panel allows you to retrieve all active records. You can click on record to get the movement to the selected record.
|
||||
Two magnifying glass are also available. You can click on the left one to zoom on the record. You can click on the right one to get the original zoom.
|
||||
* A search bar is also available. It allows you to perform a search into the RecordsPanel.
|
||||
* A button to open/close the panels is also available.
|
||||
* The module has been translated in French.
|
||||
* Now you can now make the geoengine view editable. Simply add editable attribute in the geoengine view.
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<geoengine editable="1">
|
||||
<field name="name" />
|
||||
<field name="city" />
|
||||
<field name="total_sales" />
|
||||
<field name="the_geom" />
|
||||
<field name="display_name" />
|
||||
<templates>
|
||||
<t t-name="info_box">
|
||||
<field name="city" widget="badge" />
|
||||
<ul>
|
||||
<li>ZIP : <field name="name" />
|
||||
</li>
|
||||
<li>Total Sales: <field name="total_sales" />
|
||||
</li>
|
||||
</ul>
|
||||
</t>
|
||||
</templates>
|
||||
</geoengine>
|
||||
|
||||
Thanks to that, you can create new records by drawing them directly in the geoengine view. You can also edit record in the same view.
|
||||
|
||||
Bug Tracker
|
||||
===========
|
||||
|
||||
Bugs are tracked on `GitHub Issues <https://github.com/OCA/geospatial/issues>`_.
|
||||
In case of trouble, please check there if your issue has already been reported.
|
||||
If you spotted it first, help us to smash it by providing a detailed and welcomed
|
||||
`feedback <https://github.com/OCA/geospatial/issues/new?body=module:%20base_geoengine%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
|
||||
|
||||
Do not contact contributors directly about support or help with technical issues.
|
||||
|
||||
Credits
|
||||
=======
|
||||
|
||||
Authors
|
||||
~~~~~~~
|
||||
|
||||
* Camptocamp
|
||||
* ACSONE SA/NV
|
||||
|
||||
Contributors
|
||||
~~~~~~~~~~~~
|
||||
|
||||
* Nicolas Bessi <nicolas.bessi@camptocamp.com>
|
||||
* Frederic Junod <frederic.junod@camptocamp.com>
|
||||
* Yannick Payot <yannick.payot@camptocamp.com>
|
||||
* Sandy Carter <sandy.carter@savoirfairelinux.com>
|
||||
* Laurent Mignon <laurent.mignon@acsone.eu>
|
||||
* Jonathan Nemry <jonathan.nemry@acsone.eu>
|
||||
* David Lasley <dave@dlasley.net>
|
||||
* Daniel Reis <dgreis@sapo.pt>
|
||||
* Matthieu Dietrich <matthieu.dietrich@camptocamp.com>
|
||||
* Alan Ramos <alan.ramos@jarsa.com.mx>
|
||||
* Damien Crier <damien.crier@camptocamp.com>
|
||||
* Cyril Gaudin <cyril.gaudin@camptocamp.com>
|
||||
* Pierre Verkest <pverkest@anybox.fr>
|
||||
* Benjamin Willig <benjamin.willig@acsone.eu>
|
||||
* Devendra Kavthekar <dkatodoo@gmail.com>
|
||||
* Emanuel Cino <ecino@compassion.ch>
|
||||
* Thomas Nowicki <thomas.nowicki@camptocamp.com>
|
||||
* Alexandre Saunier <alexandre.saunier@camptocamp.com>
|
||||
* Sandip Mangukiya <smangukiya@opensourceintegrators.com>
|
||||
* Samuel Kouff <s.kouff@student.helmo.be>
|
||||
|
||||
Maintainers
|
||||
~~~~~~~~~~~
|
||||
|
||||
This module is maintained by the OCA.
|
||||
|
||||
.. image:: https://odoo-community.org/logo.png
|
||||
:alt: Odoo Community Association
|
||||
:target: https://odoo-community.org
|
||||
|
||||
OCA, or the Odoo Community Association, is a nonprofit organization whose
|
||||
mission is to support the collaborative development of Odoo features and
|
||||
promote its widespread use.
|
||||
|
||||
This module is part of the `OCA/geospatial <https://github.com/OCA/geospatial/tree/16.0/base_geoengine>`_ project on GitHub.
|
||||
|
||||
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
from . import models
|
||||
from . import expressions
|
||||
from . import fields
|
||||
from . import geo_convertion_helper
|
||||
from . import geo_operators
|
||||
from .geo_db import init_postgis
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
# Copyright 2011-2015 Nicolas Bessi (Camptocamp SA)
|
||||
# Copyright 2016 Yannick Payot (Camptocamp SA)
|
||||
# Copyright 2023 ACSONE SA/NV
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
{
|
||||
"name": "Geospatial support for Odoo",
|
||||
"version": "16.0.1.2.0",
|
||||
"category": "GeoBI",
|
||||
"author": "Camptocamp,ACSONE SA/NV,Odoo Community Association (OCA)",
|
||||
"license": "AGPL-3",
|
||||
"website": "https://github.com/OCA/geospatial",
|
||||
"depends": ["base", "web"],
|
||||
"data": [
|
||||
"security/data.xml",
|
||||
"views/base_geoengine_view.xml",
|
||||
"views/ir_model_view.xml",
|
||||
"views/ir_view_view.xml",
|
||||
"views/geo_raster_layer_view.xml",
|
||||
"views/geo_vector_layer_view.xml",
|
||||
"security/ir.model.access.csv",
|
||||
],
|
||||
"assets": {
|
||||
"web.assets_backend": [
|
||||
"base_geoengine/static/src/js/**/*",
|
||||
"base_geoengine/static/src/css/style.css",
|
||||
"web/static/src/libs/fontawesome/css/font-awesome.css",
|
||||
("include", "web._assets_helpers"),
|
||||
"web/static/src/scss/pre_variables.scss",
|
||||
"web/static/lib/bootstrap/scss/_variables.scss",
|
||||
("include", "web._assets_bootstrap"),
|
||||
]
|
||||
},
|
||||
"external_dependencies": {"python": ["shapely", "geojson", "simplejson"]},
|
||||
"installable": True,
|
||||
"pre_init_hook": "init_postgis",
|
||||
}
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
# Copyright 2023 ACSONE SA/NV
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
import random
|
||||
import string
|
||||
|
||||
from odoo.osv import expression
|
||||
from odoo.osv.expression import TERM_OPERATORS
|
||||
from odoo.tools import Query
|
||||
|
||||
from .fields import GeoField
|
||||
from .geo_operators import GeoOperator
|
||||
|
||||
original__leaf_to_sql = expression.expression._expression__leaf_to_sql
|
||||
|
||||
GEO_OPERATORS = {
|
||||
"geo_greater": ">",
|
||||
"geo_lesser": "<",
|
||||
"geo_equal": "=",
|
||||
"geo_touch": "ST_Touches",
|
||||
"geo_within": "ST_Within",
|
||||
"geo_contains": "ST_Contains",
|
||||
"geo_intersect": "ST_Intersects",
|
||||
}
|
||||
term_operators_list = list(TERM_OPERATORS)
|
||||
for op in GEO_OPERATORS:
|
||||
term_operators_list.append(op)
|
||||
|
||||
expression.TERM_OPERATORS = tuple(term_operators_list)
|
||||
|
||||
|
||||
def __leaf_to_sql(self, leaf, model, alias):
|
||||
"""
|
||||
This method has been monkey patched in order to be able to include
|
||||
geo_operators into the Odoo search method.
|
||||
"""
|
||||
left, operator, right = leaf
|
||||
|
||||
if isinstance(leaf, (list, tuple)):
|
||||
current_field = model._fields.get(left)
|
||||
current_operator = GeoOperator(current_field)
|
||||
if current_field and isinstance(current_field, GeoField):
|
||||
params = []
|
||||
if isinstance(right, dict):
|
||||
# We are having indirect geo_operator like (‘geom’, ‘geo_...’,
|
||||
# {‘res.zip.poly’: [‘id’, ‘in’, [1,2,3]] })
|
||||
ref_search = right
|
||||
sub_queries = []
|
||||
for key in ref_search:
|
||||
i = key.rfind(".")
|
||||
rel_model = key[0:i]
|
||||
rel_col = key[i + 1 :]
|
||||
rel_model = model.env[rel_model]
|
||||
# we compute the attributes search on spatial rel
|
||||
if ref_search[key]:
|
||||
rel_alias = (
|
||||
rel_model._table
|
||||
+ "_"
|
||||
+ "".join(random.choices(string.ascii_lowercase, k=5))
|
||||
)
|
||||
rel_query = where_calc(
|
||||
rel_model,
|
||||
ref_search[key],
|
||||
active_test=True,
|
||||
alias=rel_alias,
|
||||
)
|
||||
model._apply_ir_rules(rel_query, "read")
|
||||
if operator == "geo_equal":
|
||||
rel_query.add_where(
|
||||
f'"{alias}"."{left}" {GEO_OPERATORS[operator]} '
|
||||
f"{rel_alias}.{rel_col}"
|
||||
)
|
||||
elif operator in ("geo_greater", "geo_lesser"):
|
||||
rel_query.add_where(
|
||||
f"ST_Area({alias}.{left}) {GEO_OPERATORS[operator]} "
|
||||
f"ST_Area({rel_alias}.{rel_col})"
|
||||
)
|
||||
else:
|
||||
rel_query.add_where(
|
||||
f'{GEO_OPERATORS[operator]}("{alias}"."{left}", '
|
||||
f"{rel_alias}.{rel_col})"
|
||||
)
|
||||
|
||||
subquery, subparams = rel_query.subselect("1")
|
||||
sub_queries.append(f"EXISTS({subquery})")
|
||||
params += subparams
|
||||
query = " AND ".join(sub_queries)
|
||||
else:
|
||||
query = get_geo_func(
|
||||
current_operator, operator, left, right, params, model._table
|
||||
)
|
||||
return query, params
|
||||
return original__leaf_to_sql(self, leaf=leaf, model=model, alias=alias)
|
||||
|
||||
|
||||
def get_geo_func(current_operator, operator, left, right, params, table):
|
||||
"""
|
||||
This method will call the SQL query corresponding to the requested geo operator
|
||||
"""
|
||||
|
||||
if operator == "geo_greater":
|
||||
query = current_operator.get_geo_greater_sql(table, left, right, params)
|
||||
elif operator == "geo_lesser":
|
||||
query = current_operator.get_geo_lesser_sql(table, left, right, params)
|
||||
elif operator == "geo_equal":
|
||||
query = current_operator.get_geo_equal_sql(table, left, right, params)
|
||||
elif operator == "geo_touch":
|
||||
query = current_operator.get_geo_touch_sql(table, left, right, params)
|
||||
elif operator == "geo_within":
|
||||
query = current_operator.get_geo_within_sql(table, left, right, params)
|
||||
elif operator == "geo_contains":
|
||||
query = current_operator.get_geo_contains_sql(table, left, right, params)
|
||||
elif operator == "geo_intersect":
|
||||
query = current_operator.get_geo_intersect_sql(table, left, right, params)
|
||||
else:
|
||||
raise NotImplementedError(f"The operator {operator} is not supported")
|
||||
return query
|
||||
|
||||
|
||||
def where_calc(model, domain, active_test=True, alias=None):
|
||||
"""
|
||||
This method is copied from base, we need to create our own query.
|
||||
"""
|
||||
# if the object has an active field ('active', 'x_active'), filter out all
|
||||
# inactive records unless they were explicitly asked for
|
||||
if model._active_name and active_test and model._context.get("active_test", True):
|
||||
# the item[0] trick below works for domain items and '&'/'|'/'!'
|
||||
# operators too
|
||||
if not any(item[0] == model._active_name for item in domain):
|
||||
domain = [(model._active_name, "=", 1)] + domain
|
||||
|
||||
query = Query(model.env.cr, alias, model._table)
|
||||
if domain:
|
||||
return expression.expression(domain, model, alias=alias, query=query).query
|
||||
return query
|
||||
|
||||
|
||||
expression.expression._expression__leaf_to_sql = __leaf_to_sql
|
||||
|
|
@ -0,0 +1,330 @@
|
|||
# Copyright 2011-2012 Nicolas Bessi (Camptocamp SA)
|
||||
# Copyright 2016 Yannick Payot (Camptocamp SA)
|
||||
# Copyright 2023 ACSONE SA/NV
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
import json
|
||||
import logging
|
||||
from operator import attrgetter
|
||||
|
||||
from odoo import _, fields
|
||||
from odoo.tools import sql
|
||||
|
||||
from . import geo_convertion_helper as convert
|
||||
from .geo_db import create_geo_column, create_geo_index
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
try:
|
||||
import geojson
|
||||
from shapely.geometry import Point, shape
|
||||
from shapely.geometry.base import BaseGeometry
|
||||
from shapely.wkb import loads as wkbloads
|
||||
except ImportError:
|
||||
logger.warning("Shapely or geojson are not available in the sys path")
|
||||
|
||||
|
||||
class GeoField(fields.Field):
|
||||
"""The field descriptor contains the field definition common to all
|
||||
specialized fields for geolocalization. Subclasses must define a type
|
||||
and a geo_type. The type is the name of the corresponding column type,
|
||||
the geo_type is the name of the corresponding type in the GIS system.
|
||||
"""
|
||||
|
||||
geo_type = None
|
||||
dim = 2
|
||||
srid = 3857
|
||||
gist_index = True
|
||||
|
||||
@property
|
||||
def column_type(self):
|
||||
return ("geometry", f"geometry({self.geo_type.upper()}, {self.srid})")
|
||||
|
||||
def convert_to_column(self, value, record, values=None):
|
||||
"""Convert value to database format
|
||||
|
||||
value can be geojson, wkt, shapely geometry object.
|
||||
If geo_direct_write in context you can pass diretly WKT"""
|
||||
if not value:
|
||||
return None
|
||||
shape_to_write = self.entry_to_shape(value, same_type=True)
|
||||
if shape_to_write.is_empty:
|
||||
return None
|
||||
else:
|
||||
return f"SRID={self.srid};{shape_to_write.wkt}"
|
||||
|
||||
def convert_to_cache(self, value, record, validate=True):
|
||||
val = value
|
||||
if isinstance(val, (bytes, str)):
|
||||
try:
|
||||
int(val, 16)
|
||||
except Exception:
|
||||
# not an hex value -> try to load from a sting
|
||||
# representation of a geometry
|
||||
value = convert.value_to_shape(value, use_wkb=False)
|
||||
if isinstance(value, BaseGeometry):
|
||||
val = value.wkb_hex
|
||||
return val
|
||||
|
||||
def convert_to_record(self, value, record):
|
||||
"""Value may be:
|
||||
- a GeoJSON string when field onchange is triggered
|
||||
- a geometry object hexcode from cache
|
||||
- a unicode containing dict
|
||||
"""
|
||||
if not value:
|
||||
return False
|
||||
return convert.value_to_shape(value, use_wkb=True)
|
||||
|
||||
def convert_to_read(self, value, record, use_name_get=True):
|
||||
if not isinstance(value, BaseGeometry):
|
||||
# read hexadecimal value from database
|
||||
shape = self.load_geo(value)
|
||||
else:
|
||||
shape = value
|
||||
if not shape or shape.is_empty:
|
||||
return False
|
||||
return geojson.dumps(shape)
|
||||
|
||||
#
|
||||
# Field description
|
||||
#
|
||||
|
||||
# properties used by get_description()
|
||||
_description_dim = property(attrgetter("dim"))
|
||||
_description_srid = property(attrgetter("srid"))
|
||||
_description_gist_index = property(attrgetter("gist_index"))
|
||||
|
||||
@classmethod
|
||||
def load_geo(cls, wkb):
|
||||
"""Load geometry into browse record after read was done"""
|
||||
if isinstance(wkb, BaseGeometry):
|
||||
return wkb
|
||||
return wkbloads(wkb, hex=True) if wkb else False
|
||||
|
||||
def entry_to_shape(self, value, same_type=False):
|
||||
"""Transform input into an object"""
|
||||
shape = convert.value_to_shape(value)
|
||||
if same_type and not shape.is_empty:
|
||||
if shape.geom_type.lower() != self.geo_type.lower():
|
||||
msg = _(
|
||||
"Geo Value %(geom_type)s must be of the same type %(geo_type)s as fields",
|
||||
geom_type=shape.geom_type.lower(),
|
||||
geo_type=self.geo_type.lower(),
|
||||
)
|
||||
raise TypeError(msg)
|
||||
return shape
|
||||
|
||||
def update_geo_db_column(self, model):
|
||||
"""Update the column type in the database."""
|
||||
cr = model._cr
|
||||
query = """SELECT srid, type, coord_dimension
|
||||
FROM geometry_columns
|
||||
WHERE f_table_name = %s
|
||||
AND f_geometry_column = %s"""
|
||||
cr.execute(query, (model._table, self.name))
|
||||
check_data = cr.fetchone()
|
||||
if not check_data:
|
||||
raise TypeError(
|
||||
_(
|
||||
"geometry_columns table seems to be corrupted."
|
||||
" SRID check is not possible"
|
||||
)
|
||||
)
|
||||
if check_data[0] != self.srid:
|
||||
raise TypeError(
|
||||
_(
|
||||
"Reprojection of column is not implemented."
|
||||
" We can not change srid %(srid)s to %(data)s",
|
||||
srid=self.srid,
|
||||
data=check_data[0],
|
||||
)
|
||||
)
|
||||
elif check_data[1] != self.geo_type.upper():
|
||||
raise TypeError(
|
||||
_(
|
||||
"Geo type modification is not implemented."
|
||||
" We can not change type %(data)s to %(geo_type)s",
|
||||
data=check_data[1],
|
||||
geo_type=self.geo_type.upper(),
|
||||
)
|
||||
)
|
||||
elif check_data[2] != self.dim:
|
||||
raise TypeError(
|
||||
_(
|
||||
"Geo dimention modification is not implemented."
|
||||
" We can not change dimention %(data)s to %(dim)s",
|
||||
data=check_data[2],
|
||||
dim=self.dim,
|
||||
)
|
||||
)
|
||||
if self.gist_index:
|
||||
create_geo_index(cr, model._table, self.name)
|
||||
return True
|
||||
|
||||
def update_db_column(self, model, column):
|
||||
"""Create/update the column corresponding to ``self``.
|
||||
|
||||
For creation of geo column
|
||||
|
||||
:param model: an instance of the field's model
|
||||
:param column: the column's configuration (dict)
|
||||
if it exists, or ``None``
|
||||
"""
|
||||
# the column does not exist, create it
|
||||
|
||||
if not column:
|
||||
create_geo_column(
|
||||
model._cr,
|
||||
model._table,
|
||||
self.name,
|
||||
self.geo_type.upper(),
|
||||
self.srid,
|
||||
self.dim,
|
||||
self.string,
|
||||
)
|
||||
if self.gist_index:
|
||||
create_geo_index(model._cr, model._table, self.name)
|
||||
return
|
||||
|
||||
if column["udt_name"] == self.column_type[0]:
|
||||
return
|
||||
|
||||
self.update_geo_db_column(model)
|
||||
|
||||
if column["udt_name"] in self.column_cast_from:
|
||||
sql.convert_column(model._cr, model._table, self.name, self.column_type[1])
|
||||
else:
|
||||
newname = (self.name + "_moved{}").format
|
||||
i = 0
|
||||
while sql.column_exists(model._cr, model._table, newname(i)):
|
||||
i += 1
|
||||
if column["is_nullable"] == "NO":
|
||||
sql.drop_not_null(model._cr, model._table, self.name)
|
||||
sql.rename_column(model._cr, model._table, self.name, newname(i))
|
||||
sql.create_column(
|
||||
model._cr, model._table, self.name, self.column_type[1], self.string
|
||||
)
|
||||
|
||||
|
||||
class GeoLine(GeoField):
|
||||
"""Field for POSTGIS geometry Line type"""
|
||||
|
||||
type = "geo_line"
|
||||
geo_type = "LineString"
|
||||
|
||||
@classmethod
|
||||
def from_points(cls, cr, point1, point2, srid=None):
|
||||
"""
|
||||
Converts given points in parameter to a line.
|
||||
:param cr: DB cursor
|
||||
:param point1: Point (BaseGeometry)
|
||||
:param point2: Point (BaseGeometry)
|
||||
:param srid: SRID
|
||||
:return: LINESTRING Object
|
||||
"""
|
||||
sql = """
|
||||
SELECT
|
||||
ST_MakeLine(
|
||||
ST_GeomFromText(%(wkt1)s, %(srid)s),
|
||||
ST_GeomFromText(%(wkt2)s, %(srid)s)
|
||||
)
|
||||
"""
|
||||
cr.execute(
|
||||
sql,
|
||||
{
|
||||
"wkt1": point1.wkt,
|
||||
"wkt2": point2.wkt,
|
||||
"srid": srid or cls.srid,
|
||||
},
|
||||
)
|
||||
res = cr.fetchone()
|
||||
return cls.load_geo(res[0])
|
||||
|
||||
|
||||
class GeoPoint(GeoField):
|
||||
"""Field for POSTGIS geometry Point type"""
|
||||
|
||||
type = "geo_point"
|
||||
geo_type = "Point"
|
||||
|
||||
@classmethod
|
||||
def from_latlon(cls, cr, latitude, longitude):
|
||||
"""Convert a (latitude, longitude) into an UTM coordinate Point:"""
|
||||
pt = Point(longitude, latitude)
|
||||
cr.execute(
|
||||
"""
|
||||
SELECT
|
||||
ST_Transform(
|
||||
ST_GeomFromText(%(wkt)s, 4326),
|
||||
%(srid)s)
|
||||
""",
|
||||
{"wkt": pt.wkt, "srid": cls.srid},
|
||||
)
|
||||
res = cr.fetchone()
|
||||
return cls.load_geo(res[0])
|
||||
|
||||
@classmethod
|
||||
def to_latlon(cls, cr, geopoint):
|
||||
"""Convert a UTM coordinate point to (latitude, longitude):"""
|
||||
# Line to execute to retrieve longitude, latitude from UTM in postgres command line:
|
||||
# SELECT ST_X(geom), ST_Y(geom) FROM (SELECT ST_TRANSFORM(ST_SetSRID(
|
||||
# ST_MakePoint(601179.61612, 6399375,681364), 900913), 4326) as geom) g;
|
||||
if isinstance(geopoint, BaseGeometry):
|
||||
geo_point_instance = geopoint
|
||||
else:
|
||||
geo_point_instance = shape(json.loads(geopoint))
|
||||
cr.execute(
|
||||
"""
|
||||
SELECT
|
||||
ST_TRANSFORM(
|
||||
ST_SetSRID(
|
||||
ST_MakePoint(
|
||||
%(coord_x)s, %(coord_y)s
|
||||
),
|
||||
%(srid)s
|
||||
), 4326)""",
|
||||
{
|
||||
"coord_x": geo_point_instance.x,
|
||||
"coord_y": geo_point_instance.y,
|
||||
"srid": cls.srid,
|
||||
},
|
||||
)
|
||||
|
||||
res = cr.fetchone()
|
||||
point_latlon = cls.load_geo(res[0])
|
||||
return point_latlon.x, point_latlon.y
|
||||
|
||||
|
||||
class GeoPolygon(GeoField):
|
||||
"""Field for POSTGIS geometry Polygon type"""
|
||||
|
||||
type = "geo_polygon"
|
||||
geo_type = "Polygon"
|
||||
|
||||
|
||||
class GeoMultiLine(GeoField):
|
||||
"""Field for POSTGIS geometry MultiLine type"""
|
||||
|
||||
type = "geo_multi_line"
|
||||
geo_type = "MultiLineString"
|
||||
|
||||
|
||||
class GeoMultiPoint(GeoField):
|
||||
"""Field for POSTGIS geometry MultiPoint type"""
|
||||
|
||||
type = "geo_multi_point"
|
||||
geo_type = "MultiPoint"
|
||||
|
||||
|
||||
class GeoMultiPolygon(GeoField):
|
||||
"""Field for POSTGIS geometry MultiPolygon type"""
|
||||
|
||||
type = "geo_multi_polygon"
|
||||
geo_type = "MultiPolygon"
|
||||
|
||||
|
||||
fields.GeoLine = GeoLine
|
||||
fields.GeoPoint = GeoPoint
|
||||
fields.GeoPolygon = GeoPolygon
|
||||
fields.GeoMultiLine = GeoMultiLine
|
||||
fields.GeoMultiPoint = GeoMultiPoint
|
||||
fields.GeoMultiPolygon = GeoMultiPolygon
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
# Copyright 2011-2012 Nicolas Bessi (Camptocamp SA)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
import logging
|
||||
|
||||
from odoo import _
|
||||
|
||||
try:
|
||||
import geojson
|
||||
from shapely import wkb, wkt
|
||||
from shapely.geometry import shape
|
||||
from shapely.geometry.base import BaseGeometry
|
||||
except ImportError:
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.warning(_("Shapely or geojson are not available in the sys path"))
|
||||
|
||||
|
||||
def value_to_shape(value, use_wkb=False):
|
||||
"""Transforms input into a Shapely object"""
|
||||
if not value:
|
||||
return wkt.loads("GEOMETRYCOLLECTION EMPTY")
|
||||
if isinstance(value, str):
|
||||
# We try to do this before parsing json exception
|
||||
# exception are ressource costly
|
||||
if "{" in value:
|
||||
geo_dict = geojson.loads(value)
|
||||
return shape(geo_dict)
|
||||
elif use_wkb:
|
||||
return wkb.loads(value, hex=True)
|
||||
else:
|
||||
return wkt.loads(value)
|
||||
elif hasattr(value, "wkt"):
|
||||
if isinstance(value, BaseGeometry):
|
||||
return value
|
||||
else:
|
||||
return wkt.loads(value.wkt)
|
||||
else:
|
||||
raise TypeError(
|
||||
_(
|
||||
"Write/create/search geo type must be wkt/geojson "
|
||||
"string or must respond to wkt"
|
||||
)
|
||||
)
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
# Copyright 2011-2012 Nicolas Bessi (Camptocamp SA)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
"""Helper to setup Postgis"""
|
||||
import logging
|
||||
|
||||
from odoo import _
|
||||
from odoo.exceptions import MissingError
|
||||
from odoo.tools import sql
|
||||
|
||||
logger = logging.getLogger("geoengine.sql")
|
||||
_schema = logging.getLogger("odoo.schema")
|
||||
|
||||
|
||||
def init_postgis(cr):
|
||||
"""Initialize postgis
|
||||
Add PostGIS support to the database. PostGIS is a spatial database
|
||||
extender for PostgreSQL object-relational database. It adds support for
|
||||
geographic objects allowing location queries to be run in SQL.
|
||||
"""
|
||||
cr.execute(
|
||||
"""
|
||||
SELECT
|
||||
tablename
|
||||
FROM
|
||||
pg_tables
|
||||
WHERE
|
||||
tablename='spatial_ref_sys';
|
||||
"""
|
||||
)
|
||||
check = cr.fetchone()
|
||||
if check:
|
||||
return {}
|
||||
try:
|
||||
cr.execute(
|
||||
"""
|
||||
CREATE EXTENSION postgis;
|
||||
CREATE EXTENSION postgis_topology;
|
||||
"""
|
||||
)
|
||||
except Exception as exc:
|
||||
raise MissingError(
|
||||
_(
|
||||
"Error, can not automatically initialize spatial postgis"
|
||||
" support. Database user may have to be superuser and"
|
||||
" postgres/postgis extensions with their devel header have"
|
||||
" to be installed. If you do not want Odoo to connect with a"
|
||||
" super user you can manually prepare your database. To do"
|
||||
" this, open a client to your database using a super user and"
|
||||
" run:\n"
|
||||
"CREATE EXTENSION postgis;\n"
|
||||
"CREATE EXTENSION postgis_topology;\n"
|
||||
)
|
||||
) from exc
|
||||
|
||||
|
||||
def create_geo_column(cr, tablename, columnname, geotype, srid, dim, comment=None):
|
||||
"""Create a geometry column with the given type.
|
||||
|
||||
:params: srid: geometry's projection srid
|
||||
:params: dim: geometry's dimension (2D or 3D)
|
||||
"""
|
||||
cr.execute(
|
||||
"SELECT AddGeometryColumn( %s, %s, %s, %s, %s)",
|
||||
(tablename, columnname, srid, geotype, dim),
|
||||
)
|
||||
if comment:
|
||||
# pylint: disable=E8103
|
||||
cr.execute(
|
||||
'COMMENT ON COLUMN "{}"."{}" IS %s'.format(tablename, columnname),
|
||||
(comment,),
|
||||
)
|
||||
_schema.debug(
|
||||
"Table %r: added geometry column %r of type %s", tablename, columnname, geotype
|
||||
)
|
||||
|
||||
|
||||
def _postgis_index_name(table, col_name):
|
||||
return "{}_{}_gist_index".format(table, col_name)
|
||||
|
||||
|
||||
def create_geo_index(cr, tablename, columnname):
|
||||
"""Create the given index unless it exists."""
|
||||
indexname = _postgis_index_name(tablename, columnname)
|
||||
if sql.index_exists(cr, indexname):
|
||||
return
|
||||
# pylint: disable=E8103
|
||||
cr.execute(
|
||||
"CREATE INDEX {} ON {} USING GIST ( {} )".format(
|
||||
indexname, tablename, columnname
|
||||
)
|
||||
)
|
||||
_schema.debug("Table %r: created index %r", tablename, indexname)
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
# Copyright 2011-2012 Nicolas Bessi (Camptocamp SA)
|
||||
# Copyright 2023 ACSONE SA/NV
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
|
||||
class GeoOperator(object):
|
||||
def __init__(self, geo_field):
|
||||
self.geo_field = geo_field
|
||||
|
||||
def _get_direct_como_op_sql(self, table, col, value, params, op=""):
|
||||
"""provide raw sql for geater and lesser operators"""
|
||||
if isinstance(value, (int, float)):
|
||||
return " ST_Area({}.{}) {} {}".format(table, col, op, value)
|
||||
else:
|
||||
base = self.geo_field.entry_to_shape(value, same_type=False)
|
||||
params.append(base.wkt)
|
||||
return " ST_Area({}.{}) {} ST_Area(ST_GeomFromText(%s))".format(
|
||||
table, col, op
|
||||
)
|
||||
|
||||
def _get_postgis_comp_sql(self, table, col, value, params, op=""):
|
||||
"""return raw sql for all search based on St_**(a, b) posgis operator"""
|
||||
base = self.geo_field.entry_to_shape(value, same_type=False)
|
||||
srid = self.geo_field.srid
|
||||
params.append(base.wkt)
|
||||
params.append(srid)
|
||||
return f"{op}({table}.{col}, ST_GeomFromText(%s, %s))"
|
||||
|
||||
def get_geo_greater_sql(self, table, col, value, params):
|
||||
"""Returns raw sql for geo_greater operator
|
||||
(used for area comparison)
|
||||
"""
|
||||
return self._get_direct_como_op_sql(table, col, value, params, op=">")
|
||||
|
||||
def get_geo_lesser_sql(self, table, col, value, params):
|
||||
"""Returns raw sql for geo_lesser operator
|
||||
(used for area comparison)"""
|
||||
return self._get_direct_como_op_sql(table, col, value, params, op="<")
|
||||
|
||||
def get_geo_equal_sql(
|
||||
self,
|
||||
table,
|
||||
col,
|
||||
value,
|
||||
params,
|
||||
):
|
||||
"""Returns raw sql for geo_equal operator
|
||||
(used for equality comparison)
|
||||
"""
|
||||
base = self.geo_field.entry_to_shape(value, same_type=False)
|
||||
compare_to = "ST_GeomFromText(%s)"
|
||||
params.append(base.wkt)
|
||||
return " {}.{} = {}".format(table, col, compare_to)
|
||||
|
||||
def get_geo_intersect_sql(self, table, col, value, params):
|
||||
"""Returns raw sql for geo_intersec operator
|
||||
(used for spatial comparison)
|
||||
"""
|
||||
return self._get_postgis_comp_sql(table, col, value, params, op="ST_Intersects")
|
||||
|
||||
def get_geo_touch_sql(self, table, col, value, params):
|
||||
"""Returns raw sql for geo_touch operator
|
||||
(used for spatial comparison)
|
||||
"""
|
||||
return self._get_postgis_comp_sql(table, col, value, params, op="ST_Touches")
|
||||
|
||||
def get_geo_within_sql(self, table, col, value, params):
|
||||
"""Returns raw sql for geo_within operator
|
||||
(used for spatial comparison)
|
||||
"""
|
||||
return self._get_postgis_comp_sql(table, col, value, params, op="ST_Within")
|
||||
|
||||
def get_geo_contains_sql(self, table, col, value, params):
|
||||
"""Returns raw sql for geo_contains operator
|
||||
(used for spatial comparison)
|
||||
"""
|
||||
return self._get_postgis_comp_sql(table, col, value, params, op="ST_Contains")
|
||||
|
|
@ -0,0 +1,971 @@
|
|||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * base_geoengine
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 16.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: \n"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/models/base.py:0
|
||||
#, python-format
|
||||
msgid "%s column does not exists or is not a geo field"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__active_on_startup
|
||||
msgid "Active On Startup"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__attribute_field_id
|
||||
msgid "Attribute field"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model,name:base_geoengine.model_base
|
||||
msgid "Base"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_vector_layer__geo_repr__basic
|
||||
msgid "Basic"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__begin_color
|
||||
msgid "Begin color class"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_geoengine_view_form
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_view_form
|
||||
msgid "Classification"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__classification
|
||||
msgid "Classification mode"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__type
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type__code
|
||||
msgid "Code"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_vector_layer__geo_repr__colored
|
||||
msgid "Colored range/Chroma.js"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_geoengine_view_form
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_view_form
|
||||
msgid "Colors"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.ui.menu,name:base_geoengine.geoengine_base_view_menu
|
||||
msgid "Configuration"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_model_fields__gist_index
|
||||
msgid "Create gist index"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__create_uid
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type__create_uid
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__create_uid
|
||||
msgid "Created by"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__create_date
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type__create_date
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__create_date
|
||||
msgid "Created on"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_vector_layer__classification__custom
|
||||
msgid "Custom"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_ui_view__default_extent
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_website_page__default_extent
|
||||
msgid "Default map extent"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_ui_view__default_zoom
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_website_page__default_zoom
|
||||
msgid "Default map zoom"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_raster_layer__params
|
||||
msgid "Dictiorary of values for dimensions as JSON"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__dimensions
|
||||
msgid "Dimensions"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/geoengine_controller/geoengine_controller.xml:0
|
||||
#, python-format
|
||||
msgid "Discard"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__display_polygon_labels
|
||||
msgid "Display Labels on Polygon"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__display_name
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type__display_name
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__display_name
|
||||
msgid "Display Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_raster_layer__raster_type__d_wms
|
||||
msgid "Distant WMS"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/layers_panel/layers_panel.esm.js:0
|
||||
#, python-format
|
||||
msgid "Domain editing"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/layers_panel/layers_panel.esm.js:0
|
||||
#, python-format
|
||||
msgid "Editing vector layer"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__end_color
|
||||
msgid "End color class"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/geo_db.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Error, can not automatically initialize spatial postgis support. Database user may have to be superuser and postgres/postgis extensions with their devel header have to be installed. If you do not want Odoo to connect with a super user you can manually prepare your database. To do this, open a client to your database using a super user and run:\n"
|
||||
"CREATE EXTENSION postgis;\n"
|
||||
"CREATE EXTENSION postgis_topology;\n"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_model_fields__ttype
|
||||
msgid "Field Type"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model,name:base_geoengine.model_ir_model_fields
|
||||
msgid "Fields"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__format_suffix
|
||||
msgid "Format"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_raster_view_form
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_geoengine_view_form
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_view_form
|
||||
msgid "General"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/fields.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Geo Value %(geom_type)s must be of the same type %(geo_type)s as fields"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/fields.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Geo dimention modification is not implemented. We can not change dimention "
|
||||
"%(data)s to %(dim)s"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__geo_field_id
|
||||
msgid "Geo field"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/fields.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Geo type modification is not implemented. We can not change type %(data)s to"
|
||||
" %(geo_type)s"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_ui_view__type__geoengine
|
||||
msgid "GeoEngine"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.ui.menu,name:base_geoengine.geoengine_base_menu
|
||||
msgid "GeoEngine Backend"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geoengine_view_form
|
||||
msgid "GeoEngine Data"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/geoengine_view.esm.js:0
|
||||
#, python-format
|
||||
msgid "Geoengine"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:res.groups,name:base_geoengine.group_geoengine_admin
|
||||
msgid "Geoengine Admin"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:res.groups,name:base_geoengine.group_geoengine_user
|
||||
msgid "Geoengine User"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__has_type
|
||||
msgid "Has Type"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__id
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type__id
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__id
|
||||
msgid "ID"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_vector_layer__classification__interval
|
||||
msgid "Interval"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__is_wms
|
||||
msgid "Is Wms"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__is_wmts
|
||||
msgid "Is Wmts"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__overlay
|
||||
msgid "Is overlay layer?"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__geo_type__linestring
|
||||
msgid "LINESTRING"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer____last_update
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type____last_update
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer____last_update
|
||||
msgid "Last Modified on"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__write_uid
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type__write_uid
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__write_uid
|
||||
msgid "Last Updated by"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__write_date
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type__write_date
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__write_date
|
||||
msgid "Last Updated on"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__type_id
|
||||
msgid "Layer"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__name
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__name
|
||||
msgid "Layer Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__layer_opacity
|
||||
msgid "Layer Opacity"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__sequence
|
||||
msgid "Layer Priority"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_raster_view_form
|
||||
msgid "Layer data"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__readonly
|
||||
msgid "Layer is read only"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__sequence
|
||||
msgid "Layer priority"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_vector_layer__active_on_startup
|
||||
msgid "Layer will be shown on startup if checked."
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/layers_panel/layers_panel.xml:0
|
||||
#, python-format
|
||||
msgid "Layers ("
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_raster_layer__dimensions
|
||||
msgid "List of dimensions separated by ','"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__geo_type__multilinestring
|
||||
msgid "MULTILINESTRING"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__geo_type__multipoint
|
||||
msgid "MULTIPOINT"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__geo_type__multipolygon
|
||||
msgid "MULTIPOLYGON"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__matrix_set
|
||||
msgid "Matrix set"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__max_extent
|
||||
msgid "Max extent"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/geoengine_arch_parser.esm.js:0
|
||||
#, python-format
|
||||
msgid "Missing ${INFO_BOX_ATTRIBUTE} template."
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__model_name
|
||||
msgid "Model"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__model_domain
|
||||
msgid "Model Domain"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__model_id
|
||||
msgid "Model to use"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__model_view_id
|
||||
msgid "Model view"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type__name
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_raster_layer__params_wms
|
||||
msgid "Need to provide at least a LAYERS param"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/geoengine_controller/geoengine_controller.esm.js:0
|
||||
#, python-format
|
||||
msgid "New record"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/models/base.py:0
|
||||
#, python-format
|
||||
msgid "No GeoEngine view defined for the model %s"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/models/base.py:0
|
||||
#, python-format
|
||||
msgid "No raster layer for view %s"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__nb_class
|
||||
msgid "Number of class"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/geoengine_renderer/geoengine_renderer.xml:0
|
||||
#, python-format
|
||||
msgid "OPEN"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_raster_layer__raster_type__odoo
|
||||
msgid "Odoo field"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_raster_view_form
|
||||
msgid "Odoo layer data (Not implemented)"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__field_id
|
||||
msgid "Odoo layer field to use"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_raster_layer__raster_type__osm
|
||||
msgid "OpenStreetMap"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__geo_type__point
|
||||
msgid "POINT"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__geo_type__polygon
|
||||
msgid "POLYGON"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__params
|
||||
msgid "Params"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__params_wms
|
||||
msgid "Params WMS"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/models/base.py:0
|
||||
#, python-format
|
||||
msgid "Please create a view or modify view mode"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_model_fields__dim
|
||||
msgid "PostGIs Dimension"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_model_fields__geo_type
|
||||
msgid "PostGIs type"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__projection
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_ui_view__projection
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_website_page__projection
|
||||
msgid "Projection"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_vector_layer__geo_repr__proportion
|
||||
msgid "Proportional Symbol"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_vector_layer__classification__quantile
|
||||
msgid "Quantile"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geoengine_view_form
|
||||
msgid "Raster (Background layers)"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.actions.act_window,name:base_geoengine.geo_engine_view_rater_action
|
||||
#: model:ir.model,name:base_geoengine.model_geoengine_raster_layer
|
||||
msgid "Raster Layer"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.ui.menu,name:base_geoengine.geoengine_raster_layer_menu
|
||||
msgid "Raster Layer Management"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model,name:base_geoengine.model_geoengine_raster_layer_type
|
||||
msgid "Raster Layer Type"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_raster_view_form
|
||||
msgid "Raster Layer View"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__raster_type
|
||||
msgid "Raster layer type"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_ui_view__raster_layer_ids
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_website_page__raster_layer_ids
|
||||
msgid "Raster layers"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/layers_panel/layers_panel.xml:0
|
||||
#, python-format
|
||||
msgid "Rasters"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/records_panel/records_panel.xml:0
|
||||
#, python-format
|
||||
msgid "Records ("
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_view_form
|
||||
msgid "Related Model"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__view_id
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__view_id
|
||||
msgid "Related View"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_geoengine_view_form
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_view_form
|
||||
msgid "Representation"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__geo_repr
|
||||
msgid "Representation mode"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/fields.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Reprojection of column is not implemented. We can not change srid %(srid)s "
|
||||
"to %(data)s"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__request_encoding
|
||||
msgid "Request encoding"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__resolutions
|
||||
msgid "Resolutions"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_ui_view__restricted_extent
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_website_page__restricted_extent
|
||||
msgid "Restricted map extent"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/geoengine_controller/geoengine_controller.xml:0
|
||||
#, python-format
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/records_panel/search_bar_records/search_bar_records.xml:0
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/records_panel/search_bar_records/search_bar_records.xml:0
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/records_panel/search_bar_records/search_bar_records.xml:0
|
||||
#, python-format
|
||||
msgid "Search..."
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__server_type
|
||||
msgid "Server Type"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type__service
|
||||
msgid "Service"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__url
|
||||
msgid "Service URL"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/geo_convertion_helper.py:0
|
||||
#, python-format
|
||||
msgid "Shapely or geojson are not available in the sys path"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_geo_field_input/domain_selector_geo_field_input.esm.js:0
|
||||
#, python-format
|
||||
msgid "Subdomain"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/models/geo_vector_layer.py:0
|
||||
#, python-format
|
||||
msgid "The geo_field_id must be a field in %s model"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_raster_layer__server_type
|
||||
msgid ""
|
||||
"The type of the remote WMS server: mapserver, geoserver, carmentaserver, or "
|
||||
"qgis"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_vector_layer__classification__unique
|
||||
msgid "Unique value"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__units
|
||||
msgid "Units"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__use_to_edit
|
||||
msgid "Use to edit"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_view_form
|
||||
msgid "Vector"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geoengine_view_form
|
||||
msgid "Vector (Active layers)"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.actions.act_window,name:base_geoengine.geo_engine_view_raster_action
|
||||
#: model:ir.actions.act_window,name:base_geoengine.geo_vector_geoengine_view_action
|
||||
#: model:ir.model,name:base_geoengine.model_geoengine_vector_layer
|
||||
msgid "Vector Layer"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.ui.menu,name:base_geoengine.geoengine_vector_layer_menu
|
||||
msgid "Vector Layer Management"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_ui_view__vector_layer_ids
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_website_page__vector_layer_ids
|
||||
msgid "Vector layers"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/layers_panel/layers_panel.xml:0
|
||||
#, python-format
|
||||
msgid "Vectors"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model,name:base_geoengine.model_ir_ui_view
|
||||
msgid "View"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.ui.menu,name:base_geoengine.geoengine_view_menu
|
||||
msgid "View Management"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_ui_view__type
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_website_page__type
|
||||
msgid "View Type"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.actions.act_window,name:base_geoengine.geo_engine_view_action
|
||||
msgid "Views"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_raster_view_form
|
||||
msgid "WMS options"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_raster_layer__raster_type__wmts
|
||||
msgid "WMTS"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_raster_view_form
|
||||
msgid "WMTS options"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/geoengine_controller/geoengine_controller.esm.js:0
|
||||
#, python-format
|
||||
msgid "Warning"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/geo_convertion_helper.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Write/create/search geo type must be wkt/geojson string or must respond to "
|
||||
"wkt"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/geoengine_controller/geoengine_controller.esm.js:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"You are about to create a new record without having displayed all the "
|
||||
"others. A risk of overlap could occur. Would you like to continue ?"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/models/base.py:0
|
||||
#, python-format
|
||||
msgid "You must at least provide one of domain or geo_domain"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/models/geo_vector_layer.py:0
|
||||
#, python-format
|
||||
msgid "You need to provide an attribute that exists in %s model"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/models/geo_vector_layer.py:0
|
||||
#, python-format
|
||||
msgid "You need to select a numeric field"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_raster_layer__projection
|
||||
msgid "eg. EPSG:21781"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_raster_layer__request_encoding
|
||||
msgid "eg. REST"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_raster_layer__units
|
||||
msgid "eg. m"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_raster_layer__format_suffix
|
||||
msgid "eg. png"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_geo_field/domain_selector_geo_field.esm.js:0
|
||||
#, python-format
|
||||
msgid "geo_contains"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_geo_field/domain_selector_geo_field.esm.js:0
|
||||
#, python-format
|
||||
msgid "geo_equal"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_geo_field/domain_selector_geo_field.esm.js:0
|
||||
#, python-format
|
||||
msgid "geo_greater"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_geo_field/domain_selector_geo_field.esm.js:0
|
||||
#, python-format
|
||||
msgid "geo_intersect"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_geo_field/domain_selector_geo_field.esm.js:0
|
||||
#, python-format
|
||||
msgid "geo_lesser"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__ttype__geo_line
|
||||
msgid "geo_line"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__ttype__geo_multi_line
|
||||
msgid "geo_multi_line"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__ttype__geo_multi_point
|
||||
msgid "geo_multi_point"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__ttype__geo_multi_polygon
|
||||
msgid "geo_multi_polygon"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__ttype__geo_point
|
||||
msgid "geo_point"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__ttype__geo_polygon
|
||||
msgid "geo_polygon"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/models/base.py:0
|
||||
#, python-format
|
||||
msgid "geo_search is deprecated: uses search method defined on base model"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_geo_field/domain_selector_geo_field.esm.js:0
|
||||
#, python-format
|
||||
msgid "geo_touch"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_geo_field/domain_selector_geo_field.esm.js:0
|
||||
#, python-format
|
||||
msgid "geo_within"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/fields.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"geometry_columns table seems to be corrupted. SRID check is not possible"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_vector_layer__begin_color
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_vector_layer__end_color
|
||||
msgid "hex value"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_number_field/domain_selector_number_field.esm.js:0
|
||||
#, python-format
|
||||
msgid "in active_ids"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_number_field/domain_selector_number_field.esm.js:0
|
||||
#, python-format
|
||||
msgid "not in active_ids"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_model_fields__srid
|
||||
msgid "srid"
|
||||
msgstr ""
|
||||
|
|
@ -0,0 +1,971 @@
|
|||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * base_geoengine
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 16.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: \n"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/models/base.py:0
|
||||
#, python-format
|
||||
msgid "%s column does not exists or is not a geo field"
|
||||
msgstr "%s kolona ne postoji ili nije geo polje"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__active_on_startup
|
||||
msgid "Active On Startup"
|
||||
msgstr "Aktivan pri pokretanju"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__attribute_field_id
|
||||
msgid "Attribute field"
|
||||
msgstr "Polje atributa"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model,name:base_geoengine.model_base
|
||||
msgid "Base"
|
||||
msgstr "Osnova"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_vector_layer__geo_repr__basic
|
||||
msgid "Basic"
|
||||
msgstr "Osnovno"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__begin_color
|
||||
msgid "Begin color class"
|
||||
msgstr "Početna klasa boja"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_geoengine_view_form
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_view_form
|
||||
msgid "Classification"
|
||||
msgstr "Klasifikacija"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__classification
|
||||
msgid "Classification mode"
|
||||
msgstr "Režim klasifikacije"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__type
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type__code
|
||||
msgid "Code"
|
||||
msgstr "Šifra"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_vector_layer__geo_repr__colored
|
||||
msgid "Colored range/Chroma.js"
|
||||
msgstr "Obojeni raspon/Chroma.js"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_geoengine_view_form
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_view_form
|
||||
msgid "Colors"
|
||||
msgstr "Boje"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.ui.menu,name:base_geoengine.geoengine_base_view_menu
|
||||
msgid "Configuration"
|
||||
msgstr "Konfiguracija"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_model_fields__gist_index
|
||||
msgid "Create gist index"
|
||||
msgstr "Kreiraj gist indeks"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__create_uid
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type__create_uid
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__create_uid
|
||||
msgid "Created by"
|
||||
msgstr "Kreirao"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__create_date
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type__create_date
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__create_date
|
||||
msgid "Created on"
|
||||
msgstr "Kreirano"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_vector_layer__classification__custom
|
||||
msgid "Custom"
|
||||
msgstr "Prilagođeno"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_ui_view__default_extent
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_website_page__default_extent
|
||||
msgid "Default map extent"
|
||||
msgstr "Zadani opseg karte"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_ui_view__default_zoom
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_website_page__default_zoom
|
||||
msgid "Default map zoom"
|
||||
msgstr "Zadani zoom karte"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_raster_layer__params
|
||||
msgid "Dictiorary of values for dimensions as JSON"
|
||||
msgstr "Rječnik vrijednosti za dimenzije kao JSON"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__dimensions
|
||||
msgid "Dimensions"
|
||||
msgstr "Dimenzije"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/geoengine_controller/geoengine_controller.xml:0
|
||||
#, python-format
|
||||
msgid "Discard"
|
||||
msgstr "Napusti"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__display_polygon_labels
|
||||
msgid "Display Labels on Polygon"
|
||||
msgstr "Prikaži labele na poligonu"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__display_name
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type__display_name
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__display_name
|
||||
msgid "Display Name"
|
||||
msgstr "Prikazani naziv"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_raster_layer__raster_type__d_wms
|
||||
msgid "Distant WMS"
|
||||
msgstr "Udaljeni WMS"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/layers_panel/layers_panel.esm.js:0
|
||||
#, python-format
|
||||
msgid "Domain editing"
|
||||
msgstr "Uređivanje domena"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/layers_panel/layers_panel.esm.js:0
|
||||
#, python-format
|
||||
msgid "Editing vector layer"
|
||||
msgstr "Uređivanje vektorskog sloja"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__end_color
|
||||
msgid "End color class"
|
||||
msgstr "Završna klasa boja"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/geo_db.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Error, can not automatically initialize spatial postgis support. Database user may have to be superuser and postgres/postgis extensions with their devel header have to be installed. If you do not want Odoo to connect with a super user you can manually prepare your database. To do this, open a client to your database using a super user and run:\n"
|
||||
"CREATE EXTENSION postgis;\n"
|
||||
"CREATE EXTENSION postgis_topology;\n"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_model_fields__ttype
|
||||
msgid "Field Type"
|
||||
msgstr "Tip polja"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model,name:base_geoengine.model_ir_model_fields
|
||||
msgid "Fields"
|
||||
msgstr "Polja"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__format_suffix
|
||||
msgid "Format"
|
||||
msgstr "Format"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_raster_view_form
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_geoengine_view_form
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_view_form
|
||||
msgid "General"
|
||||
msgstr "Opšte"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/fields.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Geo Value %(geom_type)s must be of the same type %(geo_type)s as fields"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/fields.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Geo dimention modification is not implemented. We can not change dimention "
|
||||
"%(data)s to %(dim)s"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__geo_field_id
|
||||
msgid "Geo field"
|
||||
msgstr "Geo polje"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/fields.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Geo type modification is not implemented. We can not change type %(data)s to"
|
||||
" %(geo_type)s"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_ui_view__type__geoengine
|
||||
msgid "GeoEngine"
|
||||
msgstr "GeoEngine"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.ui.menu,name:base_geoengine.geoengine_base_menu
|
||||
msgid "GeoEngine Backend"
|
||||
msgstr "GeoEngine Backend"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geoengine_view_form
|
||||
msgid "GeoEngine Data"
|
||||
msgstr "GeoEngine podaci"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/geoengine_view.esm.js:0
|
||||
#, python-format
|
||||
msgid "Geoengine"
|
||||
msgstr "Geoengine"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:res.groups,name:base_geoengine.group_geoengine_admin
|
||||
msgid "Geoengine Admin"
|
||||
msgstr "Geoengine administrator"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:res.groups,name:base_geoengine.group_geoengine_user
|
||||
msgid "Geoengine User"
|
||||
msgstr "Geoengine korisnik"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__has_type
|
||||
msgid "Has Type"
|
||||
msgstr "Ima tip"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__id
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type__id
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__id
|
||||
msgid "ID"
|
||||
msgstr "ID"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_vector_layer__classification__interval
|
||||
msgid "Interval"
|
||||
msgstr "Razdoblje"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__is_wms
|
||||
msgid "Is Wms"
|
||||
msgstr "Je Wms"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__is_wmts
|
||||
msgid "Is Wmts"
|
||||
msgstr "Je Wmts"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__overlay
|
||||
msgid "Is overlay layer?"
|
||||
msgstr "Je prekrivni sloj?"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__geo_type__linestring
|
||||
msgid "LINESTRING"
|
||||
msgstr "LINESTRING"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer____last_update
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type____last_update
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer____last_update
|
||||
msgid "Last Modified on"
|
||||
msgstr "Zadnje mijenjano"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__write_uid
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type__write_uid
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__write_uid
|
||||
msgid "Last Updated by"
|
||||
msgstr "Zadnji ažurirao"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__write_date
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type__write_date
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__write_date
|
||||
msgid "Last Updated on"
|
||||
msgstr "Zadnje ažurirano"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__type_id
|
||||
msgid "Layer"
|
||||
msgstr "Sloj"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__name
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__name
|
||||
msgid "Layer Name"
|
||||
msgstr "Naziv sloja"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__layer_opacity
|
||||
msgid "Layer Opacity"
|
||||
msgstr "Neprozirnost sloja"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__sequence
|
||||
msgid "Layer Priority"
|
||||
msgstr "Prioritet sloja"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_raster_view_form
|
||||
msgid "Layer data"
|
||||
msgstr "Podaci sloja"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__readonly
|
||||
msgid "Layer is read only"
|
||||
msgstr "Sloj je samo za čitanje"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__sequence
|
||||
msgid "Layer priority"
|
||||
msgstr "Prioritet sloja"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_vector_layer__active_on_startup
|
||||
msgid "Layer will be shown on startup if checked."
|
||||
msgstr "Sloj će biti prikazan pri pokretanju ako je označeno."
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/layers_panel/layers_panel.xml:0
|
||||
#, python-format
|
||||
msgid "Layers ("
|
||||
msgstr "Slojevi ("
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_raster_layer__dimensions
|
||||
msgid "List of dimensions separated by ','"
|
||||
msgstr "Lista dimenzija odvojena sa ','"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__geo_type__multilinestring
|
||||
msgid "MULTILINESTRING"
|
||||
msgstr "MULTILINESTRING"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__geo_type__multipoint
|
||||
msgid "MULTIPOINT"
|
||||
msgstr "MULTIPOINT"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__geo_type__multipolygon
|
||||
msgid "MULTIPOLYGON"
|
||||
msgstr "MULTIPOLYGON"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__matrix_set
|
||||
msgid "Matrix set"
|
||||
msgstr "Matrica set"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__max_extent
|
||||
msgid "Max extent"
|
||||
msgstr "Maksimalni opseg"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/geoengine_arch_parser.esm.js:0
|
||||
#, python-format
|
||||
msgid "Missing ${INFO_BOX_ATTRIBUTE} template."
|
||||
msgstr "Nedostaje ${INFO_BOX_ATTRIBUTE} šablon."
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__model_name
|
||||
msgid "Model"
|
||||
msgstr "Model"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__model_domain
|
||||
msgid "Model Domain"
|
||||
msgstr "Domen modela"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__model_id
|
||||
msgid "Model to use"
|
||||
msgstr "Model za korištenje"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__model_view_id
|
||||
msgid "Model view"
|
||||
msgstr "Pogled modela"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type__name
|
||||
msgid "Name"
|
||||
msgstr "Naziv:"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_raster_layer__params_wms
|
||||
msgid "Need to provide at least a LAYERS param"
|
||||
msgstr "Trebate pružiti najmanje LAYERS parametar"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/geoengine_controller/geoengine_controller.esm.js:0
|
||||
#, python-format
|
||||
msgid "New record"
|
||||
msgstr "Novi zapis"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/models/base.py:0
|
||||
#, python-format
|
||||
msgid "No GeoEngine view defined for the model %s"
|
||||
msgstr "Nije definisan GeoEngine pogled za model %s"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/models/base.py:0
|
||||
#, python-format
|
||||
msgid "No raster layer for view %s"
|
||||
msgstr "Nema rasterskog sloja za pogled %s"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__nb_class
|
||||
msgid "Number of class"
|
||||
msgstr "Broj klasa"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/geoengine_renderer/geoengine_renderer.xml:0
|
||||
#, python-format
|
||||
msgid "OPEN"
|
||||
msgstr "OTVORI"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_raster_layer__raster_type__odoo
|
||||
msgid "Odoo field"
|
||||
msgstr "Odoo polje"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_raster_view_form
|
||||
msgid "Odoo layer data (Not implemented)"
|
||||
msgstr "Odoo podaci sloja (nije implementirano)"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__field_id
|
||||
msgid "Odoo layer field to use"
|
||||
msgstr "Odoo polje sloja za korištenje"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_raster_layer__raster_type__osm
|
||||
msgid "OpenStreetMap"
|
||||
msgstr "OpenStreetMap"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__geo_type__point
|
||||
msgid "POINT"
|
||||
msgstr "POINT"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__geo_type__polygon
|
||||
msgid "POLYGON"
|
||||
msgstr "POLYGON"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__params
|
||||
msgid "Params"
|
||||
msgstr "Parametri"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__params_wms
|
||||
msgid "Params WMS"
|
||||
msgstr "Parametri WMS"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/models/base.py:0
|
||||
#, python-format
|
||||
msgid "Please create a view or modify view mode"
|
||||
msgstr "Molimo kreirajte pogled ili modificirajte režim pogleda"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_model_fields__dim
|
||||
msgid "PostGIs Dimension"
|
||||
msgstr "PostGIs dimenzija"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_model_fields__geo_type
|
||||
msgid "PostGIs type"
|
||||
msgstr "PostGIs tip"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__projection
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_ui_view__projection
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_website_page__projection
|
||||
msgid "Projection"
|
||||
msgstr "Projekcija"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_vector_layer__geo_repr__proportion
|
||||
msgid "Proportional Symbol"
|
||||
msgstr "Proporcionalni simbol"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_vector_layer__classification__quantile
|
||||
msgid "Quantile"
|
||||
msgstr "Kvantil"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geoengine_view_form
|
||||
msgid "Raster (Background layers)"
|
||||
msgstr "Raster (pozadinski slojevi)"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.actions.act_window,name:base_geoengine.geo_engine_view_rater_action
|
||||
#: model:ir.model,name:base_geoengine.model_geoengine_raster_layer
|
||||
msgid "Raster Layer"
|
||||
msgstr "Rasterski sloj"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.ui.menu,name:base_geoengine.geoengine_raster_layer_menu
|
||||
msgid "Raster Layer Management"
|
||||
msgstr "Upravljanje rasterskim slojem"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model,name:base_geoengine.model_geoengine_raster_layer_type
|
||||
msgid "Raster Layer Type"
|
||||
msgstr "Tip rasterskog sloja"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_raster_view_form
|
||||
msgid "Raster Layer View"
|
||||
msgstr "Pogled rasterskog sloja"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__raster_type
|
||||
msgid "Raster layer type"
|
||||
msgstr "Tip rasterskog sloja"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_ui_view__raster_layer_ids
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_website_page__raster_layer_ids
|
||||
msgid "Raster layers"
|
||||
msgstr "Rasterski slojevi"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/layers_panel/layers_panel.xml:0
|
||||
#, python-format
|
||||
msgid "Rasters"
|
||||
msgstr "Rasteri"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/records_panel/records_panel.xml:0
|
||||
#, python-format
|
||||
msgid "Records ("
|
||||
msgstr "Zapisi ("
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_view_form
|
||||
msgid "Related Model"
|
||||
msgstr "Kreirano"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__view_id
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__view_id
|
||||
msgid "Related View"
|
||||
msgstr "Povezani pogled"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_geoengine_view_form
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_view_form
|
||||
msgid "Representation"
|
||||
msgstr "Reprezentacija"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__geo_repr
|
||||
msgid "Representation mode"
|
||||
msgstr "Režim reprezentacije"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/fields.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Reprojection of column is not implemented. We can not change srid %(srid)s "
|
||||
"to %(data)s"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__request_encoding
|
||||
msgid "Request encoding"
|
||||
msgstr "Kodiranje zahtjeva"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__resolutions
|
||||
msgid "Resolutions"
|
||||
msgstr "Rezolucije"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_ui_view__restricted_extent
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_website_page__restricted_extent
|
||||
msgid "Restricted map extent"
|
||||
msgstr "Ograničeni opseg karte"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/geoengine_controller/geoengine_controller.xml:0
|
||||
#, python-format
|
||||
msgid "Save"
|
||||
msgstr "Spremi"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/records_panel/search_bar_records/search_bar_records.xml:0
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/records_panel/search_bar_records/search_bar_records.xml:0
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/records_panel/search_bar_records/search_bar_records.xml:0
|
||||
#, python-format
|
||||
msgid "Search..."
|
||||
msgstr "Pretraži..."
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__server_type
|
||||
msgid "Server Type"
|
||||
msgstr "Tip poslužitelja"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type__service
|
||||
msgid "Service"
|
||||
msgstr "Usluga"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__url
|
||||
msgid "Service URL"
|
||||
msgstr "URL servisa"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/geo_convertion_helper.py:0
|
||||
#, python-format
|
||||
msgid "Shapely or geojson are not available in the sys path"
|
||||
msgstr "Shapely ili geojson nisu dostupni u sys path"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_geo_field_input/domain_selector_geo_field_input.esm.js:0
|
||||
#, python-format
|
||||
msgid "Subdomain"
|
||||
msgstr "Poddomen"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/models/geo_vector_layer.py:0
|
||||
#, python-format
|
||||
msgid "The geo_field_id must be a field in %s model"
|
||||
msgstr "geo_field_id mora biti polje u %s modelu"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_raster_layer__server_type
|
||||
msgid ""
|
||||
"The type of the remote WMS server: mapserver, geoserver, carmentaserver, or "
|
||||
"qgis"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_vector_layer__classification__unique
|
||||
msgid "Unique value"
|
||||
msgstr "Jedinstvena vrijednost"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__units
|
||||
msgid "Units"
|
||||
msgstr "Jedinice"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__use_to_edit
|
||||
msgid "Use to edit"
|
||||
msgstr "Koristi za uređivanje"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_view_form
|
||||
msgid "Vector"
|
||||
msgstr "Vektor"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geoengine_view_form
|
||||
msgid "Vector (Active layers)"
|
||||
msgstr "Vektor (aktivni slojevi)"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.actions.act_window,name:base_geoengine.geo_engine_view_raster_action
|
||||
#: model:ir.actions.act_window,name:base_geoengine.geo_vector_geoengine_view_action
|
||||
#: model:ir.model,name:base_geoengine.model_geoengine_vector_layer
|
||||
msgid "Vector Layer"
|
||||
msgstr "Vektorski sloj"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.ui.menu,name:base_geoengine.geoengine_vector_layer_menu
|
||||
msgid "Vector Layer Management"
|
||||
msgstr "Upravljanje vektorskim slojem"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_ui_view__vector_layer_ids
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_website_page__vector_layer_ids
|
||||
msgid "Vector layers"
|
||||
msgstr "Vektorski slojevi"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/layers_panel/layers_panel.xml:0
|
||||
#, python-format
|
||||
msgid "Vectors"
|
||||
msgstr "Vektori"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model,name:base_geoengine.model_ir_ui_view
|
||||
msgid "View"
|
||||
msgstr "Pregled"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.ui.menu,name:base_geoengine.geoengine_view_menu
|
||||
msgid "View Management"
|
||||
msgstr "Upravljanje pogledima"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_ui_view__type
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_website_page__type
|
||||
msgid "View Type"
|
||||
msgstr "Vrsta pregleda"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.actions.act_window,name:base_geoengine.geo_engine_view_action
|
||||
msgid "Views"
|
||||
msgstr "Pogledi"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_raster_view_form
|
||||
msgid "WMS options"
|
||||
msgstr "WMS opcije"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_raster_layer__raster_type__wmts
|
||||
msgid "WMTS"
|
||||
msgstr "WMTS"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_raster_view_form
|
||||
msgid "WMTS options"
|
||||
msgstr "WMTS opcije"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/geoengine_controller/geoengine_controller.esm.js:0
|
||||
#, python-format
|
||||
msgid "Warning"
|
||||
msgstr "Upozorenje"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/geo_convertion_helper.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Write/create/search geo type must be wkt/geojson string or must respond to "
|
||||
"wkt"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/geoengine_controller/geoengine_controller.esm.js:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"You are about to create a new record without having displayed all the "
|
||||
"others. A risk of overlap could occur. Would you like to continue ?"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/models/base.py:0
|
||||
#, python-format
|
||||
msgid "You must at least provide one of domain or geo_domain"
|
||||
msgstr "Morate pružiti najmanje jedan od domena ili geo_domena"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/models/geo_vector_layer.py:0
|
||||
#, python-format
|
||||
msgid "You need to provide an attribute that exists in %s model"
|
||||
msgstr "Trebate pružiti atribut koji postoji u %s modelu"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/models/geo_vector_layer.py:0
|
||||
#, python-format
|
||||
msgid "You need to select a numeric field"
|
||||
msgstr "Trebate odabrati numeričko polje"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_raster_layer__projection
|
||||
msgid "eg. EPSG:21781"
|
||||
msgstr "npr. EPSG:21781"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_raster_layer__request_encoding
|
||||
msgid "eg. REST"
|
||||
msgstr "npr. REST"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_raster_layer__units
|
||||
msgid "eg. m"
|
||||
msgstr "npr. m"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_raster_layer__format_suffix
|
||||
msgid "eg. png"
|
||||
msgstr "npr. png"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_geo_field/domain_selector_geo_field.esm.js:0
|
||||
#, python-format
|
||||
msgid "geo_contains"
|
||||
msgstr "geo_contains"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_geo_field/domain_selector_geo_field.esm.js:0
|
||||
#, python-format
|
||||
msgid "geo_equal"
|
||||
msgstr "geo_equal"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_geo_field/domain_selector_geo_field.esm.js:0
|
||||
#, python-format
|
||||
msgid "geo_greater"
|
||||
msgstr "geo_greater"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_geo_field/domain_selector_geo_field.esm.js:0
|
||||
#, python-format
|
||||
msgid "geo_intersect"
|
||||
msgstr "geo_intersect"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_geo_field/domain_selector_geo_field.esm.js:0
|
||||
#, python-format
|
||||
msgid "geo_lesser"
|
||||
msgstr "geo_lesser"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__ttype__geo_line
|
||||
msgid "geo_line"
|
||||
msgstr "geo_line"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__ttype__geo_multi_line
|
||||
msgid "geo_multi_line"
|
||||
msgstr "geo_multi_line"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__ttype__geo_multi_point
|
||||
msgid "geo_multi_point"
|
||||
msgstr "geo_multi_point"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__ttype__geo_multi_polygon
|
||||
msgid "geo_multi_polygon"
|
||||
msgstr "geo_multi_polygon"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__ttype__geo_point
|
||||
msgid "geo_point"
|
||||
msgstr "geo_point"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__ttype__geo_polygon
|
||||
msgid "geo_polygon"
|
||||
msgstr "geo_polygon"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/models/base.py:0
|
||||
#, python-format
|
||||
msgid "geo_search is deprecated: uses search method defined on base model"
|
||||
msgstr "geo_search je zastarjelo: koristi search metodu definisanu na osnovnom modelu"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_geo_field/domain_selector_geo_field.esm.js:0
|
||||
#, python-format
|
||||
msgid "geo_touch"
|
||||
msgstr "geo_touch"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_geo_field/domain_selector_geo_field.esm.js:0
|
||||
#, python-format
|
||||
msgid "geo_within"
|
||||
msgstr "geo_within"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/fields.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"geometry_columns table seems to be corrupted. SRID check is not possible"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_vector_layer__begin_color
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_vector_layer__end_color
|
||||
msgid "hex value"
|
||||
msgstr "hex vrijednost"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_number_field/domain_selector_number_field.esm.js:0
|
||||
#, python-format
|
||||
msgid "in active_ids"
|
||||
msgstr "u active_ids"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_number_field/domain_selector_number_field.esm.js:0
|
||||
#, python-format
|
||||
msgid "not in active_ids"
|
||||
msgstr "nije u active_ids"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_model_fields__srid
|
||||
msgid "srid"
|
||||
msgstr "srid"
|
||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,998 @@
|
|||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * base_geoengine
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 16.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2025-07-28 09:25+0000\n"
|
||||
"Last-Translator: mymage <stefano.consolaro@mymage.it>\n"
|
||||
"Language-Team: none\n"
|
||||
"Language: it\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 5.10.4\n"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/models/base.py:0
|
||||
#, python-format
|
||||
msgid "%s column does not exists or is not a geo field"
|
||||
msgstr "La colonna %s non esiste, o non è un campo geo"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__active_on_startup
|
||||
msgid "Active On Startup"
|
||||
msgstr "Attivo all'avvio"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__attribute_field_id
|
||||
msgid "Attribute field"
|
||||
msgstr "Campo attributo"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model,name:base_geoengine.model_base
|
||||
msgid "Base"
|
||||
msgstr "Base"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_vector_layer__geo_repr__basic
|
||||
msgid "Basic"
|
||||
msgstr "Base"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__begin_color
|
||||
msgid "Begin color class"
|
||||
msgstr "Classe colore inizio"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_geoengine_view_form
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_view_form
|
||||
msgid "Classification"
|
||||
msgstr "Classificazione"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__classification
|
||||
msgid "Classification mode"
|
||||
msgstr "Modo di classificazione"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__type
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type__code
|
||||
msgid "Code"
|
||||
msgstr "Codice"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_vector_layer__geo_repr__colored
|
||||
msgid "Colored range/Chroma.js"
|
||||
msgstr "Intervallo colorato/Chroma.js"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_geoengine_view_form
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_view_form
|
||||
msgid "Colors"
|
||||
msgstr "Colori"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.ui.menu,name:base_geoengine.geoengine_base_view_menu
|
||||
msgid "Configuration"
|
||||
msgstr "Configurazione"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_model_fields__gist_index
|
||||
msgid "Create gist index"
|
||||
msgstr "Crea indice gist"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__create_uid
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type__create_uid
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__create_uid
|
||||
msgid "Created by"
|
||||
msgstr "Creato da"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__create_date
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type__create_date
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__create_date
|
||||
msgid "Created on"
|
||||
msgstr "Creato il"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_vector_layer__classification__custom
|
||||
msgid "Custom"
|
||||
msgstr "Personalizzato"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_ui_view__default_extent
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_website_page__default_extent
|
||||
msgid "Default map extent"
|
||||
msgstr "Estensione predefinita della mappa"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_ui_view__default_zoom
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_website_page__default_zoom
|
||||
msgid "Default map zoom"
|
||||
msgstr "Zoom predefinito della mappa"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_raster_layer__params
|
||||
msgid "Dictiorary of values for dimensions as JSON"
|
||||
msgstr "Dizionario JSON di valori delle dimensioni"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__dimensions
|
||||
msgid "Dimensions"
|
||||
msgstr "Dimensioni"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/geoengine_controller/geoengine_controller.xml:0
|
||||
#, python-format
|
||||
msgid "Discard"
|
||||
msgstr "Abbandona"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__display_polygon_labels
|
||||
msgid "Display Labels on Polygon"
|
||||
msgstr "Mostra etichette sul poligono"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__display_name
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type__display_name
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__display_name
|
||||
msgid "Display Name"
|
||||
msgstr "Nome visualizzato"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_raster_layer__raster_type__d_wms
|
||||
msgid "Distant WMS"
|
||||
msgstr "WMS remoto"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/layers_panel/layers_panel.esm.js:0
|
||||
#, python-format
|
||||
msgid "Domain editing"
|
||||
msgstr "Modifica dminio"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/layers_panel/layers_panel.esm.js:0
|
||||
#, python-format
|
||||
msgid "Editing vector layer"
|
||||
msgstr "Modifica livello vettore"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__end_color
|
||||
msgid "End color class"
|
||||
msgstr "Classe colore fine"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/geo_db.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Error, can not automatically initialize spatial postgis support. Database "
|
||||
"user may have to be superuser and postgres/postgis extensions with their "
|
||||
"devel header have to be installed. If you do not want Odoo to connect with a "
|
||||
"super user you can manually prepare your database. To do this, open a client "
|
||||
"to your database using a super user and run:\n"
|
||||
"CREATE EXTENSION postgis;\n"
|
||||
"CREATE EXTENSION postgis_topology;\n"
|
||||
msgstr ""
|
||||
"Errore, impossibile inizializzare automaticamente il supporto spaziale "
|
||||
"postgis. L'utente database deve essere superutente e le estensioni postgres/"
|
||||
"postgis con le loro intestazioni devono essere installate. Se non si vuole "
|
||||
"che Odoo si connetta con un super utente si può preparare manualmente il "
|
||||
"database. Per questo, aprire un client verso il database utilizzando un "
|
||||
"super utente ed eseguendo:\n"
|
||||
"CREATE EXTENSION postgis;\n"
|
||||
"CREATE EXTENSION postgis_topology;\n"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_model_fields__ttype
|
||||
msgid "Field Type"
|
||||
msgstr "Tipo campo"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model,name:base_geoengine.model_ir_model_fields
|
||||
msgid "Fields"
|
||||
msgstr "Campi"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__format_suffix
|
||||
msgid "Format"
|
||||
msgstr "Formato"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_raster_view_form
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_geoengine_view_form
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_view_form
|
||||
msgid "General"
|
||||
msgstr "Generale"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/fields.py:0
|
||||
#, python-format
|
||||
msgid "Geo Value %(geom_type)s must be of the same type %(geo_type)s as fields"
|
||||
msgstr ""
|
||||
"Il valore geo %(geom_type)s deve essere dello stesso tipo %(geo_type)s come "
|
||||
"i campi"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/fields.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Geo dimention modification is not implemented. We can not change dimention "
|
||||
"%(data)s to %(dim)s"
|
||||
msgstr ""
|
||||
"La modifica della dimensione geo non è implementata. Non si possono cambiare "
|
||||
"le dimensioni %(data)s a %(dim)s"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__geo_field_id
|
||||
msgid "Geo field"
|
||||
msgstr "Campo geo"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/fields.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Geo type modification is not implemented. We can not change type %(data)s to "
|
||||
"%(geo_type)s"
|
||||
msgstr ""
|
||||
"La modifica del tipo geo non è implementata. Non si può cambiare il tipo "
|
||||
"%(data)s a %(geo_type)s"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_ui_view__type__geoengine
|
||||
msgid "GeoEngine"
|
||||
msgstr "GeoEngine"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.ui.menu,name:base_geoengine.geoengine_base_menu
|
||||
msgid "GeoEngine Backend"
|
||||
msgstr "Backend GeoEngine"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geoengine_view_form
|
||||
msgid "GeoEngine Data"
|
||||
msgstr "Dati GeoEngine"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/geoengine_view.esm.js:0
|
||||
#, python-format
|
||||
msgid "Geoengine"
|
||||
msgstr "GeoEngine"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:res.groups,name:base_geoengine.group_geoengine_admin
|
||||
msgid "Geoengine Admin"
|
||||
msgstr "Amministratore Geoengine"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:res.groups,name:base_geoengine.group_geoengine_user
|
||||
msgid "Geoengine User"
|
||||
msgstr "Utente GeoEngine"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__has_type
|
||||
msgid "Has Type"
|
||||
msgstr "Ha tipo"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__id
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type__id
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__id
|
||||
msgid "ID"
|
||||
msgstr "ID"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_vector_layer__classification__interval
|
||||
msgid "Interval"
|
||||
msgstr "Intervallo"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__is_wms
|
||||
msgid "Is Wms"
|
||||
msgstr "È WMS"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__is_wmts
|
||||
msgid "Is Wmts"
|
||||
msgstr "È WMTS"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__overlay
|
||||
msgid "Is overlay layer?"
|
||||
msgstr "È livello in sovraimpressione?"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__geo_type__linestring
|
||||
msgid "LINESTRING"
|
||||
msgstr "LINESTRING"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer____last_update
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type____last_update
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer____last_update
|
||||
msgid "Last Modified on"
|
||||
msgstr "Ultima modifica il"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__write_uid
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type__write_uid
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__write_uid
|
||||
msgid "Last Updated by"
|
||||
msgstr "Ultimo aggiornamento di"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__write_date
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type__write_date
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__write_date
|
||||
msgid "Last Updated on"
|
||||
msgstr "Ultimo aggiornamento il"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__type_id
|
||||
msgid "Layer"
|
||||
msgstr "Livello"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__name
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__name
|
||||
msgid "Layer Name"
|
||||
msgstr "Nome livello"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__layer_opacity
|
||||
msgid "Layer Opacity"
|
||||
msgstr "Opacità ivello"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__sequence
|
||||
msgid "Layer Priority"
|
||||
msgstr "Priorità livello"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_raster_view_form
|
||||
msgid "Layer data"
|
||||
msgstr "Dati ivello"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__readonly
|
||||
msgid "Layer is read only"
|
||||
msgstr "Il ivello è in sola lettura"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__sequence
|
||||
msgid "Layer priority"
|
||||
msgstr "Priorità livello"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_vector_layer__active_on_startup
|
||||
msgid "Layer will be shown on startup if checked."
|
||||
msgstr "Il livello verrà mostrato all'avvio se selezionato."
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/layers_panel/layers_panel.xml:0
|
||||
#, python-format
|
||||
msgid "Layers ("
|
||||
msgstr "Livelli ("
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_raster_layer__dimensions
|
||||
msgid "List of dimensions separated by ','"
|
||||
msgstr "Elenco dimensioni separate da ','"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__geo_type__multilinestring
|
||||
msgid "MULTILINESTRING"
|
||||
msgstr "MULTILINESTRING"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__geo_type__multipoint
|
||||
msgid "MULTIPOINT"
|
||||
msgstr "MULTIPOINT"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__geo_type__multipolygon
|
||||
msgid "MULTIPOLYGON"
|
||||
msgstr "MULTIPOLYGON"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__matrix_set
|
||||
msgid "Matrix set"
|
||||
msgstr "Set matrice"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__max_extent
|
||||
msgid "Max extent"
|
||||
msgstr "Estensione massima"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/geoengine_arch_parser.esm.js:0
|
||||
#, python-format
|
||||
msgid "Missing ${INFO_BOX_ATTRIBUTE} template."
|
||||
msgstr "Modello ${INFO_BOX_ATTRIBUTE} non trovato."
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__model_name
|
||||
msgid "Model"
|
||||
msgstr "Modello"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__model_domain
|
||||
msgid "Model Domain"
|
||||
msgstr "Dominio modello"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__model_id
|
||||
msgid "Model to use"
|
||||
msgstr "Modello da usare"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__model_view_id
|
||||
msgid "Model view"
|
||||
msgstr "Vista modello"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type__name
|
||||
msgid "Name"
|
||||
msgstr "Nome"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_raster_layer__params_wms
|
||||
msgid "Need to provide at least a LAYERS param"
|
||||
msgstr "Serve fornire almeno un parametro LAYERS"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/geoengine_controller/geoengine_controller.esm.js:0
|
||||
#, python-format
|
||||
msgid "New record"
|
||||
msgstr "Nuovo record"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/models/base.py:0
|
||||
#, python-format
|
||||
msgid "No GeoEngine view defined for the model %s"
|
||||
msgstr "Nessuna vista GeoEngine definita per il modello %s"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/models/base.py:0
|
||||
#, python-format
|
||||
msgid "No raster layer for view %s"
|
||||
msgstr "Nessuno livello raster per la vista %s"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__nb_class
|
||||
msgid "Number of class"
|
||||
msgstr "Numero di classi"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/geoengine_renderer/geoengine_renderer.xml:0
|
||||
#, python-format
|
||||
msgid "OPEN"
|
||||
msgstr "OPEN"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_raster_layer__raster_type__odoo
|
||||
msgid "Odoo field"
|
||||
msgstr "Campo Odoo"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_raster_view_form
|
||||
msgid "Odoo layer data (Not implemented)"
|
||||
msgstr "Livello dati Odoo (non implementato)"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__field_id
|
||||
msgid "Odoo layer field to use"
|
||||
msgstr "Livello campo Odoo da usare"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_raster_layer__raster_type__osm
|
||||
msgid "OpenStreetMap"
|
||||
msgstr "OpenStreetMap"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__geo_type__point
|
||||
msgid "POINT"
|
||||
msgstr "POINT"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__geo_type__polygon
|
||||
msgid "POLYGON"
|
||||
msgstr "POLYGON"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__params
|
||||
msgid "Params"
|
||||
msgstr "Parametri"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__params_wms
|
||||
msgid "Params WMS"
|
||||
msgstr "Parametri WMS"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/models/base.py:0
|
||||
#, python-format
|
||||
msgid "Please create a view or modify view mode"
|
||||
msgstr "Creare una vista o modificare la modalità di visualizzazione"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_model_fields__dim
|
||||
msgid "PostGIs Dimension"
|
||||
msgstr "Dimensione PostGIs"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_model_fields__geo_type
|
||||
msgid "PostGIs type"
|
||||
msgstr "Tipo PostGIs"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__projection
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_ui_view__projection
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_website_page__projection
|
||||
msgid "Projection"
|
||||
msgstr "Proiezione"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_vector_layer__geo_repr__proportion
|
||||
msgid "Proportional Symbol"
|
||||
msgstr "Simbolo proporzionale"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_vector_layer__classification__quantile
|
||||
msgid "Quantile"
|
||||
msgstr "Quantile"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geoengine_view_form
|
||||
msgid "Raster (Background layers)"
|
||||
msgstr "Raster (livello di sfondo)"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.actions.act_window,name:base_geoengine.geo_engine_view_rater_action
|
||||
#: model:ir.model,name:base_geoengine.model_geoengine_raster_layer
|
||||
msgid "Raster Layer"
|
||||
msgstr "Livello raster"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.ui.menu,name:base_geoengine.geoengine_raster_layer_menu
|
||||
msgid "Raster Layer Management"
|
||||
msgstr "Gestione livello raster"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model,name:base_geoengine.model_geoengine_raster_layer_type
|
||||
msgid "Raster Layer Type"
|
||||
msgstr "Tipo livello raster"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_raster_view_form
|
||||
msgid "Raster Layer View"
|
||||
msgstr "Vista livello raster"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__raster_type
|
||||
msgid "Raster layer type"
|
||||
msgstr "Tipo livello raster"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_ui_view__raster_layer_ids
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_website_page__raster_layer_ids
|
||||
msgid "Raster layers"
|
||||
msgstr "Livelli raster"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/layers_panel/layers_panel.xml:0
|
||||
#, python-format
|
||||
msgid "Rasters"
|
||||
msgstr "Raster"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/records_panel/records_panel.xml:0
|
||||
#, python-format
|
||||
msgid "Records ("
|
||||
msgstr "Record ("
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_view_form
|
||||
msgid "Related Model"
|
||||
msgstr "Modello correlato"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__view_id
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__view_id
|
||||
msgid "Related View"
|
||||
msgstr "Viste correlata"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_geoengine_view_form
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_view_form
|
||||
msgid "Representation"
|
||||
msgstr "Rappresentazione"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__geo_repr
|
||||
msgid "Representation mode"
|
||||
msgstr "Modalità di rappresentazione"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/fields.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Reprojection of column is not implemented. We can not change srid %(srid)s "
|
||||
"to %(data)s"
|
||||
msgstr ""
|
||||
"Riproiezione della colonna nn implementata. Non si può modificare srid "
|
||||
"%(srid)s a %(data)s"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__request_encoding
|
||||
msgid "Request encoding"
|
||||
msgstr "Codifica richiesta"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__resolutions
|
||||
msgid "Resolutions"
|
||||
msgstr "Risoluzione"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_ui_view__restricted_extent
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_website_page__restricted_extent
|
||||
msgid "Restricted map extent"
|
||||
msgstr "Estensione ristretta della mappa"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/geoengine_controller/geoengine_controller.xml:0
|
||||
#, python-format
|
||||
msgid "Save"
|
||||
msgstr "Salva"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/records_panel/search_bar_records/search_bar_records.xml:0
|
||||
#, python-format
|
||||
msgid "Search..."
|
||||
msgstr "Cerca..."
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__server_type
|
||||
msgid "Server Type"
|
||||
msgstr "Tipo server"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type__service
|
||||
msgid "Service"
|
||||
msgstr "Servizio"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__url
|
||||
msgid "Service URL"
|
||||
msgstr "URL servizio"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/geo_convertion_helper.py:0
|
||||
#, python-format
|
||||
msgid "Shapely or geojson are not available in the sys path"
|
||||
msgstr "Shapely o geojson non sono disponibili nel path di sistema"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_geo_field_input/domain_selector_geo_field_input.esm.js:0
|
||||
#, python-format
|
||||
msgid "Subdomain"
|
||||
msgstr "Sottodominio"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/models/geo_vector_layer.py:0
|
||||
#, python-format
|
||||
msgid "The geo_field_id must be a field in %s model"
|
||||
msgstr "Il geo_field_id deve essere un campo nel modello %s"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_raster_layer__server_type
|
||||
msgid ""
|
||||
"The type of the remote WMS server: mapserver, geoserver, carmentaserver, or "
|
||||
"qgis"
|
||||
msgstr ""
|
||||
"Il tipo sel server WMS remoto: mapserver, geoserver, carmentaserver, o qgis"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_vector_layer__classification__unique
|
||||
msgid "Unique value"
|
||||
msgstr "Valore unico"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__units
|
||||
msgid "Units"
|
||||
msgstr "Unità"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__use_to_edit
|
||||
msgid "Use to edit"
|
||||
msgstr "Usa per modificare"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_view_form
|
||||
msgid "Vector"
|
||||
msgstr "Vettore"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geoengine_view_form
|
||||
msgid "Vector (Active layers)"
|
||||
msgstr "Vettore (livelli attivi)"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.actions.act_window,name:base_geoengine.geo_engine_view_raster_action
|
||||
#: model:ir.actions.act_window,name:base_geoengine.geo_vector_geoengine_view_action
|
||||
#: model:ir.model,name:base_geoengine.model_geoengine_vector_layer
|
||||
msgid "Vector Layer"
|
||||
msgstr "Livello vettoriale"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.ui.menu,name:base_geoengine.geoengine_vector_layer_menu
|
||||
msgid "Vector Layer Management"
|
||||
msgstr "Gestione livello vettoriale"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_ui_view__vector_layer_ids
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_website_page__vector_layer_ids
|
||||
msgid "Vector layers"
|
||||
msgstr "Livelli vettoriali"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/layers_panel/layers_panel.xml:0
|
||||
#, python-format
|
||||
msgid "Vectors"
|
||||
msgstr "Vettori"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model,name:base_geoengine.model_ir_ui_view
|
||||
msgid "View"
|
||||
msgstr "Vista"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.ui.menu,name:base_geoengine.geoengine_view_menu
|
||||
msgid "View Management"
|
||||
msgstr "Gestione vista"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_ui_view__type
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_website_page__type
|
||||
msgid "View Type"
|
||||
msgstr "Tipo vista"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.actions.act_window,name:base_geoengine.geo_engine_view_action
|
||||
msgid "Views"
|
||||
msgstr "Viste"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_raster_view_form
|
||||
msgid "WMS options"
|
||||
msgstr "Opzioni WMS"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_raster_layer__raster_type__wmts
|
||||
msgid "WMTS"
|
||||
msgstr "WMTS"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_raster_view_form
|
||||
msgid "WMTS options"
|
||||
msgstr "Opzioni WMTS"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/geoengine_controller/geoengine_controller.esm.js:0
|
||||
#, python-format
|
||||
msgid "Warning"
|
||||
msgstr "Attenzione"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/geo_convertion_helper.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Write/create/search geo type must be wkt/geojson string or must respond to "
|
||||
"wkt"
|
||||
msgstr ""
|
||||
"Il tipo geo scrittura/creazione/ricerca deve essere una stringa wkt/geojson "
|
||||
"odeve rispondere a wkt"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/geoengine_controller/geoengine_controller.esm.js:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"You are about to create a new record without having displayed all the "
|
||||
"others. A risk of overlap could occur. Would you like to continue ?"
|
||||
msgstr ""
|
||||
"Si sta per creare un nuovo record senza aver disabilitato tutti gli altri. "
|
||||
"C'è il rischio di sovrapposizione. Si vuole continuare?"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/models/base.py:0
|
||||
#, python-format
|
||||
msgid "You must at least provide one of domain or geo_domain"
|
||||
msgstr "Bisogna fornire almeno un dominio o un geo_domain"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/models/geo_vector_layer.py:0
|
||||
#, python-format
|
||||
msgid "You need to provide an attribute that exists in %s model"
|
||||
msgstr "Bisogna fornire un attributo che esista nel modello %s"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/models/geo_vector_layer.py:0
|
||||
#, python-format
|
||||
msgid "You need to select a numeric field"
|
||||
msgstr "Bisogna selezionare un campo numerico"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_raster_layer__projection
|
||||
msgid "eg. EPSG:21781"
|
||||
msgstr "es. EPSG:21781"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_raster_layer__request_encoding
|
||||
msgid "eg. REST"
|
||||
msgstr "es. REST"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_raster_layer__units
|
||||
msgid "eg. m"
|
||||
msgstr "es. m"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_raster_layer__format_suffix
|
||||
msgid "eg. png"
|
||||
msgstr "es. png"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_geo_field/domain_selector_geo_field.esm.js:0
|
||||
#, python-format
|
||||
msgid "geo_contains"
|
||||
msgstr "geo_contains"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_geo_field/domain_selector_geo_field.esm.js:0
|
||||
#, python-format
|
||||
msgid "geo_equal"
|
||||
msgstr "geo_equal"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_geo_field/domain_selector_geo_field.esm.js:0
|
||||
#, python-format
|
||||
msgid "geo_greater"
|
||||
msgstr "geo_greater"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_geo_field/domain_selector_geo_field.esm.js:0
|
||||
#, python-format
|
||||
msgid "geo_intersect"
|
||||
msgstr "geo_intersect"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_geo_field/domain_selector_geo_field.esm.js:0
|
||||
#, python-format
|
||||
msgid "geo_lesser"
|
||||
msgstr "geo_lesser"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__ttype__geo_line
|
||||
msgid "geo_line"
|
||||
msgstr "geo_line"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__ttype__geo_multi_line
|
||||
msgid "geo_multi_line"
|
||||
msgstr "geo_multi_line"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__ttype__geo_multi_point
|
||||
msgid "geo_multi_point"
|
||||
msgstr "geo_multi_point"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__ttype__geo_multi_polygon
|
||||
msgid "geo_multi_polygon"
|
||||
msgstr "geo_multi_polygon"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__ttype__geo_point
|
||||
msgid "geo_point"
|
||||
msgstr "geo_point"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__ttype__geo_polygon
|
||||
msgid "geo_polygon"
|
||||
msgstr "geo_polygon"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/models/base.py:0
|
||||
#, python-format
|
||||
msgid "geo_search is deprecated: uses search method defined on base model"
|
||||
msgstr ""
|
||||
"geo_search è deprecat: usare il motodo ricerca definito nel modello base"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_geo_field/domain_selector_geo_field.esm.js:0
|
||||
#, python-format
|
||||
msgid "geo_touch"
|
||||
msgstr "geo_touch"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_geo_field/domain_selector_geo_field.esm.js:0
|
||||
#, python-format
|
||||
msgid "geo_within"
|
||||
msgstr "geo_within"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/fields.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"geometry_columns table seems to be corrupted. SRID check is not possible"
|
||||
msgstr ""
|
||||
"la tabella geometry_columns sembra corrotta.Il controllo SRID non è possibile"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_vector_layer__begin_color
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_vector_layer__end_color
|
||||
msgid "hex value"
|
||||
msgstr "valore esadecimale"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_number_field/domain_selector_number_field.esm.js:0
|
||||
#, python-format
|
||||
msgid "in active_ids"
|
||||
msgstr "in active_ids"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_number_field/domain_selector_number_field.esm.js:0
|
||||
#, python-format
|
||||
msgid "not in active_ids"
|
||||
msgstr "not in active_ids"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_model_fields__srid
|
||||
msgid "srid"
|
||||
msgstr "srid"
|
||||
|
|
@ -0,0 +1,994 @@
|
|||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * base_geoengine
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 16.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: 2024-06-19 12:51+0000\n"
|
||||
"Last-Translator: jakobkrabbe <jakob@syscare.se>\n"
|
||||
"Language-Team: none\n"
|
||||
"Language: sv\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 4.17\n"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/models/base.py:0
|
||||
#, python-format
|
||||
msgid "%s column does not exists or is not a geo field"
|
||||
msgstr "%s kolumnen finns inte eller är inte ett geofält"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__active_on_startup
|
||||
msgid "Active On Startup"
|
||||
msgstr "Aktiv vid uppstart"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__attribute_field_id
|
||||
msgid "Attribute field"
|
||||
msgstr "Attributfält"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model,name:base_geoengine.model_base
|
||||
msgid "Base"
|
||||
msgstr "Bas"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_vector_layer__geo_repr__basic
|
||||
msgid "Basic"
|
||||
msgstr "Grundläggande"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__begin_color
|
||||
msgid "Begin color class"
|
||||
msgstr "Börja färgklass"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_geoengine_view_form
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_view_form
|
||||
msgid "Classification"
|
||||
msgstr "Klassificering"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__classification
|
||||
msgid "Classification mode"
|
||||
msgstr "Klassificeringsläge"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__type
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type__code
|
||||
msgid "Code"
|
||||
msgstr "Kod"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_vector_layer__geo_repr__colored
|
||||
msgid "Colored range/Chroma.js"
|
||||
msgstr "Färgat område/Chroma.js"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_geoengine_view_form
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_view_form
|
||||
msgid "Colors"
|
||||
msgstr "Färger"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.ui.menu,name:base_geoengine.geoengine_base_view_menu
|
||||
msgid "Configuration"
|
||||
msgstr "Konfiguration"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_model_fields__gist_index
|
||||
msgid "Create gist index"
|
||||
msgstr "Skapa huvudindex"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__create_uid
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type__create_uid
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__create_uid
|
||||
msgid "Created by"
|
||||
msgstr "Skapad av"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__create_date
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type__create_date
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__create_date
|
||||
msgid "Created on"
|
||||
msgstr "Skapad på"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_vector_layer__classification__custom
|
||||
msgid "Custom"
|
||||
msgstr "Anpassad"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_ui_view__default_extent
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_website_page__default_extent
|
||||
msgid "Default map extent"
|
||||
msgstr "Standard kartomfattning"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_ui_view__default_zoom
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_website_page__default_zoom
|
||||
msgid "Default map zoom"
|
||||
msgstr "Standard kartzoom"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_raster_layer__params
|
||||
msgid "Dictiorary of values for dimensions as JSON"
|
||||
msgstr "Ordbok med värden för dimensioner som JSON"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__dimensions
|
||||
msgid "Dimensions"
|
||||
msgstr "Dimensioner"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/geoengine_controller/geoengine_controller.xml:0
|
||||
#, python-format
|
||||
msgid "Discard"
|
||||
msgstr "Kassera"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__display_polygon_labels
|
||||
msgid "Display Labels on Polygon"
|
||||
msgstr "Visa etiketter på polygon"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__display_name
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type__display_name
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__display_name
|
||||
msgid "Display Name"
|
||||
msgstr "Visningsnamn"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_raster_layer__raster_type__d_wms
|
||||
msgid "Distant WMS"
|
||||
msgstr "Avlägsen WMS"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/layers_panel/layers_panel.esm.js:0
|
||||
#, python-format
|
||||
msgid "Domain editing"
|
||||
msgstr "Domänredigering"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/layers_panel/layers_panel.esm.js:0
|
||||
#, python-format
|
||||
msgid "Editing vector layer"
|
||||
msgstr "Redigera vektorlager"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__end_color
|
||||
msgid "End color class"
|
||||
msgstr "Avsluta färgklass"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/geo_db.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Error, can not automatically initialize spatial postgis support. Database "
|
||||
"user may have to be superuser and postgres/postgis extensions with their "
|
||||
"devel header have to be installed. If you do not want Odoo to connect with a "
|
||||
"super user you can manually prepare your database. To do this, open a client "
|
||||
"to your database using a super user and run:\n"
|
||||
"CREATE EXTENSION postgis;\n"
|
||||
"CREATE EXTENSION postgis_topology;\n"
|
||||
msgstr ""
|
||||
"Fel, kan inte automatiskt initiera spatial postgis-stöd. Databasanvändare "
|
||||
"kan behöva vara superanvändare och postgres/postgis-tillägg med deras "
|
||||
"utvecklingshuvud måste installeras. Om du inte vill att Odoo ska ansluta "
|
||||
"till en superanvändare kan du manuellt förbereda din databas. För att göra "
|
||||
"detta, öppna en klient till din databas med en superanvändare och kör:\n"
|
||||
"CREATE EXTENSION postgis;\n"
|
||||
"CREATE EXTENSION postgis_topology;\n"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_model_fields__ttype
|
||||
msgid "Field Type"
|
||||
msgstr "Fälttyp"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model,name:base_geoengine.model_ir_model_fields
|
||||
msgid "Fields"
|
||||
msgstr "Fält"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__format_suffix
|
||||
msgid "Format"
|
||||
msgstr "Format"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_raster_view_form
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_geoengine_view_form
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_view_form
|
||||
msgid "General"
|
||||
msgstr "Generell"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/fields.py:0
|
||||
#, python-format
|
||||
msgid "Geo Value %(geom_type)s must be of the same type %(geo_type)s as fields"
|
||||
msgstr "Geovärde %(geom_type)s måste vara av samma typ %(geo_type)s som fält"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/fields.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Geo dimention modification is not implemented. We can not change dimention "
|
||||
"%(data)s to %(dim)s"
|
||||
msgstr ""
|
||||
"Modifiering av geografisk dimension är inte implementerad. Vi kan inte ändra "
|
||||
"dimension %(data)s till %(dim)s"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__geo_field_id
|
||||
msgid "Geo field"
|
||||
msgstr "Geofält"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/fields.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Geo type modification is not implemented. We can not change type %(data)s to "
|
||||
"%(geo_type)s"
|
||||
msgstr ""
|
||||
"Ändring av geotyp är inte implementerad. Vi kan inte ändra typ %(data)s till "
|
||||
"%(geo_type)s"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_ui_view__type__geoengine
|
||||
msgid "GeoEngine"
|
||||
msgstr "GeoMotor"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.ui.menu,name:base_geoengine.geoengine_base_menu
|
||||
msgid "GeoEngine Backend"
|
||||
msgstr "GeoMotor Backend"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geoengine_view_form
|
||||
msgid "GeoEngine Data"
|
||||
msgstr "GeoMotor data"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/geoengine_view.esm.js:0
|
||||
#, python-format
|
||||
msgid "Geoengine"
|
||||
msgstr "Geomotor"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:res.groups,name:base_geoengine.group_geoengine_admin
|
||||
msgid "Geoengine Admin"
|
||||
msgstr "Geomotor Admin"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:res.groups,name:base_geoengine.group_geoengine_user
|
||||
msgid "Geoengine User"
|
||||
msgstr "Geomotor användare"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__has_type
|
||||
msgid "Has Type"
|
||||
msgstr "Har typ"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__id
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type__id
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__id
|
||||
msgid "ID"
|
||||
msgstr "ID"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_vector_layer__classification__interval
|
||||
msgid "Interval"
|
||||
msgstr "Intervall"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__is_wms
|
||||
msgid "Is Wms"
|
||||
msgstr "Är Wms"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__is_wmts
|
||||
msgid "Is Wmts"
|
||||
msgstr "Är Wmts"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__overlay
|
||||
msgid "Is overlay layer?"
|
||||
msgstr "Är överläggslager?"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__geo_type__linestring
|
||||
msgid "LINESTRING"
|
||||
msgstr "LINESTRING"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer____last_update
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type____last_update
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer____last_update
|
||||
msgid "Last Modified on"
|
||||
msgstr "Senast modifierad på"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__write_uid
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type__write_uid
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__write_uid
|
||||
msgid "Last Updated by"
|
||||
msgstr "Senast uppdaterad av"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__write_date
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type__write_date
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__write_date
|
||||
msgid "Last Updated on"
|
||||
msgstr "Senast uppdaterad på"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__type_id
|
||||
msgid "Layer"
|
||||
msgstr "Lager"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__name
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__name
|
||||
msgid "Layer Name"
|
||||
msgstr "Lagernamn"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__layer_opacity
|
||||
msgid "Layer Opacity"
|
||||
msgstr "Lageropacitet"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__sequence
|
||||
msgid "Layer Priority"
|
||||
msgstr "Lagerprioritet"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_raster_view_form
|
||||
msgid "Layer data"
|
||||
msgstr "Lagerdata"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__readonly
|
||||
msgid "Layer is read only"
|
||||
msgstr "Layer är skrivskyddad"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__sequence
|
||||
msgid "Layer priority"
|
||||
msgstr "Lagerprioritet"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_vector_layer__active_on_startup
|
||||
msgid "Layer will be shown on startup if checked."
|
||||
msgstr "Lager kommer att visas vid start om det är markerat."
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/layers_panel/layers_panel.xml:0
|
||||
#, python-format
|
||||
msgid "Layers ("
|
||||
msgstr "Lager ("
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_raster_layer__dimensions
|
||||
msgid "List of dimensions separated by ','"
|
||||
msgstr "Lista över dimensioner avgränsade med ','"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__geo_type__multilinestring
|
||||
msgid "MULTILINESTRING"
|
||||
msgstr "MULTILINJESTRING"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__geo_type__multipoint
|
||||
msgid "MULTIPOINT"
|
||||
msgstr "MULTIPOINT"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__geo_type__multipolygon
|
||||
msgid "MULTIPOLYGON"
|
||||
msgstr "MULTIPOLYGON"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__matrix_set
|
||||
msgid "Matrix set"
|
||||
msgstr "Matris set"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__max_extent
|
||||
msgid "Max extent"
|
||||
msgstr "Max omfattning"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/geoengine_arch_parser.esm.js:0
|
||||
#, python-format
|
||||
msgid "Missing ${INFO_BOX_ATTRIBUTE} template."
|
||||
msgstr "${INFO_BOX_ATTRIBUTE} mall saknas."
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__model_name
|
||||
msgid "Model"
|
||||
msgstr "Modell"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__model_domain
|
||||
msgid "Model Domain"
|
||||
msgstr "Modelldomän"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__model_id
|
||||
msgid "Model to use"
|
||||
msgstr "Modell att använda"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__model_view_id
|
||||
msgid "Model view"
|
||||
msgstr "Modellvy"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type__name
|
||||
msgid "Name"
|
||||
msgstr "Namn"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_raster_layer__params_wms
|
||||
msgid "Need to provide at least a LAYERS param"
|
||||
msgstr "Behöver tillhandahålla minst en LAGER parameter"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/geoengine_controller/geoengine_controller.esm.js:0
|
||||
#, python-format
|
||||
msgid "New record"
|
||||
msgstr "Ny post"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/models/base.py:0
|
||||
#, python-format
|
||||
msgid "No GeoEngine view defined for the model %s"
|
||||
msgstr "Ingen GeoMotor-vy definierad för modellen %s"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/models/base.py:0
|
||||
#, python-format
|
||||
msgid "No raster layer for view %s"
|
||||
msgstr "Inget rasterlager för vyn %s"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__nb_class
|
||||
msgid "Number of class"
|
||||
msgstr "Nummer av klass"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/geoengine_renderer/geoengine_renderer.xml:0
|
||||
#, python-format
|
||||
msgid "OPEN"
|
||||
msgstr "ÖPPNA"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_raster_layer__raster_type__odoo
|
||||
msgid "Odoo field"
|
||||
msgstr "Odoofält"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_raster_view_form
|
||||
msgid "Odoo layer data (Not implemented)"
|
||||
msgstr "Odoo lagerdata (inte implementerad)"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__field_id
|
||||
msgid "Odoo layer field to use"
|
||||
msgstr "Odoo lagerfält att använda"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_raster_layer__raster_type__osm
|
||||
msgid "OpenStreetMap"
|
||||
msgstr "OpenStreetMap"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__geo_type__point
|
||||
msgid "POINT"
|
||||
msgstr "PEKA"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__geo_type__polygon
|
||||
msgid "POLYGON"
|
||||
msgstr "POLYGON"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__params
|
||||
msgid "Params"
|
||||
msgstr "Parametrar"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__params_wms
|
||||
msgid "Params WMS"
|
||||
msgstr ""
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/models/base.py:0
|
||||
#, python-format
|
||||
msgid "Please create a view or modify view mode"
|
||||
msgstr "Vänligen skapa en vy eller ändra visningsläge"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_model_fields__dim
|
||||
msgid "PostGIs Dimension"
|
||||
msgstr "PostGIs dimension"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_model_fields__geo_type
|
||||
msgid "PostGIs type"
|
||||
msgstr "PostGIs typ"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__projection
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_ui_view__projection
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_website_page__projection
|
||||
msgid "Projection"
|
||||
msgstr "Projektion"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_vector_layer__geo_repr__proportion
|
||||
msgid "Proportional Symbol"
|
||||
msgstr "Proportionell symbol"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_vector_layer__classification__quantile
|
||||
msgid "Quantile"
|
||||
msgstr "Kvantil"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geoengine_view_form
|
||||
msgid "Raster (Background layers)"
|
||||
msgstr "Raster (bakgrundslager)"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.actions.act_window,name:base_geoengine.geo_engine_view_rater_action
|
||||
#: model:ir.model,name:base_geoengine.model_geoengine_raster_layer
|
||||
msgid "Raster Layer"
|
||||
msgstr "Raster lager"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.ui.menu,name:base_geoengine.geoengine_raster_layer_menu
|
||||
msgid "Raster Layer Management"
|
||||
msgstr "Rasterlagerhantering"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model,name:base_geoengine.model_geoengine_raster_layer_type
|
||||
msgid "Raster Layer Type"
|
||||
msgstr "Rasterlagertyp"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_raster_view_form
|
||||
msgid "Raster Layer View"
|
||||
msgstr "Rasterlagervy"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__raster_type
|
||||
msgid "Raster layer type"
|
||||
msgstr "Rasterlagertyp"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_ui_view__raster_layer_ids
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_website_page__raster_layer_ids
|
||||
msgid "Raster layers"
|
||||
msgstr "Rasterlager"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/layers_panel/layers_panel.xml:0
|
||||
#, python-format
|
||||
msgid "Rasters"
|
||||
msgstr "Raster"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/records_panel/records_panel.xml:0
|
||||
#, python-format
|
||||
msgid "Records ("
|
||||
msgstr "Poster ("
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_view_form
|
||||
msgid "Related Model"
|
||||
msgstr "Relaterad modell"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__view_id
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__view_id
|
||||
msgid "Related View"
|
||||
msgstr "Relaterad vy"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_geoengine_view_form
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_view_form
|
||||
msgid "Representation"
|
||||
msgstr "Representation"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_vector_layer__geo_repr
|
||||
msgid "Representation mode"
|
||||
msgstr "Representationsläge"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/fields.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Reprojection of column is not implemented. We can not change srid %(srid)s "
|
||||
"to %(data)s"
|
||||
msgstr ""
|
||||
"Omprojektering av kolumn är inte implementerad. Vi kan inte ändra srid "
|
||||
"%(srid)s till %(data)s"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__request_encoding
|
||||
msgid "Request encoding"
|
||||
msgstr "Begär kodning"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__resolutions
|
||||
msgid "Resolutions"
|
||||
msgstr "Upplösningar"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_ui_view__restricted_extent
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_website_page__restricted_extent
|
||||
msgid "Restricted map extent"
|
||||
msgstr "Begränsad kartutsträckning"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/geoengine_controller/geoengine_controller.xml:0
|
||||
#, python-format
|
||||
msgid "Save"
|
||||
msgstr "Spara"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/records_panel/search_bar_records/search_bar_records.xml:0
|
||||
#, python-format
|
||||
msgid "Search..."
|
||||
msgstr "Sök..."
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__server_type
|
||||
msgid "Server Type"
|
||||
msgstr "Servertyp"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer_type__service
|
||||
msgid "Service"
|
||||
msgstr "Service"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__url
|
||||
msgid "Service URL"
|
||||
msgstr "URL för tjänsten"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/geo_convertion_helper.py:0
|
||||
#, python-format
|
||||
msgid "Shapely or geojson are not available in the sys path"
|
||||
msgstr "Shapely eller geojson är inte tillgängliga i sys-sökvägen"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_geo_field_input/domain_selector_geo_field_input.esm.js:0
|
||||
#, python-format
|
||||
msgid "Subdomain"
|
||||
msgstr "Subdomän"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/models/geo_vector_layer.py:0
|
||||
#, python-format
|
||||
msgid "The geo_field_id must be a field in %s model"
|
||||
msgstr "Värdet i geo_field_id fältet måste vara i %s modellen"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_raster_layer__server_type
|
||||
msgid ""
|
||||
"The type of the remote WMS server: mapserver, geoserver, carmentaserver, or "
|
||||
"qgis"
|
||||
msgstr ""
|
||||
"Typen av fjärr-WMS-servern: mapserver, geoserver, carmentaserver eller qgis"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_vector_layer__classification__unique
|
||||
msgid "Unique value"
|
||||
msgstr "Unikt värde"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__units
|
||||
msgid "Units"
|
||||
msgstr "Enheter"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_geoengine_raster_layer__use_to_edit
|
||||
msgid "Use to edit"
|
||||
msgstr "Använd för att redigera"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_vector_view_form
|
||||
msgid "Vector"
|
||||
msgstr "Vektor"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geoengine_view_form
|
||||
msgid "Vector (Active layers)"
|
||||
msgstr "Vektor (aktivt lager)"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.actions.act_window,name:base_geoengine.geo_engine_view_raster_action
|
||||
#: model:ir.actions.act_window,name:base_geoengine.geo_vector_geoengine_view_action
|
||||
#: model:ir.model,name:base_geoengine.model_geoengine_vector_layer
|
||||
msgid "Vector Layer"
|
||||
msgstr "Vektor lager"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.ui.menu,name:base_geoengine.geoengine_vector_layer_menu
|
||||
msgid "Vector Layer Management"
|
||||
msgstr "Vektor lagerhantering"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_ui_view__vector_layer_ids
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_website_page__vector_layer_ids
|
||||
msgid "Vector layers"
|
||||
msgstr "Vektor lager"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/layers_panel/layers_panel.xml:0
|
||||
#, python-format
|
||||
msgid "Vectors"
|
||||
msgstr "Vektorer"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model,name:base_geoengine.model_ir_ui_view
|
||||
msgid "View"
|
||||
msgstr "Vy"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.ui.menu,name:base_geoengine.geoengine_view_menu
|
||||
msgid "View Management"
|
||||
msgstr "Visningshanterare"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_ui_view__type
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_website_page__type
|
||||
msgid "View Type"
|
||||
msgstr "Vytyp"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.actions.act_window,name:base_geoengine.geo_engine_view_action
|
||||
msgid "Views"
|
||||
msgstr "Vyer"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_raster_view_form
|
||||
msgid "WMS options"
|
||||
msgstr "WMS alternativ"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__geoengine_raster_layer__raster_type__wmts
|
||||
msgid "WMTS"
|
||||
msgstr "WMTS"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model_terms:ir.ui.view,arch_db:base_geoengine.geo_raster_view_form
|
||||
msgid "WMTS options"
|
||||
msgstr "WMTS alternativ"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/geoengine_controller/geoengine_controller.esm.js:0
|
||||
#, python-format
|
||||
msgid "Warning"
|
||||
msgstr "Varning"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/geo_convertion_helper.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Write/create/search geo type must be wkt/geojson string or must respond to "
|
||||
"wkt"
|
||||
msgstr ""
|
||||
"Skriv/skapa/sök geotyp måste vara wkt/geojson-sträng eller måste svara på wkt"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/views/geoengine/geoengine_controller/geoengine_controller.esm.js:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"You are about to create a new record without having displayed all the "
|
||||
"others. A risk of overlap could occur. Would you like to continue ?"
|
||||
msgstr ""
|
||||
"Du är på väg att skapa en ny post utan att ha visat alla de andra. Det kan "
|
||||
"uppstå risk för överlappning. Vill du fortsätta?"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/models/base.py:0
|
||||
#, python-format
|
||||
msgid "You must at least provide one of domain or geo_domain"
|
||||
msgstr "Du måste åtminstone tillhandahålla en av domän eller geo_domän"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/models/geo_vector_layer.py:0
|
||||
#, python-format
|
||||
msgid "You need to provide an attribute that exists in %s model"
|
||||
msgstr "Du behöver ange ett attribut som finns i %s model"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/models/geo_vector_layer.py:0
|
||||
#, python-format
|
||||
msgid "You need to select a numeric field"
|
||||
msgstr "Du måste välja ett numeriskt fält"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_raster_layer__projection
|
||||
msgid "eg. EPSG:21781"
|
||||
msgstr "t.ex. EPSG:21781"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_raster_layer__request_encoding
|
||||
msgid "eg. REST"
|
||||
msgstr "t.ex. REST"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_raster_layer__units
|
||||
msgid "eg. m"
|
||||
msgstr "t.ex. m"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_raster_layer__format_suffix
|
||||
msgid "eg. png"
|
||||
msgstr "t.ex. png"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_geo_field/domain_selector_geo_field.esm.js:0
|
||||
#, python-format
|
||||
msgid "geo_contains"
|
||||
msgstr "geo_innehåller"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_geo_field/domain_selector_geo_field.esm.js:0
|
||||
#, python-format
|
||||
msgid "geo_equal"
|
||||
msgstr "geo_jämlik"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_geo_field/domain_selector_geo_field.esm.js:0
|
||||
#, python-format
|
||||
msgid "geo_greater"
|
||||
msgstr "geo_större"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_geo_field/domain_selector_geo_field.esm.js:0
|
||||
#, python-format
|
||||
msgid "geo_intersect"
|
||||
msgstr "geo_intersect"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_geo_field/domain_selector_geo_field.esm.js:0
|
||||
#, python-format
|
||||
msgid "geo_lesser"
|
||||
msgstr "geo_lesser"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__ttype__geo_line
|
||||
msgid "geo_line"
|
||||
msgstr "geo_linje"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__ttype__geo_multi_line
|
||||
msgid "geo_multi_line"
|
||||
msgstr "geo_multi_line"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__ttype__geo_multi_point
|
||||
msgid "geo_multi_point"
|
||||
msgstr "geo_multi_punkt"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__ttype__geo_multi_polygon
|
||||
msgid "geo_multi_polygon"
|
||||
msgstr "geo_multi_polygon"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__ttype__geo_point
|
||||
msgid "geo_point"
|
||||
msgstr "geo_punkt"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields.selection,name:base_geoengine.selection__ir_model_fields__ttype__geo_polygon
|
||||
msgid "geo_polygon"
|
||||
msgstr "geo_polygon"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/models/base.py:0
|
||||
#, python-format
|
||||
msgid "geo_search is deprecated: uses search method defined on base model"
|
||||
msgstr ""
|
||||
"geo_search är föråldrad: använder sökmetod som definieras i basmodellen"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_geo_field/domain_selector_geo_field.esm.js:0
|
||||
#, python-format
|
||||
msgid "geo_touch"
|
||||
msgstr "geo_touch"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_geo_field/domain_selector_geo_field.esm.js:0
|
||||
#, python-format
|
||||
msgid "geo_within"
|
||||
msgstr "geo_inom"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-python
|
||||
#: code:addons/base_geoengine/fields.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"geometry_columns table seems to be corrupted. SRID check is not possible"
|
||||
msgstr ""
|
||||
"geometry_columns-tabellen verkar vara skadad. SRID-kontroll är inte möjlig"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_vector_layer__begin_color
|
||||
#: model:ir.model.fields,help:base_geoengine.field_geoengine_vector_layer__end_color
|
||||
msgid "hex value"
|
||||
msgstr "hex-värde"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_number_field/domain_selector_number_field.esm.js:0
|
||||
#, python-format
|
||||
msgid "in active_ids"
|
||||
msgstr "i aktiva_id"
|
||||
|
||||
#. module: base_geoengine
|
||||
#. odoo-javascript
|
||||
#: code:addons/base_geoengine/static/src/js/widgets/domain_selector_geo_field/domain_selector_number_field/domain_selector_number_field.esm.js:0
|
||||
#, python-format
|
||||
msgid "not in active_ids"
|
||||
msgstr "inte i active_ids"
|
||||
|
||||
#. module: base_geoengine
|
||||
#: model:ir.model.fields,field_description:base_geoengine.field_ir_model_fields__srid
|
||||
msgid "srid"
|
||||
msgstr "srid"
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 111 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 70 KiB |
|
|
@ -0,0 +1,25 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Author: Nicolas Bessi
|
||||
# Copyright 2011-2012 Camptocamp SA
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
"""Module that manages map view and vector/raster layer"""
|
||||
from . import base
|
||||
from . import geo_raster_layer
|
||||
from . import geo_vector_layer
|
||||
from . import ir_view
|
||||
from . import ir_model
|
||||
|
|
@ -0,0 +1,172 @@
|
|||
# Copyright 2011-2012 Nicolas Bessi (Camptocamp SA)
|
||||
# Copyright 2016 Yannick Payot (Camptocamp SA)
|
||||
# Copyright 2023 ACSONE SA/NV
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
import logging
|
||||
|
||||
from odoo import _, api, models
|
||||
from odoo.exceptions import MissingError, UserError
|
||||
from odoo.osv.expression import AND
|
||||
|
||||
from .. import fields as geo_fields
|
||||
|
||||
DEFAULT_EXTENT = (
|
||||
"-123164.85222423, 5574694.9538936, " "1578017.6490538, 6186191.1800898"
|
||||
)
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Base(models.AbstractModel):
|
||||
"""Extend Base class for to allow definition of geo fields."""
|
||||
|
||||
_inherit = "base"
|
||||
|
||||
# Array of ash that define layer and data to use
|
||||
_georepr = []
|
||||
|
||||
@api.model
|
||||
def fields_get(self, allfields=None, attributes=None):
|
||||
"""Add geo_type definition for geo fields"""
|
||||
res = super().fields_get(allfields=allfields, attributes=attributes)
|
||||
for f_name in res:
|
||||
field = self._fields.get(f_name)
|
||||
if field and field.type.startswith("geo_"):
|
||||
geo_type = {
|
||||
"type": field.type,
|
||||
"dim": int(field.dim),
|
||||
"srid": field.srid,
|
||||
"geo_type": field.geo_type,
|
||||
}
|
||||
# TODO
|
||||
if field.compute or field.related:
|
||||
if not field.dim:
|
||||
geo_type["dim"] = 2
|
||||
if not field.srid:
|
||||
geo_type["srid"] = 3857
|
||||
res[f_name]["geo_type"] = geo_type
|
||||
return res
|
||||
|
||||
@api.model
|
||||
def _get_geo_view(self):
|
||||
IrView = self.env["ir.ui.view"]
|
||||
geo_view = IrView.sudo().search(
|
||||
[("model", "=", self._name), ("type", "=", "geoengine")],
|
||||
limit=1,
|
||||
)
|
||||
if not geo_view:
|
||||
raise UserError(
|
||||
_("No GeoEngine view defined for the model %s") % self._name,
|
||||
_("Please create a view or modify view mode"),
|
||||
)
|
||||
return geo_view
|
||||
|
||||
@api.model
|
||||
def set_field_real_name(self, in_tuple):
|
||||
field_obj = self.env["ir.model.fields"]
|
||||
if not in_tuple:
|
||||
return in_tuple
|
||||
name = field_obj.browse(in_tuple[0]).name
|
||||
out = (in_tuple[0], name, in_tuple[1])
|
||||
return out
|
||||
|
||||
@api.model
|
||||
def get_geoengine_layers(self, view_id=None, view_type="geoengine", **options):
|
||||
view_obj = self.env["ir.ui.view"]
|
||||
|
||||
if not view_id:
|
||||
view = self._get_geo_view()
|
||||
else:
|
||||
view = view_obj.browse(view_id)
|
||||
geoengine_layers = {
|
||||
"backgrounds": [],
|
||||
"actives": [],
|
||||
"projection": view.projection,
|
||||
"restricted_extent": view.restricted_extent,
|
||||
"default_extent": view.default_extent or DEFAULT_EXTENT,
|
||||
"default_zoom": view.default_zoom,
|
||||
}
|
||||
|
||||
for layer in view.raster_layer_ids:
|
||||
layer_dict = layer.read()[0]
|
||||
geoengine_layers["backgrounds"].append(layer_dict)
|
||||
for layer in view.vector_layer_ids:
|
||||
layer_dict = layer.read()[0]
|
||||
layer_dict["attribute_field_id"] = self.set_field_real_name(
|
||||
layer_dict.get("attribute_field_id", False)
|
||||
)
|
||||
layer_dict["geo_field_id"] = self.set_field_real_name(
|
||||
layer_dict.get("geo_field_id", False)
|
||||
)
|
||||
layer_dict["resModel"] = layer._name
|
||||
layer_dict["model"] = layer.model_id.model
|
||||
layer_dict["model_domain"] = layer.model_domain
|
||||
geoengine_layers["actives"].append(layer_dict)
|
||||
return geoengine_layers
|
||||
|
||||
@api.model
|
||||
def get_edit_info_for_geo_column(self, column):
|
||||
raster_obj = self.env["geoengine.raster.layer"]
|
||||
|
||||
field = self._fields.get(column)
|
||||
if not field or not isinstance(field, geo_fields.GeoField):
|
||||
raise ValueError(
|
||||
_("%s column does not exists or is not a geo field") % column
|
||||
)
|
||||
view = self._get_geo_view()
|
||||
raster = raster_obj.search(
|
||||
[("view_id", "=", view.id), ("use_to_edit", "=", True)], limit=1
|
||||
)
|
||||
if not raster:
|
||||
raster = raster_obj.search([("view_id", "=", view.id)], limit=1)
|
||||
if not raster:
|
||||
raise MissingError(_("No raster layer for view %s") % (view.name,))
|
||||
return {
|
||||
"edit_raster": raster.read()[0],
|
||||
"srid": field.srid,
|
||||
"projection": view.projection,
|
||||
"restricted_extent": view.restricted_extent,
|
||||
"default_extent": view.default_extent or DEFAULT_EXTENT,
|
||||
"default_zoom": view.default_zoom,
|
||||
}
|
||||
|
||||
@api.model
|
||||
def geo_search(
|
||||
self, domain=None, geo_domain=None, offset=0, limit=None, order=None
|
||||
):
|
||||
"""Perform a geo search it allows direct domain:
|
||||
geo_search(
|
||||
domain=[('name', 'ilike', 'toto']),
|
||||
geo_domain=[('the_point', 'geo_intersect',
|
||||
myshaply_obj or mywkt or mygeojson)])
|
||||
|
||||
We can also support indirect geo_domain (
|
||||
‘geom’, ‘geo_operator’, {‘res.zip.poly’: [‘id’, ‘in’, [1,2,3]] })
|
||||
|
||||
The supported operators are :
|
||||
* geo_greater
|
||||
* geo_lesser
|
||||
* geo_equal
|
||||
* geo_touch
|
||||
* geo_within
|
||||
* geo_contains
|
||||
* geo_intersect"""
|
||||
# First we do a standard search in order to apply security rules
|
||||
# and do a search on standard attributes
|
||||
# Limit and offset are managed after, we may loose a lot of performance
|
||||
# here
|
||||
_logger.debug(
|
||||
_("geo_search is deprecated: uses search method defined on base model")
|
||||
)
|
||||
domain = domain or []
|
||||
geo_domain = geo_domain or []
|
||||
search_domain = domain or []
|
||||
if domain and geo_domain:
|
||||
search_domain = AND([domain, geo_domain])
|
||||
elif geo_domain:
|
||||
search_domain = geo_domain
|
||||
|
||||
if not search_domain:
|
||||
raise ValueError(_("You must at least provide one of domain or geo_domain"))
|
||||
|
||||
return self.search(search_domain, limit=limit, offset=offset, order=order)
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
# Copyright 2011-2012 Nicolas Bessi (Camptocamp SA)
|
||||
# Copyright 2016 Yannick Payot (Camptocamp SA)
|
||||
# Copyright 2023 ACSONE SA/NV
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class GeoRasterLayerType(models.Model):
|
||||
_name = "geoengine.raster.layer.type"
|
||||
_description = "Raster Layer Type"
|
||||
|
||||
name = fields.Char(translate=True, required=True)
|
||||
code = fields.Char(required=True)
|
||||
service = fields.Char(required=True)
|
||||
|
||||
|
||||
class GeoRasterLayer(models.Model):
|
||||
_name = "geoengine.raster.layer"
|
||||
_description = "Raster Layer"
|
||||
|
||||
raster_type = fields.Selection(
|
||||
[
|
||||
("osm", "OpenStreetMap"),
|
||||
("wmts", "WMTS"),
|
||||
("d_wms", "Distant WMS"),
|
||||
("odoo", "Odoo field"),
|
||||
],
|
||||
string="Raster layer type",
|
||||
default="osm",
|
||||
required=True,
|
||||
)
|
||||
name = fields.Char("Layer Name", translate=True, required=True)
|
||||
url = fields.Char("Service URL")
|
||||
|
||||
# technical field to display or not wmts options
|
||||
is_wmts = fields.Boolean(compute="_compute_is_wmts")
|
||||
# technical field to display or not wms options
|
||||
is_wms = fields.Boolean(compute="_compute_is_wms")
|
||||
# wmts options
|
||||
matrix_set = fields.Char("Matrix set")
|
||||
format_suffix = fields.Char("Format", help="eg. png")
|
||||
request_encoding = fields.Char("Request encoding", help="eg. REST")
|
||||
projection = fields.Char(help="eg. EPSG:21781")
|
||||
units = fields.Char(help="eg. m") # Not used
|
||||
resolutions = fields.Char()
|
||||
max_extent = fields.Char("Max extent")
|
||||
dimensions = fields.Char(help="List of dimensions separated by ','")
|
||||
params = fields.Char(help="Dictiorary of values for dimensions as JSON")
|
||||
|
||||
# wms options
|
||||
params_wms = fields.Char(
|
||||
"Params WMS", help="Need to provide at least a LAYERS param"
|
||||
)
|
||||
server_type = fields.Char(
|
||||
help="The type of the remote WMS server: mapserver, geoserver, carmentaserver, or qgis",
|
||||
)
|
||||
|
||||
# technical field to display or not layer type -- Not used
|
||||
has_type = fields.Boolean(compute="_compute_has_type")
|
||||
type_id = fields.Many2one(
|
||||
"geoengine.raster.layer.type", "Layer", domain="[('service', '=', raster_type)]"
|
||||
)
|
||||
type = fields.Char(related="type_id.code")
|
||||
sequence = fields.Integer("Layer priority", default=6)
|
||||
overlay = fields.Boolean("Is overlay layer?")
|
||||
field_id = fields.Many2one(
|
||||
"ir.model.fields",
|
||||
"Odoo layer field to use",
|
||||
domain=[("ttype", "ilike", "geo_"), ("model", "=", "view_id.model")],
|
||||
)
|
||||
view_id = fields.Many2one(
|
||||
"ir.ui.view", "Related View", domain=[("type", "=", "geoengine")], required=True
|
||||
)
|
||||
use_to_edit = fields.Boolean("Use to edit")
|
||||
|
||||
@api.depends("raster_type", "is_wmts")
|
||||
def _compute_has_type(self):
|
||||
for rec in self:
|
||||
rec.has_type = rec.raster_type == "is_wmts"
|
||||
|
||||
@api.depends("raster_type")
|
||||
def _compute_is_wmts(self):
|
||||
for rec in self:
|
||||
rec.is_wmts = rec.raster_type == "wmts"
|
||||
|
||||
@api.depends("raster_type")
|
||||
def _compute_is_wms(self):
|
||||
for rec in self:
|
||||
rec.is_wms = rec.raster_type == "d_wms"
|
||||
|
|
@ -0,0 +1,156 @@
|
|||
# Copyright 2011-2012 Nicolas Bessi (Camptocamp SA)
|
||||
# Copyright 2016 Yannick Payot (Camptocamp SA)
|
||||
# Copyright 2023 ACSONE SA/NV
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
SUPPORTED_ATT = [
|
||||
"float",
|
||||
"integer",
|
||||
"integer_big",
|
||||
"related",
|
||||
"function",
|
||||
"date",
|
||||
"datetime",
|
||||
"char",
|
||||
"text",
|
||||
"selection",
|
||||
]
|
||||
|
||||
NUMBER_ATT = ["float", "integer", "integer_big"]
|
||||
|
||||
|
||||
class GeoVectorLayer(models.Model):
|
||||
_name = "geoengine.vector.layer"
|
||||
_description = "Vector Layer"
|
||||
_order = "sequence ASC, name"
|
||||
|
||||
geo_repr = fields.Selection(
|
||||
[
|
||||
("basic", "Basic"),
|
||||
# Actually we have to think if we should separate it for colored
|
||||
("proportion", "Proportional Symbol"),
|
||||
("colored", "Colored range/Chroma.js"),
|
||||
],
|
||||
string="Representation mode",
|
||||
required=True,
|
||||
)
|
||||
|
||||
classification = fields.Selection(
|
||||
[
|
||||
("unique", "Unique value"),
|
||||
("interval", "Interval"),
|
||||
("quantile", "Quantile"),
|
||||
("custom", "Custom"),
|
||||
],
|
||||
string="Classification mode",
|
||||
required=False,
|
||||
)
|
||||
name = fields.Char("Layer Name", translate=True, required=True)
|
||||
begin_color = fields.Char("Begin color class", required=False, help="hex value")
|
||||
end_color = fields.Char(
|
||||
"End color class", required=False, help="hex value", default="#FF680A"
|
||||
)
|
||||
nb_class = fields.Integer("Number of class", default=1)
|
||||
geo_field_id = fields.Many2one(
|
||||
"ir.model.fields",
|
||||
"Geo field",
|
||||
required=True,
|
||||
ondelete="cascade",
|
||||
domain=[("ttype", "ilike", "geo_")],
|
||||
)
|
||||
attribute_field_id = fields.Many2one(
|
||||
"ir.model.fields", "Attribute field", domain=[("ttype", "in", SUPPORTED_ATT)]
|
||||
)
|
||||
model_id = fields.Many2one(
|
||||
"ir.model",
|
||||
"Model to use",
|
||||
store=True,
|
||||
readonly=False,
|
||||
compute="_compute_model_id",
|
||||
)
|
||||
model_name = fields.Char(related="model_id.model", readonly=True)
|
||||
|
||||
view_id = fields.Many2one(
|
||||
"ir.ui.view", "Related View", domain=[("type", "=", "geoengine")], required=True
|
||||
)
|
||||
sequence = fields.Integer("Layer Priority", default=6)
|
||||
readonly = fields.Boolean("Layer is read only")
|
||||
display_polygon_labels = fields.Boolean("Display Labels on Polygon")
|
||||
active_on_startup = fields.Boolean(
|
||||
help="Layer will be shown on startup if checked."
|
||||
)
|
||||
layer_opacity = fields.Float(default=1.0)
|
||||
model_domain = fields.Char(default="[]")
|
||||
model_view_id = fields.Many2one(
|
||||
"ir.ui.view",
|
||||
"Model view",
|
||||
domain=[("type", "=", "geoengine")],
|
||||
compute="_compute_model_view_id",
|
||||
readonly=False,
|
||||
)
|
||||
|
||||
@api.constrains("geo_field_id", "model_id")
|
||||
def _check_geo_field_id(self):
|
||||
for rec in self:
|
||||
if rec.model_id:
|
||||
if not rec.geo_field_id.model_id == rec.model_id:
|
||||
raise ValidationError(
|
||||
_(
|
||||
"The geo_field_id must be a field in %s model",
|
||||
rec.model_id.display_name,
|
||||
)
|
||||
)
|
||||
|
||||
@api.constrains("geo_repr", "attribute_field_id")
|
||||
def _check_geo_repr(self):
|
||||
for rec in self:
|
||||
if (
|
||||
rec.attribute_field_id
|
||||
and rec.attribute_field_id.ttype not in NUMBER_ATT
|
||||
):
|
||||
if (
|
||||
rec.geo_repr == "colored"
|
||||
and rec.classification != "unique"
|
||||
or rec.geo_repr == "proportion"
|
||||
):
|
||||
raise ValidationError(
|
||||
_(
|
||||
"You need to select a numeric field",
|
||||
)
|
||||
)
|
||||
|
||||
@api.constrains("attribute_field_id", "geo_field_id")
|
||||
def _check_if_attribute_in_geo_field(self):
|
||||
for rec in self:
|
||||
if rec.attribute_field_id and rec.geo_field_id:
|
||||
if rec.attribute_field_id.model != rec.geo_field_id.model:
|
||||
raise ValidationError(
|
||||
_(
|
||||
"You need to provide an attribute that exists in %s model",
|
||||
rec.geo_field_id.model_id.display_name,
|
||||
)
|
||||
)
|
||||
|
||||
@api.depends("model_id")
|
||||
def _compute_model_view_id(self):
|
||||
for rec in self:
|
||||
if rec.model_id:
|
||||
for view in rec.model_id.view_ids:
|
||||
if view.type == "geoengine":
|
||||
rec.model_view_id = view
|
||||
else:
|
||||
rec.model_view_id = ""
|
||||
|
||||
@api.depends("geo_field_id", "view_id")
|
||||
def _compute_model_id(self):
|
||||
for rec in self:
|
||||
if rec.view_id and rec.geo_field_id:
|
||||
if rec.view_id.model != rec.geo_field_id.model:
|
||||
rec.model_id = rec.geo_field_id.model_id
|
||||
else:
|
||||
rec.model_id = ""
|
||||
else:
|
||||
rec.model_id = ""
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
# Copyright 2011-2012 Nicolas Bessi (Camptocamp SA)
|
||||
# Copyright 2023 Yannick Payot (Camptocamp SA)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from odoo import fields, models
|
||||
|
||||
from odoo.addons import base
|
||||
|
||||
if "geoengine" not in base.models.ir_actions.VIEW_TYPES:
|
||||
base.models.ir_actions.VIEW_TYPES.append(("geoengine", "Geoengine"))
|
||||
|
||||
GEO_TYPES = [
|
||||
("geo_polygon", "geo_polygon"),
|
||||
("geo_multi_polygon", "geo_multi_polygon"),
|
||||
("geo_point", "geo_point"),
|
||||
("geo_multi_point", "geo_multi_point"),
|
||||
("geo_line", "geo_line"),
|
||||
("geo_multi_line", "geo_multi_line"),
|
||||
]
|
||||
|
||||
GEO_TYPES_ONDELETE = {
|
||||
"geo_polygon": "cascade",
|
||||
"geo_multi_polygon": "cascade",
|
||||
"geo_point": "cascade",
|
||||
"geo_multi_point": "cascade",
|
||||
"geo_line": "cascade",
|
||||
"geo_multi_line": "cascade",
|
||||
}
|
||||
|
||||
POSTGIS_GEO_TYPES = [
|
||||
("POINT", "POINT"),
|
||||
("MULTIPOINT", "MULTIPOINT"),
|
||||
("LINESTRING", "LINESTRING"),
|
||||
("MULTILINESTRING", "MULTILINESTRING"),
|
||||
("POLYGON", "POLYGON"),
|
||||
("MULTIPOLYGON", "MULTIPOLYGON"),
|
||||
]
|
||||
|
||||
|
||||
class IrModelField(models.Model):
|
||||
_inherit = "ir.model.fields"
|
||||
|
||||
srid = fields.Integer("srid", required=False)
|
||||
geo_type = fields.Selection(POSTGIS_GEO_TYPES, string="PostGIs type")
|
||||
dim = fields.Selection(
|
||||
[("2", "2"), ("3", "3"), ("4", "4")], string="PostGIs Dimension", default="2"
|
||||
)
|
||||
gist_index = fields.Boolean("Create gist index")
|
||||
ttype = fields.Selection(
|
||||
selection_add=GEO_TYPES,
|
||||
ondelete=GEO_TYPES_ONDELETE,
|
||||
)
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
# Copyright 2011-2012 Nicolas Bessi (Camptocamp SA)
|
||||
# Copyright 2016-2023 Yannick Payot (Camptocamp SA)
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class IrUIView(models.Model):
|
||||
_inherit = "ir.ui.view"
|
||||
|
||||
type = fields.Selection(
|
||||
selection_add=[("geoengine", "GeoEngine")],
|
||||
ondelete={"geoengine": "cascade"},
|
||||
)
|
||||
|
||||
raster_layer_ids = fields.One2many(
|
||||
"geoengine.raster.layer", "view_id", "Raster layers", required=False
|
||||
)
|
||||
|
||||
vector_layer_ids = fields.One2many(
|
||||
"geoengine.vector.layer", "view_id", "Vector layers", required=True
|
||||
)
|
||||
|
||||
projection = fields.Char(default="EPSG:3857", required=True)
|
||||
default_extent = fields.Char(
|
||||
"Default map extent",
|
||||
default="-123164.85222423, 5574694.9538936, 1578017.6490538,"
|
||||
" 6186191.1800898",
|
||||
)
|
||||
default_zoom = fields.Integer("Default map zoom")
|
||||
restricted_extent = fields.Char("Restricted map extent")
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
* Nicolas Bessi <nicolas.bessi@camptocamp.com>
|
||||
* Frederic Junod <frederic.junod@camptocamp.com>
|
||||
* Yannick Payot <yannick.payot@camptocamp.com>
|
||||
* Sandy Carter <sandy.carter@savoirfairelinux.com>
|
||||
* Laurent Mignon <laurent.mignon@acsone.eu>
|
||||
* Jonathan Nemry <jonathan.nemry@acsone.eu>
|
||||
* David Lasley <dave@dlasley.net>
|
||||
* Daniel Reis <dgreis@sapo.pt>
|
||||
* Matthieu Dietrich <matthieu.dietrich@camptocamp.com>
|
||||
* Alan Ramos <alan.ramos@jarsa.com.mx>
|
||||
* Damien Crier <damien.crier@camptocamp.com>
|
||||
* Cyril Gaudin <cyril.gaudin@camptocamp.com>
|
||||
* Pierre Verkest <pverkest@anybox.fr>
|
||||
* Benjamin Willig <benjamin.willig@acsone.eu>
|
||||
* Devendra Kavthekar <dkatodoo@gmail.com>
|
||||
* Emanuel Cino <ecino@compassion.ch>
|
||||
* Thomas Nowicki <thomas.nowicki@camptocamp.com>
|
||||
* Alexandre Saunier <alexandre.saunier@camptocamp.com>
|
||||
* Sandip Mangukiya <smangukiya@opensourceintegrators.com>
|
||||
* Samuel Kouff <s.kouff@student.helmo.be>
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
GeoEngine is an Odoo module that adds spatial/GIS capabilites to Odoo. It will allow you to :
|
||||
|
||||
* Visualize and query your business information on map
|
||||
* Perform GeoBI and spatial query
|
||||
* Configure your spatial layers and spatial datasources
|
||||
* Extend Odoo models with spatial columns
|
||||
|
||||
GeoEngine relies on `OpenLayers <http://openlayers.org>`_ and `PostgGIS <http://postgis.refractions.net/>`_ technologies.
|
||||
|
||||
Postgis is used to store spatial information in databases. OpenLayer is used to represent spatial data in other words to show maps
|
||||
and the different spatial layers. The GeoEngine module acts as a data provider and as an OpenLayers configurator.
|
||||
It also provides a complete extension to Odoo ORM.
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
16.0.1.0.0 (2023-03-20)
|
||||
========================
|
||||
|
||||
* LayerSwitcher has been removed as it was not really practical. A LayerPanel is now active.
|
||||
* The geo_search method is now deprecated and replaced by the standard odoo search method.
|
||||
* The widget "geo_edit_map" attribute is no longer necessary as the field is automatically detected by
|
||||
his type. We can also provide an option attribute that allows us to pass an opacity and a color as
|
||||
parameters.
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<form>
|
||||
<notebook colspan="4">
|
||||
<page string="Geometry">
|
||||
<field name="the_geom" options="{'opacity': 0.8, 'color': '#0000FF' }" />
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
|
||||
* The method geo_search is now deprecated. We now need to use the standard odoo search method.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
obj.search([("the_point","geo_intersect",{"dummy.zip.the_geom": [("id", "=", rec.id)]})])
|
||||
|
||||
* We can now pass to the geoengine view a template to display the information we want
|
||||
to see when clicking on a feature.
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<geoengine>
|
||||
<field name="name" />
|
||||
<field name="city" />
|
||||
<field name="total_sales" />
|
||||
<field name="the_geom" />
|
||||
<templates>
|
||||
<t t-name="info_box">
|
||||
<field name="city" widget="badge" />
|
||||
<ul>
|
||||
<li>ZIP : <field name="name" />
|
||||
</li>
|
||||
<li>Total Sales: <field name="total_sales" />
|
||||
</li>
|
||||
</ul>
|
||||
</t>
|
||||
</templates>
|
||||
</geoengine>
|
||||
|
||||
* We can now pass a model to use to a layer to display other information on the map.
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<record id="geoengine_vector_layer_hs_retail_machines" model="geoengine.vector.layer">
|
||||
<field name="model_id" ref="base_geoengine_demo.model_geoengine_demo_automatic_retailing_machine"/>
|
||||
<field name="model_domain">[('state', '=', 'hs')]</field>
|
||||
<field name="geo_field_id" ref="base_geoengine_demo.field_geoengine_demo_automatic_retailing_machine__the_point"/>
|
||||
<field name="name">HS retail machines</field>
|
||||
<field name="view_id" ref="ir_ui_view_resbetterzipgeoview0" />
|
||||
<field name="geo_repr">basic</field>
|
||||
<field name="attribute_field_id" ref="base_geoengine_demo.field_geoengine_demo_automatic_retailing_machine__name"/>
|
||||
<field name="begin_color">#FF0000</field>
|
||||
<field name="display_polygon_labels" eval="0" />
|
||||
<field name="layer_opacity">0.8</field>
|
||||
</record>
|
||||
|
||||
|
||||
* There is some new features in the LayerPanel.
|
||||
|
||||
1. If you are logged in as an admin, you have the possibility to edit the layer by clicking on the edit button. This will open a dialog box.
|
||||
Changes will appear in real time on the view.
|
||||
2. If you are logged in as an admin, you can also change the domain of the layer. If you are logged in as a user, changes will not be
|
||||
persisted in the database. Changes will appear in real time on the view.
|
||||
3. If you are logged in as an admin, you can also change the sequence of the layers by sliding them over each other. If you are logged in as a user, changes will not be
|
||||
persisted in the database.
|
||||
|
||||
* Widget domain is now implemented for geo field This means that the geo-operators are also implemented and that there is the possibility to add a sub-domain.
|
||||
If we want to add a domain that includes all the records that are displayed in the geoengine view (active_ids). We can use the two new operators :
|
||||
"in active_ids" and "not in active_ids". These will automatically replace the marker with ids. Note that the widget will indicate that the domain is invalid
|
||||
because of the marker.
|
||||
* Creation of the RecordsPanel. This panel allows you to retrieve all active records. You can click on record to get the movement to the selected record.
|
||||
Two magnifying glass are also available. You can click on the left one to zoom on the record. You can click on the right one to get the original zoom.
|
||||
* A search bar is also available. It allows you to perform a search into the RecordsPanel.
|
||||
* A button to open/close the panels is also available.
|
||||
* The module has been translated in French.
|
||||
* Now you can now make the geoengine view editable. Simply add editable attribute in the geoengine view.
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<geoengine editable="1">
|
||||
<field name="name" />
|
||||
<field name="city" />
|
||||
<field name="total_sales" />
|
||||
<field name="the_geom" />
|
||||
<field name="display_name" />
|
||||
<templates>
|
||||
<t t-name="info_box">
|
||||
<field name="city" widget="badge" />
|
||||
<ul>
|
||||
<li>ZIP : <field name="name" />
|
||||
</li>
|
||||
<li>Total Sales: <field name="total_sales" />
|
||||
</li>
|
||||
</ul>
|
||||
</t>
|
||||
</templates>
|
||||
</geoengine>
|
||||
|
||||
Thanks to that, you can create new records by drawing them directly in the geoengine view. You can also edit record in the same view.
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
|
||||
To install this module, you need to have `PostGIS <http://postgis.net/>`_ installed.
|
||||
|
||||
On Ubuntu::
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo apt-get install postgis
|
||||
|
||||
The module also requires two additional python libs:
|
||||
|
||||
* `Shapely <http://pypi.python.org/pypi/Shapely>`_
|
||||
|
||||
* `geojson <http://pypi.python.org/pypi/geojson>`_
|
||||
|
||||
When you will install the module this two additional libs will be installed.
|
||||
|
||||
For a complete documentation please refer to the `public documenation <http://oca.github.io/geospatial/index.html>`_
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
Geoengine Demo
|
||||
==============
|
||||
|
||||
1. As a user/admin, when I am in the Geoengine Demo module and I go to the ZIP menu.
|
||||
When I click on an item in the list view, I get to the form view showing me the different
|
||||
information about the ZIP. We can see its ZIP, city, priority, total sales and his spatial
|
||||
representation.
|
||||
2. As a user, I can't modify the information in the form view.
|
||||
3. As an admin, I can modify the information in the form view. I can click on the bin button to clear
|
||||
the map and I can draw a new shape.
|
||||
4. As a user, when I go the "Retail machines" tab and there are no items to display, it does not
|
||||
show me anything.
|
||||
5. As an admin, when I go the "Retail machines" tab and there are no items to display, the list view of
|
||||
the retail machines suggests to me to add a new line.
|
||||
6. As a user/admin, if there are items to be displayed in the "Retail machines" tab then I can click on an
|
||||
item and the retail machines form view will be displayed. We can see its spatial representation by going
|
||||
to "The point" tab and its attributes in "Attributes" tab.
|
||||
7. As a user/admin, when I go to the geoengine zip view by clicking on the map button at the top right of the
|
||||
screen. The geoengine view appears with the first 80 results displayed on the map. The vector layers
|
||||
selected are those defined as "active on startup" by the admin. The selected raster layer is the first
|
||||
one that is not an overlay layer.
|
||||
8. As a user/admin, when I hover over an area on the map, the area changes its style.
|
||||
9. As a user/admin, when I click on an area, a popup appears an I can see the different information about the
|
||||
area. If I click on the cross, the popup will disappear. If I click somewhere else on the map, the
|
||||
popup will also disappear. If I click on the about button, then the form view will be displayed.
|
||||
10. As a user/admin, when I use the paging system, then the results displayed on the map are different
|
||||
(corresponding to the request).
|
||||
11. As a user/admin, if we use the search bar, we can search results by his zip or his city.
|
||||
12. As an admin, if I change the sequence of layers with the handle button then the change are persisted in database.
|
||||
13. As a user, if I change the sequence of layers with the handle button then the change are not persisted in database.
|
||||
There are just the changes in the display.
|
||||
14. As an admin, if I change the domain of a layer with the filter button then the change are persisted in database.
|
||||
15. As a user, if I change the domain of a layer with the filter button then the change are not persisted in database.
|
||||
There are just the changes in the display.
|
||||
16. As an admin, I have the possibility to edit the layer with its corresponding button.
|
||||
17. As a user/admin, I can open/close LayerPanel with its button.
|
||||
18. As a user/admin, I can open/close RecordsPanel with its button.
|
||||
19. As a user/admin, when I click on a record in RecordsPanel, a move is made on the map to the selected record.
|
||||
20. As a user/admin, when I click on a record in RecordsPanel, I can also click on the left magnifying glass to zoom on the record.
|
||||
21. As a user/admin, when I click on a record in RecordsPanel, I can also click on the right magnifying glass to get the original zoom.
|
||||
22. As a user/admin, I can use the search bar to search in the RecordsPanel.
|
||||
23. As an admin,If the geoengine view is in edit mode, I can create new records by drawing them in the view.
|
||||
24. As an admin, If the geoengine view is in edit mode, I can modify its spatial representation.
|
||||
|
||||
Geoengine Backend
|
||||
=================
|
||||
|
||||
1. As an admin, if I go into the configuration of the raster layers and it has elements, I can click
|
||||
on one and see its information.
|
||||
2. As an admin, if I want to create a new raster layer, I can click on "NEW" and fill out the form. The
|
||||
required fields for OpenStreetMap type are "Layer Name" and "Related View". If we want to have a
|
||||
WMTS (Web Map Tile Service) raster type. The required fields in addition to the precedents are "Service URL",
|
||||
"Matrix set","Format", "Projection" and "Resolutions". If we take WMS (Web Map Service) raster type, then the
|
||||
required fields are "Layer Name", "Related View", "Service URL", "Params", "Server Type".
|
||||
3. As an admin,if I go into the configuration of the vector layers and it has elements, I can click
|
||||
on one and see its information.
|
||||
4. As an admin, if I want to create a new vector layer, I can click on "NEW" and fill out the form. The
|
||||
required fields are "Layer Name", "Related View", "Geo field" and "Representation mode".
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
|
||||
<record id="group_geoengine_user" model="res.groups">
|
||||
<field name="name">Geoengine User</field>
|
||||
</record>
|
||||
|
||||
<record id="group_geoengine_admin" model="res.groups">
|
||||
<field name="name">Geoengine Admin</field>
|
||||
<field name="implied_ids" eval="[(4, ref('group_geoengine_user')),]" />
|
||||
<field name="users" eval="[(4, ref('base.user_root'))]" />
|
||||
</record>
|
||||
|
||||
<record id="base.group_user" model="res.groups">
|
||||
<field name="implied_ids" eval="[Command.link(ref('group_geoengine_user'))]" />
|
||||
</record>
|
||||
|
||||
<record id="base.group_erp_manager" model="res.groups">
|
||||
<field name="implied_ids" eval="[Command.link(ref('group_geoengine_admin'))]" />
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_geo_user_vector_user,geoengine.user.vector.layer,base_geoengine.model_geoengine_vector_layer,base_geoengine.group_geoengine_user,1,0,0,0
|
||||
access_geo_admin_vector_user,geoengine.admin.vector.layer,base_geoengine.model_geoengine_vector_layer,base_geoengine.group_geoengine_admin,1,1,1,1
|
||||
access_geo_user_raster_user,geoengine.user.raster.layer,base_geoengine.model_geoengine_raster_layer,base_geoengine.group_geoengine_user,1,0,0,0
|
||||
access_geo_admin_raster_user,geoengine.admin.raster.layer,base_geoengine.model_geoengine_raster_layer,base_geoengine.group_geoengine_admin,1,1,1,1
|
||||
access_geo_user_raster_type_user,geoengine.user.raster.layer.type,base_geoengine.model_geoengine_raster_layer_type,base_geoengine.group_geoengine_user,1,0,0,0
|
||||
access_geo_admin_raster_type_user,geoengine.admin.raster.layer.type,base_geoengine.model_geoengine_raster_layer_type,base_geoengine.group_geoengine_admin,1,1,1,1
|
||||
|
Binary file not shown.
|
After Width: | Height: | Size: 127 KiB |
|
|
@ -0,0 +1,659 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
|
||||
<title>README.rst</title>
|
||||
<style type="text/css">
|
||||
|
||||
/*
|
||||
:Author: David Goodger (goodger@python.org)
|
||||
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
|
||||
:Copyright: This stylesheet has been placed in the public domain.
|
||||
|
||||
Default cascading style sheet for the HTML output of Docutils.
|
||||
Despite the name, some widely supported CSS2 features are used.
|
||||
|
||||
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
|
||||
customize this style sheet.
|
||||
*/
|
||||
|
||||
/* used to remove borders from tables and images */
|
||||
.borderless, table.borderless td, table.borderless th {
|
||||
border: 0 }
|
||||
|
||||
table.borderless td, table.borderless th {
|
||||
/* Override padding for "table.docutils td" with "! important".
|
||||
The right padding separates the table cells. */
|
||||
padding: 0 0.5em 0 0 ! important }
|
||||
|
||||
.first {
|
||||
/* Override more specific margin styles with "! important". */
|
||||
margin-top: 0 ! important }
|
||||
|
||||
.last, .with-subtitle {
|
||||
margin-bottom: 0 ! important }
|
||||
|
||||
.hidden {
|
||||
display: none }
|
||||
|
||||
.subscript {
|
||||
vertical-align: sub;
|
||||
font-size: smaller }
|
||||
|
||||
.superscript {
|
||||
vertical-align: super;
|
||||
font-size: smaller }
|
||||
|
||||
a.toc-backref {
|
||||
text-decoration: none ;
|
||||
color: black }
|
||||
|
||||
blockquote.epigraph {
|
||||
margin: 2em 5em ; }
|
||||
|
||||
dl.docutils dd {
|
||||
margin-bottom: 0.5em }
|
||||
|
||||
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Uncomment (and remove this text!) to get bold-faced definition list terms
|
||||
dl.docutils dt {
|
||||
font-weight: bold }
|
||||
*/
|
||||
|
||||
div.abstract {
|
||||
margin: 2em 5em }
|
||||
|
||||
div.abstract p.topic-title {
|
||||
font-weight: bold ;
|
||||
text-align: center }
|
||||
|
||||
div.admonition, div.attention, div.caution, div.danger, div.error,
|
||||
div.hint, div.important, div.note, div.tip, div.warning {
|
||||
margin: 2em ;
|
||||
border: medium outset ;
|
||||
padding: 1em }
|
||||
|
||||
div.admonition p.admonition-title, div.hint p.admonition-title,
|
||||
div.important p.admonition-title, div.note p.admonition-title,
|
||||
div.tip p.admonition-title {
|
||||
font-weight: bold ;
|
||||
font-family: sans-serif }
|
||||
|
||||
div.attention p.admonition-title, div.caution p.admonition-title,
|
||||
div.danger p.admonition-title, div.error p.admonition-title,
|
||||
div.warning p.admonition-title, .code .error {
|
||||
color: red ;
|
||||
font-weight: bold ;
|
||||
font-family: sans-serif }
|
||||
|
||||
/* Uncomment (and remove this text!) to get reduced vertical space in
|
||||
compound paragraphs.
|
||||
div.compound .compound-first, div.compound .compound-middle {
|
||||
margin-bottom: 0.5em }
|
||||
|
||||
div.compound .compound-last, div.compound .compound-middle {
|
||||
margin-top: 0.5em }
|
||||
*/
|
||||
|
||||
div.dedication {
|
||||
margin: 2em 5em ;
|
||||
text-align: center ;
|
||||
font-style: italic }
|
||||
|
||||
div.dedication p.topic-title {
|
||||
font-weight: bold ;
|
||||
font-style: normal }
|
||||
|
||||
div.figure {
|
||||
margin-left: 2em ;
|
||||
margin-right: 2em }
|
||||
|
||||
div.footer, div.header {
|
||||
clear: both;
|
||||
font-size: smaller }
|
||||
|
||||
div.line-block {
|
||||
display: block ;
|
||||
margin-top: 1em ;
|
||||
margin-bottom: 1em }
|
||||
|
||||
div.line-block div.line-block {
|
||||
margin-top: 0 ;
|
||||
margin-bottom: 0 ;
|
||||
margin-left: 1.5em }
|
||||
|
||||
div.sidebar {
|
||||
margin: 0 0 0.5em 1em ;
|
||||
border: medium outset ;
|
||||
padding: 1em ;
|
||||
background-color: #ffffee ;
|
||||
width: 40% ;
|
||||
float: right ;
|
||||
clear: right }
|
||||
|
||||
div.sidebar p.rubric {
|
||||
font-family: sans-serif ;
|
||||
font-size: medium }
|
||||
|
||||
div.system-messages {
|
||||
margin: 5em }
|
||||
|
||||
div.system-messages h1 {
|
||||
color: red }
|
||||
|
||||
div.system-message {
|
||||
border: medium outset ;
|
||||
padding: 1em }
|
||||
|
||||
div.system-message p.system-message-title {
|
||||
color: red ;
|
||||
font-weight: bold }
|
||||
|
||||
div.topic {
|
||||
margin: 2em }
|
||||
|
||||
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
|
||||
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
|
||||
margin-top: 0.4em }
|
||||
|
||||
h1.title {
|
||||
text-align: center }
|
||||
|
||||
h2.subtitle {
|
||||
text-align: center }
|
||||
|
||||
hr.docutils {
|
||||
width: 75% }
|
||||
|
||||
img.align-left, .figure.align-left, object.align-left, table.align-left {
|
||||
clear: left ;
|
||||
float: left ;
|
||||
margin-right: 1em }
|
||||
|
||||
img.align-right, .figure.align-right, object.align-right, table.align-right {
|
||||
clear: right ;
|
||||
float: right ;
|
||||
margin-left: 1em }
|
||||
|
||||
img.align-center, .figure.align-center, object.align-center {
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
table.align-center {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.align-left {
|
||||
text-align: left }
|
||||
|
||||
.align-center {
|
||||
clear: both ;
|
||||
text-align: center }
|
||||
|
||||
.align-right {
|
||||
text-align: right }
|
||||
|
||||
/* reset inner alignment in figures */
|
||||
div.align-right {
|
||||
text-align: inherit }
|
||||
|
||||
/* div.align-center * { */
|
||||
/* text-align: left } */
|
||||
|
||||
.align-top {
|
||||
vertical-align: top }
|
||||
|
||||
.align-middle {
|
||||
vertical-align: middle }
|
||||
|
||||
.align-bottom {
|
||||
vertical-align: bottom }
|
||||
|
||||
ol.simple, ul.simple {
|
||||
margin-bottom: 1em }
|
||||
|
||||
ol.arabic {
|
||||
list-style: decimal }
|
||||
|
||||
ol.loweralpha {
|
||||
list-style: lower-alpha }
|
||||
|
||||
ol.upperalpha {
|
||||
list-style: upper-alpha }
|
||||
|
||||
ol.lowerroman {
|
||||
list-style: lower-roman }
|
||||
|
||||
ol.upperroman {
|
||||
list-style: upper-roman }
|
||||
|
||||
p.attribution {
|
||||
text-align: right ;
|
||||
margin-left: 50% }
|
||||
|
||||
p.caption {
|
||||
font-style: italic }
|
||||
|
||||
p.credits {
|
||||
font-style: italic ;
|
||||
font-size: smaller }
|
||||
|
||||
p.label {
|
||||
white-space: nowrap }
|
||||
|
||||
p.rubric {
|
||||
font-weight: bold ;
|
||||
font-size: larger ;
|
||||
color: maroon ;
|
||||
text-align: center }
|
||||
|
||||
p.sidebar-title {
|
||||
font-family: sans-serif ;
|
||||
font-weight: bold ;
|
||||
font-size: larger }
|
||||
|
||||
p.sidebar-subtitle {
|
||||
font-family: sans-serif ;
|
||||
font-weight: bold }
|
||||
|
||||
p.topic-title {
|
||||
font-weight: bold }
|
||||
|
||||
pre.address {
|
||||
margin-bottom: 0 ;
|
||||
margin-top: 0 ;
|
||||
font: inherit }
|
||||
|
||||
pre.literal-block, pre.doctest-block, pre.math, pre.code {
|
||||
margin-left: 2em ;
|
||||
margin-right: 2em }
|
||||
|
||||
pre.code .ln { color: gray; } /* line numbers */
|
||||
pre.code, code { background-color: #eeeeee }
|
||||
pre.code .comment, code .comment { color: #5C6576 }
|
||||
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
|
||||
pre.code .literal.string, code .literal.string { color: #0C5404 }
|
||||
pre.code .name.builtin, code .name.builtin { color: #352B84 }
|
||||
pre.code .deleted, code .deleted { background-color: #DEB0A1}
|
||||
pre.code .inserted, code .inserted { background-color: #A3D289}
|
||||
|
||||
span.classifier {
|
||||
font-family: sans-serif ;
|
||||
font-style: oblique }
|
||||
|
||||
span.classifier-delimiter {
|
||||
font-family: sans-serif ;
|
||||
font-weight: bold }
|
||||
|
||||
span.interpreted {
|
||||
font-family: sans-serif }
|
||||
|
||||
span.option {
|
||||
white-space: nowrap }
|
||||
|
||||
span.pre {
|
||||
white-space: pre }
|
||||
|
||||
span.problematic, pre.problematic {
|
||||
color: red }
|
||||
|
||||
span.section-subtitle {
|
||||
/* font-size relative to parent (h1..h6 element) */
|
||||
font-size: 80% }
|
||||
|
||||
table.citation {
|
||||
border-left: solid 1px gray;
|
||||
margin-left: 1px }
|
||||
|
||||
table.docinfo {
|
||||
margin: 2em 4em }
|
||||
|
||||
table.docutils {
|
||||
margin-top: 0.5em ;
|
||||
margin-bottom: 0.5em }
|
||||
|
||||
table.footnote {
|
||||
border-left: solid 1px black;
|
||||
margin-left: 1px }
|
||||
|
||||
table.docutils td, table.docutils th,
|
||||
table.docinfo td, table.docinfo th {
|
||||
padding-left: 0.5em ;
|
||||
padding-right: 0.5em ;
|
||||
vertical-align: top }
|
||||
|
||||
table.docutils th.field-name, table.docinfo th.docinfo-name {
|
||||
font-weight: bold ;
|
||||
text-align: left ;
|
||||
white-space: nowrap ;
|
||||
padding-left: 0 }
|
||||
|
||||
/* "booktabs" style (no vertical lines) */
|
||||
table.docutils.booktabs {
|
||||
border: 0px;
|
||||
border-top: 2px solid;
|
||||
border-bottom: 2px solid;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
table.docutils.booktabs * {
|
||||
border: 0px;
|
||||
}
|
||||
table.docutils.booktabs th {
|
||||
border-bottom: thin solid;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
|
||||
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
|
||||
font-size: 100% }
|
||||
|
||||
ul.auto-toc {
|
||||
list-style-type: none }
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="document">
|
||||
|
||||
|
||||
<a class="reference external image-reference" href="https://odoo-community.org/get-involved?utm_source=readme">
|
||||
<img alt="Odoo Community Association" src="https://odoo-community.org/readme-banner-image" />
|
||||
</a>
|
||||
<div class="section" id="geospatial-support-for-odoo">
|
||||
<h1>Geospatial support for Odoo</h1>
|
||||
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!! This file is generated by oca-gen-addon-readme !!
|
||||
!! changes will be overwritten. !!
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!! source digest: sha256:2faa9b7de06a2c3c20d9bc960073bdc6638396bc987e338093331e0099278604
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
|
||||
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/license-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/geospatial/tree/16.0/base_geoengine"><img alt="OCA/geospatial" src="https://img.shields.io/badge/github-OCA%2Fgeospatial-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/geospatial-16-0/geospatial-16-0-base_geoengine"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/geospatial&target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
|
||||
<p>GeoEngine is an Odoo module that adds spatial/GIS capabilites to Odoo. It will allow you to :</p>
|
||||
<ul class="simple">
|
||||
<li>Visualize and query your business information on map</li>
|
||||
<li>Perform GeoBI and spatial query</li>
|
||||
<li>Configure your spatial layers and spatial datasources</li>
|
||||
<li>Extend Odoo models with spatial columns</li>
|
||||
</ul>
|
||||
<p>GeoEngine relies on <a class="reference external" href="http://openlayers.org">OpenLayers</a> and <a class="reference external" href="http://postgis.refractions.net/">PostgGIS</a> technologies.</p>
|
||||
<p>Postgis is used to store spatial information in databases. OpenLayer is used to represent spatial data in other words to show maps
|
||||
and the different spatial layers. The GeoEngine module acts as a data provider and as an OpenLayers configurator.
|
||||
It also provides a complete extension to Odoo ORM.</p>
|
||||
<p><strong>Table of contents</strong></p>
|
||||
<div class="contents local topic" id="contents">
|
||||
<ul class="simple">
|
||||
<li><a class="reference internal" href="#installation" id="toc-entry-1">Installation</a></li>
|
||||
<li><a class="reference internal" href="#usage" id="toc-entry-2">Usage</a></li>
|
||||
<li><a class="reference internal" href="#geoengine-demo" id="toc-entry-3">Geoengine Demo</a></li>
|
||||
<li><a class="reference internal" href="#geoengine-backend" id="toc-entry-4">Geoengine Backend</a></li>
|
||||
<li><a class="reference internal" href="#changelog" id="toc-entry-5">Changelog</a></li>
|
||||
<li><a class="reference internal" href="#section-1" id="toc-entry-6">16.0.1.0.0 (2023-03-20)</a></li>
|
||||
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-7">Bug Tracker</a></li>
|
||||
<li><a class="reference internal" href="#credits" id="toc-entry-8">Credits</a><ul>
|
||||
<li><a class="reference internal" href="#authors" id="toc-entry-9">Authors</a></li>
|
||||
<li><a class="reference internal" href="#contributors" id="toc-entry-10">Contributors</a></li>
|
||||
<li><a class="reference internal" href="#maintainers" id="toc-entry-11">Maintainers</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="installation">
|
||||
<h2><a class="toc-backref" href="#toc-entry-1">Installation</a></h2>
|
||||
<p>To install this module, you need to have <a class="reference external" href="http://postgis.net/">PostGIS</a> installed.</p>
|
||||
<p>On Ubuntu:</p>
|
||||
<pre class="literal-block">
|
||||
.. code-block:: bash
|
||||
</pre>
|
||||
<blockquote>
|
||||
sudo apt-get install postgis</blockquote>
|
||||
<p>The module also requires two additional python libs:</p>
|
||||
<ul class="simple">
|
||||
<li><a class="reference external" href="http://pypi.python.org/pypi/Shapely">Shapely</a></li>
|
||||
<li><a class="reference external" href="http://pypi.python.org/pypi/geojson">geojson</a></li>
|
||||
</ul>
|
||||
<p>When you will install the module this two additional libs will be installed.</p>
|
||||
<p>For a complete documentation please refer to the <a class="reference external" href="http://oca.github.io/geospatial/index.html">public documenation</a></p>
|
||||
</div>
|
||||
<div class="section" id="usage">
|
||||
<h2><a class="toc-backref" href="#toc-entry-2">Usage</a></h2>
|
||||
</div>
|
||||
<div class="section" id="geoengine-demo">
|
||||
<h2><a class="toc-backref" href="#toc-entry-3">Geoengine Demo</a></h2>
|
||||
<ol class="arabic simple">
|
||||
<li>As a user/admin, when I am in the Geoengine Demo module and I go to the ZIP menu.
|
||||
When I click on an item in the list view, I get to the form view showing me the different
|
||||
information about the ZIP. We can see its ZIP, city, priority, total sales and his spatial
|
||||
representation.</li>
|
||||
<li>As a user, I can’t modify the information in the form view.</li>
|
||||
<li>As an admin, I can modify the information in the form view. I can click on the bin button to clear
|
||||
the map and I can draw a new shape.</li>
|
||||
<li>As a user, when I go the “Retail machines” tab and there are no items to display, it does not
|
||||
show me anything.</li>
|
||||
<li>As an admin, when I go the “Retail machines” tab and there are no items to display, the list view of
|
||||
the retail machines suggests to me to add a new line.</li>
|
||||
<li>As a user/admin, if there are items to be displayed in the “Retail machines” tab then I can click on an
|
||||
item and the retail machines form view will be displayed. We can see its spatial representation by going
|
||||
to “The point” tab and its attributes in “Attributes” tab.</li>
|
||||
<li>As a user/admin, when I go to the geoengine zip view by clicking on the map button at the top right of the
|
||||
screen. The geoengine view appears with the first 80 results displayed on the map. The vector layers
|
||||
selected are those defined as “active on startup” by the admin. The selected raster layer is the first
|
||||
one that is not an overlay layer.</li>
|
||||
<li>As a user/admin, when I hover over an area on the map, the area changes its style.</li>
|
||||
<li>As a user/admin, when I click on an area, a popup appears an I can see the different information about the
|
||||
area. If I click on the cross, the popup will disappear. If I click somewhere else on the map, the
|
||||
popup will also disappear. If I click on the about button, then the form view will be displayed.</li>
|
||||
<li>As a user/admin, when I use the paging system, then the results displayed on the map are different
|
||||
(corresponding to the request).</li>
|
||||
<li>As a user/admin, if we use the search bar, we can search results by his zip or his city.</li>
|
||||
<li>As an admin, if I change the sequence of layers with the handle button then the change are persisted in database.</li>
|
||||
<li>As a user, if I change the sequence of layers with the handle button then the change are not persisted in database.
|
||||
There are just the changes in the display.</li>
|
||||
<li>As an admin, if I change the domain of a layer with the filter button then the change are persisted in database.</li>
|
||||
<li>As a user, if I change the domain of a layer with the filter button then the change are not persisted in database.
|
||||
There are just the changes in the display.</li>
|
||||
<li>As an admin, I have the possibility to edit the layer with its corresponding button.</li>
|
||||
<li>As a user/admin, I can open/close LayerPanel with its button.</li>
|
||||
<li>As a user/admin, I can open/close RecordsPanel with its button.</li>
|
||||
<li>As a user/admin, when I click on a record in RecordsPanel, a move is made on the map to the selected record.</li>
|
||||
<li>As a user/admin, when I click on a record in RecordsPanel, I can also click on the left magnifying glass to zoom on the record.</li>
|
||||
<li>As a user/admin, when I click on a record in RecordsPanel, I can also click on the right magnifying glass to get the original zoom.</li>
|
||||
<li>As a user/admin, I can use the search bar to search in the RecordsPanel.</li>
|
||||
<li>As an admin,If the geoengine view is in edit mode, I can create new records by drawing them in the view.</li>
|
||||
<li>As an admin, If the geoengine view is in edit mode, I can modify its spatial representation.</li>
|
||||
</ol>
|
||||
</div>
|
||||
<div class="section" id="geoengine-backend">
|
||||
<h2><a class="toc-backref" href="#toc-entry-4">Geoengine Backend</a></h2>
|
||||
<ol class="arabic simple">
|
||||
<li>As an admin, if I go into the configuration of the raster layers and it has elements, I can click
|
||||
on one and see its information.</li>
|
||||
<li>As an admin, if I want to create a new raster layer, I can click on “NEW” and fill out the form. The
|
||||
required fields for OpenStreetMap type are “Layer Name” and “Related View”. If we want to have a
|
||||
WMTS (Web Map Tile Service) raster type. The required fields in addition to the precedents are “Service URL”,
|
||||
“Matrix set”,”Format”, “Projection” and “Resolutions”. If we take WMS (Web Map Service) raster type, then the
|
||||
required fields are “Layer Name”, “Related View”, “Service URL”, “Params”, “Server Type”.</li>
|
||||
<li>As an admin,if I go into the configuration of the vector layers and it has elements, I can click
|
||||
on one and see its information.</li>
|
||||
<li>As an admin, if I want to create a new vector layer, I can click on “NEW” and fill out the form. The
|
||||
required fields are “Layer Name”, “Related View”, “Geo field” and “Representation mode”.</li>
|
||||
</ol>
|
||||
</div>
|
||||
<div class="section" id="changelog">
|
||||
<h2><a class="toc-backref" href="#toc-entry-5">Changelog</a></h2>
|
||||
</div>
|
||||
<div class="section" id="section-1">
|
||||
<h2><a class="toc-backref" href="#toc-entry-6">16.0.1.0.0 (2023-03-20)</a></h2>
|
||||
<ul class="simple">
|
||||
<li>LayerSwitcher has been removed as it was not really practical. A LayerPanel is now active.</li>
|
||||
<li>The geo_search method is now deprecated and replaced by the standard odoo search method.</li>
|
||||
<li>The widget “geo_edit_map” attribute is no longer necessary as the field is automatically detected by
|
||||
his type. We can also provide an option attribute that allows us to pass an opacity and a color as
|
||||
parameters.</li>
|
||||
</ul>
|
||||
<pre class="code xml literal-block">
|
||||
<span class="nt"><form></span><span class="w">
|
||||
</span><span class="nt"><notebook</span><span class="w"> </span><span class="na">colspan=</span><span class="s">"4"</span><span class="nt">></span><span class="w">
|
||||
</span><span class="nt"><page</span><span class="w"> </span><span class="na">string=</span><span class="s">"Geometry"</span><span class="nt">></span><span class="w">
|
||||
</span><span class="nt"><field</span><span class="w"> </span><span class="na">name=</span><span class="s">"the_geom"</span><span class="w"> </span><span class="na">options=</span><span class="s">"{'opacity': 0.8, 'color': '#0000FF' }"</span><span class="w"> </span><span class="nt">/></span><span class="w">
|
||||
</span><span class="nt"></page></span><span class="w">
|
||||
</span><span class="nt"></notebook></span><span class="w">
|
||||
</span><span class="nt"></form></span>
|
||||
</pre>
|
||||
<ul class="simple">
|
||||
<li>The method geo_search is now deprecated. We now need to use the standard odoo search method.</li>
|
||||
</ul>
|
||||
<pre class="code python literal-block">
|
||||
<span class="n">obj</span><span class="o">.</span><span class="n">search</span><span class="p">([(</span><span class="s2">"the_point"</span><span class="p">,</span><span class="s2">"geo_intersect"</span><span class="p">,{</span><span class="s2">"dummy.zip.the_geom"</span><span class="p">:</span> <span class="p">[(</span><span class="s2">"id"</span><span class="p">,</span> <span class="s2">"="</span><span class="p">,</span> <span class="n">rec</span><span class="o">.</span><span class="n">id</span><span class="p">)]})])</span>
|
||||
</pre>
|
||||
<ul class="simple">
|
||||
<li>We can now pass to the geoengine view a template to display the information we want
|
||||
to see when clicking on a feature.</li>
|
||||
</ul>
|
||||
<pre class="code xml literal-block">
|
||||
<span class="nt"><geoengine></span><span class="w">
|
||||
</span><span class="nt"><field</span><span class="w"> </span><span class="na">name=</span><span class="s">"name"</span><span class="w"> </span><span class="nt">/></span><span class="w">
|
||||
</span><span class="nt"><field</span><span class="w"> </span><span class="na">name=</span><span class="s">"city"</span><span class="w"> </span><span class="nt">/></span><span class="w">
|
||||
</span><span class="nt"><field</span><span class="w"> </span><span class="na">name=</span><span class="s">"total_sales"</span><span class="w"> </span><span class="nt">/></span><span class="w">
|
||||
</span><span class="nt"><field</span><span class="w"> </span><span class="na">name=</span><span class="s">"the_geom"</span><span class="w"> </span><span class="nt">/></span><span class="w">
|
||||
</span><span class="nt"><templates></span><span class="w">
|
||||
</span><span class="nt"><t</span><span class="w"> </span><span class="na">t-name=</span><span class="s">"info_box"</span><span class="nt">></span><span class="w">
|
||||
</span><span class="nt"><field</span><span class="w"> </span><span class="na">name=</span><span class="s">"city"</span><span class="w"> </span><span class="na">widget=</span><span class="s">"badge"</span><span class="w"> </span><span class="nt">/></span><span class="w">
|
||||
</span><span class="nt"><ul></span><span class="w">
|
||||
</span><span class="nt"><li></span>ZIP<span class="w"> </span>:<span class="w"> </span><span class="nt"><field</span><span class="w"> </span><span class="na">name=</span><span class="s">"name"</span><span class="w"> </span><span class="nt">/></span><span class="w">
|
||||
</span><span class="nt"></li></span><span class="w">
|
||||
</span><span class="nt"><li></span>Total<span class="w"> </span>Sales:<span class="w"> </span><span class="nt"><field</span><span class="w"> </span><span class="na">name=</span><span class="s">"total_sales"</span><span class="w"> </span><span class="nt">/></span><span class="w">
|
||||
</span><span class="nt"></li></span><span class="w">
|
||||
</span><span class="nt"></ul></span><span class="w">
|
||||
</span><span class="nt"></t></span><span class="w">
|
||||
</span><span class="nt"></templates></span><span class="w">
|
||||
</span><span class="nt"></geoengine></span>
|
||||
</pre>
|
||||
<ul class="simple">
|
||||
<li>We can now pass a model to use to a layer to display other information on the map.</li>
|
||||
</ul>
|
||||
<pre class="code xml literal-block">
|
||||
<span class="nt"><record</span><span class="w"> </span><span class="na">id=</span><span class="s">"geoengine_vector_layer_hs_retail_machines"</span><span class="w"> </span><span class="na">model=</span><span class="s">"geoengine.vector.layer"</span><span class="nt">></span><span class="w">
|
||||
</span><span class="nt"><field</span><span class="w"> </span><span class="na">name=</span><span class="s">"model_id"</span><span class="w"> </span><span class="na">ref=</span><span class="s">"base_geoengine_demo.model_geoengine_demo_automatic_retailing_machine"</span><span class="nt">/></span><span class="w">
|
||||
</span><span class="nt"><field</span><span class="w"> </span><span class="na">name=</span><span class="s">"model_domain"</span><span class="nt">></span>[('state',<span class="w"> </span>'=',<span class="w"> </span>'hs')]<span class="nt"></field></span><span class="w">
|
||||
</span><span class="nt"><field</span><span class="w"> </span><span class="na">name=</span><span class="s">"geo_field_id"</span><span class="w"> </span><span class="na">ref=</span><span class="s">"base_geoengine_demo.field_geoengine_demo_automatic_retailing_machine__the_point"</span><span class="nt">/></span><span class="w">
|
||||
</span><span class="nt"><field</span><span class="w"> </span><span class="na">name=</span><span class="s">"name"</span><span class="nt">></span>HS<span class="w"> </span>retail<span class="w"> </span>machines<span class="nt"></field></span><span class="w">
|
||||
</span><span class="nt"><field</span><span class="w"> </span><span class="na">name=</span><span class="s">"view_id"</span><span class="w"> </span><span class="na">ref=</span><span class="s">"ir_ui_view_resbetterzipgeoview0"</span><span class="w"> </span><span class="nt">/></span><span class="w">
|
||||
</span><span class="nt"><field</span><span class="w"> </span><span class="na">name=</span><span class="s">"geo_repr"</span><span class="nt">></span>basic<span class="nt"></field></span><span class="w">
|
||||
</span><span class="nt"><field</span><span class="w"> </span><span class="na">name=</span><span class="s">"attribute_field_id"</span><span class="w"> </span><span class="na">ref=</span><span class="s">"base_geoengine_demo.field_geoengine_demo_automatic_retailing_machine__name"</span><span class="nt">/></span><span class="w">
|
||||
</span><span class="nt"><field</span><span class="w"> </span><span class="na">name=</span><span class="s">"begin_color"</span><span class="nt">></span>#FF0000<span class="nt"></field></span><span class="w">
|
||||
</span><span class="nt"><field</span><span class="w"> </span><span class="na">name=</span><span class="s">"display_polygon_labels"</span><span class="w"> </span><span class="na">eval=</span><span class="s">"0"</span><span class="w"> </span><span class="nt">/></span><span class="w">
|
||||
</span><span class="nt"><field</span><span class="w"> </span><span class="na">name=</span><span class="s">"layer_opacity"</span><span class="nt">></span>0.8<span class="nt"></field></span><span class="w">
|
||||
</span><span class="nt"></record></span>
|
||||
</pre>
|
||||
<ul class="simple">
|
||||
<li>There is some new features in the LayerPanel.</li>
|
||||
</ul>
|
||||
<ol class="arabic simple">
|
||||
<li>If you are logged in as an admin, you have the possibility to edit the layer by clicking on the edit button. This will open a dialog box.
|
||||
Changes will appear in real time on the view.</li>
|
||||
<li>If you are logged in as an admin, you can also change the domain of the layer. If you are logged in as a user, changes will not be
|
||||
persisted in the database. Changes will appear in real time on the view.</li>
|
||||
<li>If you are logged in as an admin, you can also change the sequence of the layers by sliding them over each other. If you are logged in as a user, changes will not be
|
||||
persisted in the database.</li>
|
||||
</ol>
|
||||
<ul class="simple">
|
||||
<li>Widget domain is now implemented for geo field This means that the geo-operators are also implemented and that there is the possibility to add a sub-domain.
|
||||
If we want to add a domain that includes all the records that are displayed in the geoengine view (active_ids). We can use the two new operators :
|
||||
“in active_ids” and “not in active_ids”. These will automatically replace the marker with ids. Note that the widget will indicate that the domain is invalid
|
||||
because of the marker.</li>
|
||||
<li>Creation of the RecordsPanel. This panel allows you to retrieve all active records. You can click on record to get the movement to the selected record.
|
||||
Two magnifying glass are also available. You can click on the left one to zoom on the record. You can click on the right one to get the original zoom.</li>
|
||||
<li>A search bar is also available. It allows you to perform a search into the RecordsPanel.</li>
|
||||
<li>A button to open/close the panels is also available.</li>
|
||||
<li>The module has been translated in French.</li>
|
||||
<li>Now you can now make the geoengine view editable. Simply add editable attribute in the geoengine view.</li>
|
||||
</ul>
|
||||
<pre class="code xml literal-block">
|
||||
<span class="nt"><geoengine</span><span class="w"> </span><span class="na">editable=</span><span class="s">"1"</span><span class="nt">></span><span class="w">
|
||||
</span><span class="nt"><field</span><span class="w"> </span><span class="na">name=</span><span class="s">"name"</span><span class="w"> </span><span class="nt">/></span><span class="w">
|
||||
</span><span class="nt"><field</span><span class="w"> </span><span class="na">name=</span><span class="s">"city"</span><span class="w"> </span><span class="nt">/></span><span class="w">
|
||||
</span><span class="nt"><field</span><span class="w"> </span><span class="na">name=</span><span class="s">"total_sales"</span><span class="w"> </span><span class="nt">/></span><span class="w">
|
||||
</span><span class="nt"><field</span><span class="w"> </span><span class="na">name=</span><span class="s">"the_geom"</span><span class="w"> </span><span class="nt">/></span><span class="w">
|
||||
</span><span class="nt"><field</span><span class="w"> </span><span class="na">name=</span><span class="s">"display_name"</span><span class="w"> </span><span class="nt">/></span><span class="w">
|
||||
</span><span class="nt"><templates></span><span class="w">
|
||||
</span><span class="nt"><t</span><span class="w"> </span><span class="na">t-name=</span><span class="s">"info_box"</span><span class="nt">></span><span class="w">
|
||||
</span><span class="nt"><field</span><span class="w"> </span><span class="na">name=</span><span class="s">"city"</span><span class="w"> </span><span class="na">widget=</span><span class="s">"badge"</span><span class="w"> </span><span class="nt">/></span><span class="w">
|
||||
</span><span class="nt"><ul></span><span class="w">
|
||||
</span><span class="nt"><li></span>ZIP<span class="w"> </span>:<span class="w"> </span><span class="nt"><field</span><span class="w"> </span><span class="na">name=</span><span class="s">"name"</span><span class="w"> </span><span class="nt">/></span><span class="w">
|
||||
</span><span class="nt"></li></span><span class="w">
|
||||
</span><span class="nt"><li></span>Total<span class="w"> </span>Sales:<span class="w"> </span><span class="nt"><field</span><span class="w"> </span><span class="na">name=</span><span class="s">"total_sales"</span><span class="w"> </span><span class="nt">/></span><span class="w">
|
||||
</span><span class="nt"></li></span><span class="w">
|
||||
</span><span class="nt"></ul></span><span class="w">
|
||||
</span><span class="nt"></t></span><span class="w">
|
||||
</span><span class="nt"></templates></span><span class="w">
|
||||
</span><span class="nt"></geoengine></span><span class="w">
|
||||
|
||||
</span>Thanks<span class="w"> </span>to<span class="w"> </span>that,<span class="w"> </span>you<span class="w"> </span>can<span class="w"> </span>create<span class="w"> </span>new<span class="w"> </span>records<span class="w"> </span>by<span class="w"> </span>drawing<span class="w"> </span>them<span class="w"> </span>directly<span class="w"> </span>in<span class="w"> </span>the<span class="w"> </span>geoengine<span class="w"> </span>view.<span class="w"> </span>You<span class="w"> </span>can<span class="w"> </span>also<span class="w"> </span>edit<span class="w"> </span>record<span class="w"> </span>in<span class="w"> </span>the<span class="w"> </span>same<span class="w"> </span>view.
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section" id="bug-tracker">
|
||||
<h2><a class="toc-backref" href="#toc-entry-7">Bug Tracker</a></h2>
|
||||
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/geospatial/issues">GitHub Issues</a>.
|
||||
In case of trouble, please check there if your issue has already been reported.
|
||||
If you spotted it first, help us to smash it by providing a detailed and welcomed
|
||||
<a class="reference external" href="https://github.com/OCA/geospatial/issues/new?body=module:%20base_geoengine%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
|
||||
<p>Do not contact contributors directly about support or help with technical issues.</p>
|
||||
</div>
|
||||
<div class="section" id="credits">
|
||||
<h2><a class="toc-backref" href="#toc-entry-8">Credits</a></h2>
|
||||
<div class="section" id="authors">
|
||||
<h3><a class="toc-backref" href="#toc-entry-9">Authors</a></h3>
|
||||
<ul class="simple">
|
||||
<li>Camptocamp</li>
|
||||
<li>ACSONE SA/NV</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="contributors">
|
||||
<h3><a class="toc-backref" href="#toc-entry-10">Contributors</a></h3>
|
||||
<ul class="simple">
|
||||
<li>Nicolas Bessi <<a class="reference external" href="mailto:nicolas.bessi@camptocamp.com">nicolas.bessi@camptocamp.com</a>></li>
|
||||
<li>Frederic Junod <<a class="reference external" href="mailto:frederic.junod@camptocamp.com">frederic.junod@camptocamp.com</a>></li>
|
||||
<li>Yannick Payot <<a class="reference external" href="mailto:yannick.payot@camptocamp.com">yannick.payot@camptocamp.com</a>></li>
|
||||
<li>Sandy Carter <<a class="reference external" href="mailto:sandy.carter@savoirfairelinux.com">sandy.carter@savoirfairelinux.com</a>></li>
|
||||
<li>Laurent Mignon <<a class="reference external" href="mailto:laurent.mignon@acsone.eu">laurent.mignon@acsone.eu</a>></li>
|
||||
<li>Jonathan Nemry <<a class="reference external" href="mailto:jonathan.nemry@acsone.eu">jonathan.nemry@acsone.eu</a>></li>
|
||||
<li>David Lasley <<a class="reference external" href="mailto:dave@dlasley.net">dave@dlasley.net</a>></li>
|
||||
<li>Daniel Reis <<a class="reference external" href="mailto:dgreis@sapo.pt">dgreis@sapo.pt</a>></li>
|
||||
<li>Matthieu Dietrich <<a class="reference external" href="mailto:matthieu.dietrich@camptocamp.com">matthieu.dietrich@camptocamp.com</a>></li>
|
||||
<li>Alan Ramos <<a class="reference external" href="mailto:alan.ramos@jarsa.com.mx">alan.ramos@jarsa.com.mx</a>></li>
|
||||
<li>Damien Crier <<a class="reference external" href="mailto:damien.crier@camptocamp.com">damien.crier@camptocamp.com</a>></li>
|
||||
<li>Cyril Gaudin <<a class="reference external" href="mailto:cyril.gaudin@camptocamp.com">cyril.gaudin@camptocamp.com</a>></li>
|
||||
<li>Pierre Verkest <<a class="reference external" href="mailto:pverkest@anybox.fr">pverkest@anybox.fr</a>></li>
|
||||
<li>Benjamin Willig <<a class="reference external" href="mailto:benjamin.willig@acsone.eu">benjamin.willig@acsone.eu</a>></li>
|
||||
<li>Devendra Kavthekar <<a class="reference external" href="mailto:dkatodoo@gmail.com">dkatodoo@gmail.com</a>></li>
|
||||
<li>Emanuel Cino <<a class="reference external" href="mailto:ecino@compassion.ch">ecino@compassion.ch</a>></li>
|
||||
<li>Thomas Nowicki <<a class="reference external" href="mailto:thomas.nowicki@camptocamp.com">thomas.nowicki@camptocamp.com</a>></li>
|
||||
<li>Alexandre Saunier <<a class="reference external" href="mailto:alexandre.saunier@camptocamp.com">alexandre.saunier@camptocamp.com</a>></li>
|
||||
<li>Sandip Mangukiya <<a class="reference external" href="mailto:smangukiya@opensourceintegrators.com">smangukiya@opensourceintegrators.com</a>></li>
|
||||
<li>Samuel Kouff <<a class="reference external" href="mailto:s.kouff@student.helmo.be">s.kouff@student.helmo.be</a>></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="maintainers">
|
||||
<h3><a class="toc-backref" href="#toc-entry-11">Maintainers</a></h3>
|
||||
<p>This module is maintained by the OCA.</p>
|
||||
<a class="reference external image-reference" href="https://odoo-community.org">
|
||||
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
|
||||
</a>
|
||||
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose
|
||||
mission is to support the collaborative development of Odoo features and
|
||||
promote its widespread use.</p>
|
||||
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/geospatial/tree/16.0/base_geoengine">OCA/geospatial</a> project on GitHub.</p>
|
||||
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 356 B |
|
|
@ -0,0 +1,28 @@
|
|||
chroma.js - JavaScript library for color conversions
|
||||
|
||||
Copyright (c) 2011-2015, Gregor Aisch
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. The name Gregor Aisch may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL GREGOR AISCH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,24 @@
|
|||
.geostats-legend div {
|
||||
margin:3px 10px 5px 10px;
|
||||
clear:left;
|
||||
}
|
||||
|
||||
.geostats-legend-title {
|
||||
font-weight: bold;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.geostats-legend-block {
|
||||
border: 1px solid #555555;
|
||||
display: block;
|
||||
float: left;
|
||||
height: 12px;
|
||||
margin: 0 5px 0 20px;
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
.geostats-legend-counter {
|
||||
font-size: 0.8em;
|
||||
color:#666;
|
||||
font-style: italic;
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,402 @@
|
|||
/* OpenLayers Style */
|
||||
:root,
|
||||
:host {
|
||||
--ol-background-color: white;
|
||||
--ol-accent-background-color: #f5f5f5;
|
||||
--ol-subtle-background-color: rgba(128, 128, 128, 0.25);
|
||||
--ol-partial-background-color: rgba(255, 255, 255, 0.75);
|
||||
--ol-foreground-color: #333333;
|
||||
--ol-subtle-foreground-color: #666666;
|
||||
--ol-brand-color: #00aaff;
|
||||
}
|
||||
|
||||
.ol-box {
|
||||
box-sizing: border-box;
|
||||
border-radius: 2px;
|
||||
border: 1.5px solid var(--ol-background-color);
|
||||
background-color: var(--ol-partial-background-color);
|
||||
}
|
||||
|
||||
.ol-mouse-position {
|
||||
top: 8px;
|
||||
right: 8px;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.ol-scale-line {
|
||||
background: var(--ol-partial-background-color);
|
||||
border-radius: 4px;
|
||||
bottom: 8px;
|
||||
left: 8px;
|
||||
padding: 2px;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.ol-scale-line-inner {
|
||||
border: 1px solid var(--ol-subtle-foreground-color);
|
||||
border-top: none;
|
||||
color: var(--ol-foreground-color);
|
||||
font-size: 10px;
|
||||
text-align: center;
|
||||
margin: 1px;
|
||||
will-change: contents, width;
|
||||
transition: all 0.25s;
|
||||
}
|
||||
|
||||
.ol-scale-bar {
|
||||
position: absolute;
|
||||
bottom: 8px;
|
||||
left: 8px;
|
||||
}
|
||||
|
||||
.ol-scale-bar-inner {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.ol-scale-step-marker {
|
||||
width: 1px;
|
||||
height: 15px;
|
||||
background-color: var(--ol-foreground-color);
|
||||
float: right;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.ol-scale-step-text {
|
||||
position: absolute;
|
||||
bottom: -5px;
|
||||
font-size: 10px;
|
||||
z-index: 11;
|
||||
color: var(--ol-foreground-color);
|
||||
text-shadow: -1.5px 0 var(--ol-partial-background-color),
|
||||
0 1.5px var(--ol-partial-background-color),
|
||||
1.5px 0 var(--ol-partial-background-color),
|
||||
0 -1.5px var(--ol-partial-background-color);
|
||||
}
|
||||
|
||||
.ol-scale-text {
|
||||
position: absolute;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
bottom: 25px;
|
||||
color: var(--ol-foreground-color);
|
||||
text-shadow: -1.5px 0 var(--ol-partial-background-color),
|
||||
0 1.5px var(--ol-partial-background-color),
|
||||
1.5px 0 var(--ol-partial-background-color),
|
||||
0 -1.5px var(--ol-partial-background-color);
|
||||
}
|
||||
|
||||
.ol-scale-singlebar {
|
||||
position: relative;
|
||||
height: 10px;
|
||||
z-index: 9;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid var(--ol-foreground-color);
|
||||
}
|
||||
|
||||
.ol-scale-singlebar-even {
|
||||
background-color: var(--ol-subtle-foreground-color);
|
||||
}
|
||||
|
||||
.ol-scale-singlebar-odd {
|
||||
background-color: var(--ol-background-color);
|
||||
}
|
||||
|
||||
.ol-unsupported {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ol-viewport,
|
||||
.ol-unselectable {
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
|
||||
.ol-viewport canvas {
|
||||
all: unset;
|
||||
}
|
||||
|
||||
.ol-selectable {
|
||||
-webkit-touch-callout: default;
|
||||
-webkit-user-select: text;
|
||||
-moz-user-select: text;
|
||||
user-select: text;
|
||||
}
|
||||
|
||||
.ol-grabbing {
|
||||
cursor: -webkit-grabbing;
|
||||
cursor: -moz-grabbing;
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
.ol-grab {
|
||||
cursor: move;
|
||||
cursor: -webkit-grab;
|
||||
cursor: -moz-grab;
|
||||
cursor: grab;
|
||||
}
|
||||
|
||||
.ol-control {
|
||||
position: absolute;
|
||||
background-color: var(--ol-subtle-background-color);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.ol-zoom {
|
||||
top: 0.5em;
|
||||
left: 0.5em;
|
||||
}
|
||||
|
||||
.draw-control {
|
||||
top: 4em;
|
||||
left: 0.5em;
|
||||
}
|
||||
|
||||
.select-control {
|
||||
top: 8em;
|
||||
left: 0.5em;
|
||||
}
|
||||
|
||||
.edit-control {
|
||||
top: 6em;
|
||||
left: 0.5em;
|
||||
}
|
||||
|
||||
#map-legend {
|
||||
bottom: 17em;
|
||||
right: 24em;
|
||||
z-index: 1054;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.legend {
|
||||
margin-bottom: 15px;
|
||||
display: none;
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.selected-control > i {
|
||||
color: #71639e;
|
||||
}
|
||||
|
||||
.ol-rotate {
|
||||
top: 0.5em;
|
||||
right: 0.5em;
|
||||
transition: opacity 0.25s linear, visibility 0s linear;
|
||||
}
|
||||
|
||||
.ol-rotate.ol-hidden {
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: opacity 0.25s linear, visibility 0s linear 0.25s;
|
||||
}
|
||||
|
||||
.ol-zoom-extent {
|
||||
top: 4.643em;
|
||||
left: 0.5em;
|
||||
}
|
||||
|
||||
.ol-full-screen {
|
||||
right: 0.5em;
|
||||
top: 0.5em;
|
||||
}
|
||||
|
||||
.ol-control button {
|
||||
display: block;
|
||||
margin: 1px;
|
||||
padding: 0;
|
||||
color: var(--ol-subtle-foreground-color);
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
font-size: inherit;
|
||||
text-align: center;
|
||||
height: 1.375em;
|
||||
width: 1.375em;
|
||||
line-height: 0.4em;
|
||||
background-color: var(--ol-background-color);
|
||||
border: none;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.ol-control button::-moz-focus-inner {
|
||||
border: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.ol-zoom-extent button {
|
||||
line-height: 1.4em;
|
||||
}
|
||||
|
||||
.ol-compass {
|
||||
display: block;
|
||||
font-weight: normal;
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
.ol-touch .ol-control button {
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
.ol-touch .ol-zoom-extent {
|
||||
top: 5.5em;
|
||||
}
|
||||
|
||||
.ol-control button:hover,
|
||||
.ol-control button:focus {
|
||||
text-decoration: none;
|
||||
outline: 1px solid var(--ol-subtle-foreground-color);
|
||||
color: var(--ol-foreground-color);
|
||||
}
|
||||
|
||||
.ol-zoom .ol-zoom-in {
|
||||
border-radius: 2px 2px 0 0;
|
||||
}
|
||||
|
||||
.ol-zoom .ol-zoom-out {
|
||||
border-radius: 0 0 2px 2px;
|
||||
}
|
||||
|
||||
.ol-attribution {
|
||||
text-align: right;
|
||||
bottom: 0.5em;
|
||||
right: 0.5em;
|
||||
max-width: calc(100% - 1.3em);
|
||||
display: flex;
|
||||
flex-flow: row-reverse;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.ol-attribution a {
|
||||
color: var(--ol-subtle-foreground-color);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.ol-attribution ul {
|
||||
margin: 0;
|
||||
padding: 1px 0.5em;
|
||||
color: var(--ol-foreground-color);
|
||||
text-shadow: 0 0 2px var(--ol-background-color);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.ol-attribution li {
|
||||
display: inline;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.ol-attribution li:not(:last-child):after {
|
||||
content: " ";
|
||||
}
|
||||
|
||||
.ol-attribution img {
|
||||
max-height: 2em;
|
||||
max-width: inherit;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.ol-attribution button {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.ol-attribution.ol-collapsed ul {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ol-attribution:not(.ol-collapsed) {
|
||||
background: var(--ol-partial-background-color);
|
||||
}
|
||||
|
||||
.ol-attribution.ol-uncollapsible {
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
border-radius: 4px 0 0;
|
||||
}
|
||||
|
||||
.ol-attribution.ol-uncollapsible img {
|
||||
margin-top: -0.2em;
|
||||
max-height: 1.6em;
|
||||
}
|
||||
|
||||
.ol-attribution.ol-uncollapsible button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ol-zoomslider {
|
||||
top: 4.5em;
|
||||
left: 0.5em;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
.ol-zoomslider button {
|
||||
position: relative;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
.ol-touch .ol-zoomslider {
|
||||
top: 5.5em;
|
||||
}
|
||||
|
||||
.ol-overviewmap {
|
||||
left: 0.5em;
|
||||
bottom: 0.5em;
|
||||
}
|
||||
|
||||
.ol-overviewmap.ol-uncollapsible {
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
border-radius: 0 4px 0 0;
|
||||
}
|
||||
|
||||
.ol-overviewmap .ol-overviewmap-map,
|
||||
.ol-overviewmap button {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.ol-overviewmap .ol-overviewmap-map {
|
||||
border: 1px solid var(--ol-subtle-foreground-color);
|
||||
height: 150px;
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
.ol-overviewmap:not(.ol-collapsed) button {
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.ol-overviewmap.ol-collapsed .ol-overviewmap-map,
|
||||
.ol-overviewmap.ol-uncollapsible button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ol-overviewmap:not(.ol-collapsed) {
|
||||
background: var(--ol-subtle-background-color);
|
||||
}
|
||||
|
||||
.ol-overviewmap-box {
|
||||
border: 1.5px dotted var(--ol-subtle-foreground-color);
|
||||
}
|
||||
|
||||
.ol-overviewmap .ol-overviewmap-box:hover {
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
.ol-clear {
|
||||
top: 65px;
|
||||
left: 0.5em;
|
||||
}
|
||||
|
||||
.form-check {
|
||||
display: block;
|
||||
min-height: 1.625rem;
|
||||
padding-left: 0;
|
||||
margin-bottom: 0.125rem;
|
||||
margin-left: 1.5em;
|
||||
}
|
||||
|
||||
#popup-closer {
|
||||
cursor: pointer;
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.2 KiB |
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"globals": {
|
||||
"$": false,
|
||||
"_": false,
|
||||
"ol": false,
|
||||
"chroma": false,
|
||||
"geostats": false
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/** @odoo-module */
|
||||
|
||||
import {reactive} from "@odoo/owl";
|
||||
|
||||
class RasterLayersStore {
|
||||
/**
|
||||
* Set raster layers to the store.
|
||||
* @param {*} rasters
|
||||
*/
|
||||
setRasters(rasters) {
|
||||
const newRasters = rasters.map((raster) => {
|
||||
Object.defineProperty(raster, "isVisible", {
|
||||
value: false,
|
||||
writable: true,
|
||||
});
|
||||
raster.isVisible = !raster.overlay;
|
||||
return raster;
|
||||
});
|
||||
this.rasters = newRasters;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called when a raster layer is changed. This will notify observers of the change.
|
||||
* @param {*} newRastersLayer
|
||||
*/
|
||||
onRasterLayerChanged(newRastersLayer) {
|
||||
this.rasters = newRastersLayer;
|
||||
}
|
||||
|
||||
get rastersLayers() {
|
||||
return this.rasters;
|
||||
}
|
||||
|
||||
getRaster(id) {
|
||||
return this.rasters.find((el) => el.id === id);
|
||||
}
|
||||
|
||||
get count() {
|
||||
return this.rasters.length;
|
||||
}
|
||||
}
|
||||
export const rasterLayersStore = reactive(new RasterLayersStore());
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/** @odoo-module */
|
||||
import {reactive} from "@odoo/owl";
|
||||
|
||||
class VectorLayersStore {
|
||||
/**
|
||||
* Set vector layers to the store.
|
||||
* @param {*} rasters
|
||||
*/
|
||||
setVectors(vectors) {
|
||||
const newVectors = vectors.map((vector) => {
|
||||
Object.defineProperty(vector, "isVisible", {
|
||||
value: false,
|
||||
writable: true,
|
||||
});
|
||||
if (vector.active_on_startup) {
|
||||
vector.isVisible = true;
|
||||
}
|
||||
return vector;
|
||||
});
|
||||
this.vectors = newVectors;
|
||||
}
|
||||
|
||||
get vectorsLayers() {
|
||||
return this.vectors;
|
||||
}
|
||||
|
||||
getVector(resId) {
|
||||
return this.vectors.find((el) => el.resId === resId);
|
||||
}
|
||||
|
||||
get count() {
|
||||
return this.vectors.length;
|
||||
}
|
||||
}
|
||||
|
||||
export const vectorLayersStore = reactive(new VectorLayersStore());
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
/** @odoo-module */
|
||||
|
||||
/**
|
||||
* Copyright 2023 ACSONE SA/NV
|
||||
*/
|
||||
|
||||
import {addFieldDependencies} from "@web/views/utils";
|
||||
import {Field} from "@web/views/fields/field";
|
||||
import {Widget} from "@web/views/widgets/widget";
|
||||
import {XMLParser} from "@web/core/utils/xml";
|
||||
import {_lt} from "@web/core/l10n/translation";
|
||||
|
||||
export const INFO_BOX_ATTRIBUTE = "info_box";
|
||||
|
||||
export class GeoengineArchParser extends XMLParser {
|
||||
/**
|
||||
* Allow you to browse and process the xml template of the geoengine view.
|
||||
* @param {*} arch
|
||||
* @param {*} models
|
||||
* @param {*} modelName
|
||||
* @returns {Object}
|
||||
*/
|
||||
parse(arch, models, modelName) {
|
||||
const xmlDoc = this.parseXML(arch);
|
||||
const templateDocs = {};
|
||||
const fieldNodes = {};
|
||||
const jsClass = xmlDoc.getAttribute("js_class");
|
||||
const activeFields = {};
|
||||
const geoengineAttr = {};
|
||||
|
||||
this.visitXML(xmlDoc, (node) => {
|
||||
if (["geoengine"].includes(node.tagName)) {
|
||||
geoengineAttr.editable = Boolean(
|
||||
Number(xmlDoc.getAttribute("editable"))
|
||||
);
|
||||
}
|
||||
// Get the info box template
|
||||
if (node.hasAttribute("t-name")) {
|
||||
templateDocs[node.getAttribute("t-name")] = node;
|
||||
return;
|
||||
}
|
||||
if (node.tagName === "field") {
|
||||
const fieldInfo = Field.parseFieldNode(
|
||||
node,
|
||||
models,
|
||||
modelName,
|
||||
"geoengine",
|
||||
jsClass
|
||||
);
|
||||
const name = fieldInfo.name;
|
||||
fieldNodes[name] = fieldInfo;
|
||||
node.setAttribute("field_id", name);
|
||||
|
||||
addFieldDependencies(
|
||||
activeFields,
|
||||
models[modelName],
|
||||
fieldInfo.FieldComponent.fieldDependencies
|
||||
);
|
||||
}
|
||||
|
||||
if (node.tagName === "widget") {
|
||||
const {WidgetComponent} = Widget.parseWidgetNode(node);
|
||||
addFieldDependencies(
|
||||
activeFields,
|
||||
models[modelName],
|
||||
WidgetComponent.fieldDependencies
|
||||
);
|
||||
}
|
||||
});
|
||||
const infoBox = templateDocs[INFO_BOX_ATTRIBUTE];
|
||||
if (!infoBox) {
|
||||
throw new Error(_lt(`Missing ${INFO_BOX_ATTRIBUTE} template.`));
|
||||
}
|
||||
|
||||
for (const [key, field] of Object.entries(fieldNodes)) {
|
||||
activeFields[key] = field;
|
||||
}
|
||||
|
||||
return {
|
||||
arch,
|
||||
templateDocs,
|
||||
activeFields,
|
||||
fieldNodes,
|
||||
...geoengineAttr,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/** @odoo-module */
|
||||
|
||||
/**
|
||||
* Copyright 2023 ACSONE SA/NV
|
||||
*/
|
||||
|
||||
import {ViewCompiler} from "@web/views/view_compiler";
|
||||
|
||||
export class GeoengineCompiler extends ViewCompiler {}
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
/** @odoo-module */
|
||||
|
||||
/**
|
||||
* Copyright 2023 ACSONE SA/NV
|
||||
*/
|
||||
|
||||
import {Layout} from "@web/search/layout";
|
||||
import {useModel} from "@web/views/model";
|
||||
import {usePager} from "@web/search/pager_hook";
|
||||
import {useOwnedDialogs, useService} from "@web/core/utils/hooks";
|
||||
import {FormViewDialog} from "@web/views/view_dialogs/form_view_dialog";
|
||||
import {WarningDialog} from "@web/core/errors/error_dialogs";
|
||||
import {Component, useState} from "@odoo/owl";
|
||||
|
||||
export class GeoengineController extends Component {
|
||||
/**
|
||||
* Setup the controller by using the useModel hook.
|
||||
*/
|
||||
setup() {
|
||||
this.state = useState({isSavedOrDiscarded: false});
|
||||
this.actionService = useService("action");
|
||||
this.view = useService("view");
|
||||
this.addDialog = useOwnedDialogs();
|
||||
this.editable = this.props.archInfo.editable;
|
||||
this.model = useModel(this.props.Model, {
|
||||
activeFields: this.props.archInfo.activeFields,
|
||||
resModel: this.props.resModel,
|
||||
fields: this.props.fields,
|
||||
limit: this.props.limit,
|
||||
});
|
||||
|
||||
/**
|
||||
* Allow you to display records on the map thanks to the paging located
|
||||
* at the top right of the screen.
|
||||
*/
|
||||
usePager(() => {
|
||||
const list = this.model.root;
|
||||
const {count, limit, offset} = list;
|
||||
return {
|
||||
offset: offset,
|
||||
limit: limit,
|
||||
total: count,
|
||||
onUpdate: async ({offset, limit}) => {
|
||||
await list.load({limit, offset});
|
||||
this.render(true);
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Allow you to open the form editing view for the filled-in model.
|
||||
* @param {*} resModel
|
||||
* @param {*} resId
|
||||
*/
|
||||
async openRecord(resModel, resId) {
|
||||
const {views} = await this.view.loadViews({resModel, views: [[false, "form"]]});
|
||||
this.actionService.doAction({
|
||||
type: "ir.actions.act_window",
|
||||
res_model: resModel,
|
||||
views: [[views.form.id, "form"]],
|
||||
res_id: resId,
|
||||
target: "new",
|
||||
context: {edit: false, create: false},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* When you finished drawing a new shape, this method is called to open form view and create the record.
|
||||
* @param {*} resModel
|
||||
* @param {*} field
|
||||
* @param {*} value
|
||||
*/
|
||||
async createRecord(resModel, field, value) {
|
||||
const {views} = await this.view.loadViews({resModel, views: [[false, "form"]]});
|
||||
const context = {};
|
||||
context[`default_${field}`] = value;
|
||||
|
||||
this.addDialog(FormViewDialog, {
|
||||
resModel: resModel,
|
||||
title: this.env._t("New record"),
|
||||
viewId: views.form.id,
|
||||
context,
|
||||
onRecordSaved: async () => await this.onSaveRecord(),
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called when you have finished to create a new record.
|
||||
*/
|
||||
async onSaveRecord() {
|
||||
const offset = this.model.root.count + 1;
|
||||
await this.model.root.load({offset});
|
||||
this.render(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called when you click on save button after edit a spatial representation.
|
||||
*/
|
||||
async onClickSave() {
|
||||
await this.model.root.editedRecord.save();
|
||||
this.state.isSavedOrDiscarded = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called when you click on discard button after edit a spatial representation.
|
||||
*/
|
||||
async onClickDiscard() {
|
||||
await this.model.root.editedRecord.discard();
|
||||
this.state.isSavedOrDiscarded = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* When you have finished edtiting a spatial representation, this method is called to update the value.
|
||||
* @param {*} value
|
||||
*/
|
||||
async updateRecord(value) {
|
||||
this.state.isSavedOrDiscarded = false;
|
||||
const newValue = {};
|
||||
const key = Object.keys(this.model.root.fields).find(
|
||||
(el) => this.model.root.fields[el].geo_type !== undefined
|
||||
);
|
||||
newValue[key] = value;
|
||||
await this.model.root.editedRecord.update(newValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method warns you if you start creating a record without having displayed the others.
|
||||
*/
|
||||
onDrawStart() {
|
||||
const {count, records} = this.model.root;
|
||||
if (records.length < count) {
|
||||
this.addDialog(WarningDialog, {
|
||||
title: this.env._t("Warning"),
|
||||
message: this.env._t(
|
||||
"You are about to create a new record without having displayed all the others. A risk of overlap could occur. Would you like to continue ?"
|
||||
),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GeoengineController.template = "base_geoengine.GeoengineController";
|
||||
GeoengineController.components = {Layout};
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<templates>
|
||||
<t t-name="base_geoengine.GeoengineController" owl="1">
|
||||
<Layout display="props.display" className="'h-100'">
|
||||
<t t-set-slot="layout-buttons">
|
||||
<t t-if="model.root.editedRecord">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-primary o_list_button_save"
|
||||
data-hotkey="s"
|
||||
t-on-click.stop="onClickSave"
|
||||
>
|
||||
Save
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-secondary o_list_button_discard"
|
||||
data-hotkey="j"
|
||||
t-on-click="onClickDiscard"
|
||||
>
|
||||
Discard
|
||||
</button>
|
||||
</t>
|
||||
</t>
|
||||
<t
|
||||
t-component="props.Renderer"
|
||||
isSavedOrDiscarded="state.isSavedOrDiscarded"
|
||||
archInfo="props.archInfo"
|
||||
data="model.root"
|
||||
editable="editable"
|
||||
openRecord.bind="openRecord"
|
||||
updateRecord.bind="updateRecord"
|
||||
onClickDiscard.bind="onClickDiscard"
|
||||
createRecord.bind="createRecord"
|
||||
onDrawStart.bind="onDrawStart"
|
||||
/>
|
||||
</Layout>
|
||||
</t>
|
||||
</templates>
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/** @odoo-module */
|
||||
|
||||
/**
|
||||
* Copyright 2023 ACSONE SA/NV
|
||||
*/
|
||||
|
||||
import {Field} from "@web/views/fields/field";
|
||||
import {GeoengineCompiler} from "../geoengine_compiler.esm";
|
||||
import {INFO_BOX_ATTRIBUTE} from "../geoengine_arch_parser.esm";
|
||||
import {registry} from "@web/core/registry";
|
||||
import {useViewCompiler} from "@web/views/view_compiler";
|
||||
import {Component, onWillUpdateProps} from "@odoo/owl";
|
||||
|
||||
const formatters = registry.category("formatters");
|
||||
|
||||
function getValue(record, fieldName) {
|
||||
const field = record.fields[fieldName];
|
||||
const value = record._values[fieldName];
|
||||
const formatter = formatters.get(field.type, String);
|
||||
return formatter(value, {field, data: record._values});
|
||||
}
|
||||
|
||||
export class GeoengineRecord extends Component {
|
||||
/**
|
||||
* Setup the record by compiling the arch and the info-box template.
|
||||
*/
|
||||
setup() {
|
||||
const {archInfo, templates} = this.props;
|
||||
const {arch} = archInfo;
|
||||
const ViewCompiler = this.constructor.Compiler;
|
||||
this.templates = useViewCompiler(ViewCompiler, arch, templates);
|
||||
this.createRecord(this.props);
|
||||
onWillUpdateProps(this.createRecord);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create record with formatter.
|
||||
* @param {*} props
|
||||
*/
|
||||
createRecord(props) {
|
||||
const {record} = props;
|
||||
this.record = Object.create(null);
|
||||
for (const fieldName in record._values) {
|
||||
this.record[fieldName] = {
|
||||
get value() {
|
||||
return getValue(record, fieldName);
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GeoengineRecord.template = "base_geoengine_GeoengineRecord";
|
||||
GeoengineRecord.Compiler = GeoengineCompiler;
|
||||
GeoengineRecord.components = {Field};
|
||||
GeoengineRecord.INFO_BOX_ATTRIBUTE = INFO_BOX_ATTRIBUTE;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<templates xml:space="preserve">
|
||||
<t t-name="base_geoengine_GeoengineRecord" owl="1">
|
||||
<div>
|
||||
<t t-call="{{ templates[this.constructor.INFO_BOX_ATTRIBUTE] }}" />
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,67 @@
|
|||
#olmap {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.map_container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.view {
|
||||
max-height: 90%;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
.menu {
|
||||
z-index: 2;
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
padding-right: 0.5rem;
|
||||
padding-bottom: 3rem;
|
||||
padding-left: 2.5rem;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.ol-popup {
|
||||
position: absolute;
|
||||
background-color: white;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2);
|
||||
padding: 15px;
|
||||
border-radius: 10px;
|
||||
border: 1px solid #cccccc;
|
||||
bottom: 12px;
|
||||
left: -50px;
|
||||
min-width: 280px;
|
||||
}
|
||||
.ol-popup:after,
|
||||
.ol-popup:before {
|
||||
top: 100%;
|
||||
border: solid transparent;
|
||||
content: " ";
|
||||
height: 0;
|
||||
width: 0;
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
}
|
||||
.ol-popup:after {
|
||||
border-top-color: white;
|
||||
border-width: 10px;
|
||||
left: 48px;
|
||||
margin-left: -10px;
|
||||
}
|
||||
.ol-popup:before {
|
||||
border-top-color: #cccccc;
|
||||
border-width: 11px;
|
||||
left: 48px;
|
||||
margin-left: -11px;
|
||||
}
|
||||
.ol-popup-closer {
|
||||
text-decoration: none;
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
right: 8px;
|
||||
}
|
||||
.ol-popup-closer:after {
|
||||
content: "✖";
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<templates xml:space="preserve">
|
||||
<t t-name="base_geoengine.GeoengineRenderer" owl="1">
|
||||
<div class="d-flex view w-100">
|
||||
<LayersPanel model="props.data.resModel" vectorModel="vectorModel.root" />
|
||||
<div class="map_container">
|
||||
<div id="olmap" />
|
||||
</div>
|
||||
<RecordsPanel
|
||||
list="props.data"
|
||||
onDisplayPopupRecord.bind="onDisplayPopupRecord"
|
||||
zoomOnFeature.bind="zoomOnFeature"
|
||||
zoomOutOnFeature.bind="getOriginalZoom"
|
||||
/>
|
||||
</div>
|
||||
<div id="popup" class="ol-popup">
|
||||
<div
|
||||
id="popup-closer"
|
||||
class="ol-popup-closer text-primary"
|
||||
t-on-click="clickToHidePopup"
|
||||
/>
|
||||
<div id="popup-content" />
|
||||
<div class="row d-flex justify-content-center">
|
||||
<button
|
||||
t-on-click="onInfoBoxClicked"
|
||||
class="btn btn-secondary border w-50"
|
||||
>OPEN</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="map-legend" class="ol-control" />
|
||||
</t>
|
||||
</templates>
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/** @odoo-module */
|
||||
|
||||
/**
|
||||
* Copyright 2023 ACSONE SA/NV
|
||||
*/
|
||||
|
||||
import {_lt} from "@web/core/l10n/translation";
|
||||
import {GeoengineController} from "./geoengine_controller/geoengine_controller.esm";
|
||||
import {GeoengineRenderer} from "./geoengine_renderer/geoengine_renderer.esm";
|
||||
import {GeoengineArchParser} from "./geoengine_arch_parser.esm";
|
||||
import {GeoengineCompiler} from "./geoengine_compiler.esm";
|
||||
import {RelationalModel} from "@web/views/relational_model";
|
||||
import {registry} from "@web/core/registry";
|
||||
|
||||
export const geoengineView = {
|
||||
type: "geoengine",
|
||||
display_name: _lt("Geoengine"),
|
||||
icon: "fa fa-map-o",
|
||||
multiRecord: true,
|
||||
ArchParser: GeoengineArchParser,
|
||||
Controller: GeoengineController,
|
||||
Model: RelationalModel,
|
||||
Renderer: GeoengineRenderer,
|
||||
Compiler: GeoengineCompiler,
|
||||
|
||||
props: (genericProps, view) => {
|
||||
const {ArchParser} = view;
|
||||
const {arch, relatedModels, resModel} = genericProps;
|
||||
const archInfo = new ArchParser().parse(arch, relatedModels, resModel);
|
||||
|
||||
return {
|
||||
...genericProps,
|
||||
Model: view.Model,
|
||||
Renderer: view.Renderer,
|
||||
archInfo,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
registry.category("views").add("geoengine", geoengineView);
|
||||
|
|
@ -0,0 +1,246 @@
|
|||
/** @odoo-module */
|
||||
|
||||
/**
|
||||
* Copyright 2023 ACSONE SA/NV
|
||||
*/
|
||||
|
||||
import {CheckBox} from "@web/core/checkbox/checkbox";
|
||||
import {rasterLayersStore} from "../../../raster_layers_store.esm";
|
||||
import {vectorLayersStore} from "../../../vector_layers_store.esm";
|
||||
import {useOwnedDialogs, useService} from "@web/core/utils/hooks";
|
||||
import {DomainSelectorGeoFieldDialog} from "../../../widgets/domain_selector_geo_field/domain_selector_geo_field_dialog/domain_selector_geo_field_dialog.esm";
|
||||
import {FormViewDialog} from "@web/views/view_dialogs/form_view_dialog";
|
||||
import {useSortable} from "@web/core/utils/sortable";
|
||||
|
||||
import {Component, onWillStart, useRef, useState} from "@odoo/owl";
|
||||
|
||||
export class LayersPanel extends Component {
|
||||
setup() {
|
||||
this.orm = useService("orm");
|
||||
this.actionService = useService("action");
|
||||
this.view = useService("view");
|
||||
this.rpc = useService("rpc");
|
||||
this.user = useService("user");
|
||||
this.state = useState({geoengineLayers: {}, isFolded: false});
|
||||
this.addDialog = useOwnedDialogs();
|
||||
let dataRowId = "";
|
||||
|
||||
/**
|
||||
* Call the model method "get_geoengine_layers" to get all the layers
|
||||
* in the database and add them to the store.
|
||||
*/
|
||||
onWillStart(async () => {
|
||||
await Promise.all([this.loadIsAdmin(), this.loadLayers()]);
|
||||
/**
|
||||
* Get resId of records to allow resequence of elements.
|
||||
*/
|
||||
this.state.geoengineLayers.actives.forEach((val) => {
|
||||
const element = this.props.vectorModel.records.find(
|
||||
(el) => el.resId === val.id
|
||||
);
|
||||
const obj = {id: element.id, resId: element.resId};
|
||||
Object.assign(val, obj);
|
||||
});
|
||||
// Set layers in the store
|
||||
rasterLayersStore.setRasters(this.state.geoengineLayers.backgrounds);
|
||||
vectorLayersStore.setVectors(this.state.geoengineLayers.actives);
|
||||
this.numberOfLayers = vectorLayersStore.count + rasterLayersStore.count;
|
||||
});
|
||||
|
||||
/**
|
||||
* Allows you to change the priority of the layer by sliding them over each other
|
||||
*/
|
||||
useSortable({
|
||||
ref: useRef("root"),
|
||||
elements: ".item",
|
||||
handle: ".fa-sort",
|
||||
onDragStart({element}) {
|
||||
dataRowId = element.dataset.id;
|
||||
},
|
||||
onDrop: (params) => this.sort(dataRowId, params),
|
||||
});
|
||||
}
|
||||
|
||||
async loadIsAdmin() {
|
||||
return this.user
|
||||
.hasGroup("base_geoengine.group_geoengine_admin")
|
||||
.then((result) => {
|
||||
this.isGeoengineAdmin = result;
|
||||
});
|
||||
}
|
||||
|
||||
async loadLayers() {
|
||||
return this.orm
|
||||
.call(this.props.model, "get_geoengine_layers", [])
|
||||
.then((result) => {
|
||||
this.state.geoengineLayers = result;
|
||||
});
|
||||
}
|
||||
|
||||
async sort(dataRowId, {previous}) {
|
||||
const refId = previous ? previous.dataset.id : null;
|
||||
this.resquence(dataRowId, refId);
|
||||
if (this.isGeoengineAdmin) {
|
||||
await this.resequenceAndUpdate(dataRowId, refId);
|
||||
} else {
|
||||
this.state.geoengineLayers.actives.forEach((element, index) => {
|
||||
this.onVectorChange(element, "onSequenceChanged", index + 1);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resequence the order of layers but not update them (When a user modify them).
|
||||
* @param {*} dataRowId
|
||||
* @param {*} refId
|
||||
*/
|
||||
resquence(dataRowId, refId) {
|
||||
const fromIndex = this.state.geoengineLayers.actives.findIndex(
|
||||
(r) => r.id === dataRowId
|
||||
);
|
||||
let toIndex = 0;
|
||||
if (refId !== null) {
|
||||
const targetIndex = this.state.geoengineLayers.actives.findIndex(
|
||||
(r) => r.id === refId
|
||||
);
|
||||
toIndex = fromIndex > targetIndex ? targetIndex + 1 : targetIndex;
|
||||
}
|
||||
const [record] = this.state.geoengineLayers.actives.splice(fromIndex, 1);
|
||||
this.state.geoengineLayers.actives.splice(toIndex, 0, record);
|
||||
}
|
||||
/**
|
||||
* Resequence the order of layers and update them (When an admin modify them).
|
||||
* @param {*} dataRowId
|
||||
* @param {*} refId
|
||||
*/
|
||||
async resequenceAndUpdate(dataRowId, refId) {
|
||||
this.resequencePromise = this.props.vectorModel.resequence(dataRowId, refId, {
|
||||
handleField: "sequence",
|
||||
});
|
||||
await this.resequencePromise;
|
||||
this.props.vectorModel.records.forEach((element) => {
|
||||
this.onVectorChange(element, "onSequenceChanged", element.data.sequence);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called when a raster layer is changed. The raster layer is set to visible and then
|
||||
* the method notifies the store of the change.
|
||||
* @param {*} layer
|
||||
*/
|
||||
onRasterChange(layer) {
|
||||
const indexRaster = rasterLayersStore.rastersLayers.findIndex(
|
||||
(raster) => raster.name === layer.name
|
||||
);
|
||||
const newRasters = rasterLayersStore.rastersLayers.map((item, index) => {
|
||||
if (index !== indexRaster) {
|
||||
item.isVisible = false;
|
||||
} else {
|
||||
item.isVisible = true;
|
||||
}
|
||||
return item;
|
||||
});
|
||||
rasterLayersStore.onRasterLayerChanged(newRasters);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called when a vector layer is changed. The vector layer is changed by an action and then
|
||||
* the method notifies the store of the change.
|
||||
* @param {*} layer
|
||||
* @param {*} action
|
||||
* @param {*} value
|
||||
*/
|
||||
async onVectorChange(layer, action, value) {
|
||||
vectorLayersStore.vectorsLayers.forEach((layer) => {
|
||||
layer.onDomainChanged = false;
|
||||
layer.onLayerChanged = false;
|
||||
layer.onSequenceChanged = false;
|
||||
});
|
||||
const vectorLayer = vectorLayersStore.getVector(layer.resId);
|
||||
switch (action) {
|
||||
case "onDomainChanged":
|
||||
Object.assign(vectorLayer, {
|
||||
model_domain: value,
|
||||
onDomainChanged: true,
|
||||
});
|
||||
break;
|
||||
case "onVisibleChanged":
|
||||
Object.assign(vectorLayer, {isVisible: value, onVisibleChanged: true});
|
||||
break;
|
||||
case "onLayerChanged":
|
||||
const geo_field_id = await this.orm.call(
|
||||
vectorLayer.resModel,
|
||||
"set_field_real_name",
|
||||
[value.geo_field_id]
|
||||
);
|
||||
const attribute_field_id = await this.orm.call(
|
||||
vectorLayer.resModel,
|
||||
"set_field_real_name",
|
||||
[value.attribute_field_id]
|
||||
);
|
||||
value.geo_field_id = geo_field_id;
|
||||
value.attribute_field_id = attribute_field_id;
|
||||
Object.assign(vectorLayer, {...value, onLayerChanged: true});
|
||||
break;
|
||||
case "onSequenceChanged":
|
||||
if (vectorLayer !== undefined) {
|
||||
Object.assign(vectorLayer, {
|
||||
sequence: value,
|
||||
onSequenceChanged: true,
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
onEditFilterButtonSelected(vector) {
|
||||
this.addDialog(DomainSelectorGeoFieldDialog, {
|
||||
resModel: vector.model,
|
||||
initialValue: vector.model_domain,
|
||||
readonly: false,
|
||||
isDebugMode: Boolean(this.env.debug),
|
||||
model: vector,
|
||||
onSelected: (value) => this.onEditFilterDomainChanged(vector, value),
|
||||
title: this.env._t("Domain editing"),
|
||||
});
|
||||
}
|
||||
|
||||
async onEditFilterDomainChanged(vector, value) {
|
||||
if (this.isGeoengineAdmin) {
|
||||
const record = this.props.vectorModel.records.find(
|
||||
(el) => el.resId === vector.resId
|
||||
);
|
||||
await record.update({model_domain: value});
|
||||
await record.save();
|
||||
}
|
||||
this.onVectorChange(vector, "onDomainChanged", value);
|
||||
}
|
||||
|
||||
async onEditButtonSelected(vector) {
|
||||
const view = await this.rpc("/web/action/load", {
|
||||
action_id: "base_geoengine.geo_vector_geoengine_view_action",
|
||||
});
|
||||
|
||||
this.addDialog(FormViewDialog, {
|
||||
resModel: vector.resModel,
|
||||
title: this.env._t("Editing vector layer"),
|
||||
viewId: view.view_id[0],
|
||||
resId: vector.resId,
|
||||
onRecordSaved: (record) =>
|
||||
this.onVectorChange(vector, "onLayerChanged", record.data),
|
||||
});
|
||||
}
|
||||
/**
|
||||
* This method allows you to open/close the panel.
|
||||
*/
|
||||
fold() {
|
||||
this.state.isFolded = !this.state.isFolded;
|
||||
}
|
||||
}
|
||||
|
||||
LayersPanel.template = "base_geoengine.LayersPanel";
|
||||
LayersPanel.props = {
|
||||
model: {type: String, optional: false},
|
||||
vectorModel: {type: Object, optional: false},
|
||||
};
|
||||
LayersPanel.components = {CheckBox};
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
.btn-edit {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
.o_layer_panel {
|
||||
width: 250px;
|
||||
font-size: 1em;
|
||||
padding-left: 1rem;
|
||||
}
|
||||
|
||||
.raster {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.fold {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
|
||||
.unfold {
|
||||
font-size: 1.3em;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.o_layer_panel_fold {
|
||||
width: 50px;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
background-color: #e9ecefd9;
|
||||
}
|
||||
|
||||
.title-panel {
|
||||
writing-mode: vertical-rl;
|
||||
text-orientation: mixed;
|
||||
font-size: 1.3em;
|
||||
margin-top: 1rem;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<templates>
|
||||
<t t-name="base_geoengine.LayersPanel" owl="1">
|
||||
<div
|
||||
class="menu border-end"
|
||||
t-attf-class="{{ state.isFolded ? 'o_layer_panel_fold ' : 'o_layer_panel bg-view' }}"
|
||||
>
|
||||
<div
|
||||
class="w-100 d-flex"
|
||||
t-attf-class="{{ state.isFolded ? 'justify-content-center' : 'justify-content-end'}}"
|
||||
>
|
||||
<button
|
||||
class="btn"
|
||||
t-attf-class="{{state.isFolded ? 'unfold text-900': 'fold'}}"
|
||||
t-on-click="fold"
|
||||
>
|
||||
<i class="fa fa-arrows-h" role="img" />
|
||||
</button>
|
||||
</div>
|
||||
<div t-if="!state.isFolded">
|
||||
<section class="o_search_panel_section">
|
||||
<header
|
||||
class="o_search_panel_section_header text-uppercase cursor-default"
|
||||
>
|
||||
<span class="fs-6 fw-bold">Vectors</span>
|
||||
</header>
|
||||
<div t-ref="root" class="root">
|
||||
<ul class="list p-0">
|
||||
<li
|
||||
t-foreach="state.geoengineLayers.actives"
|
||||
t-as="vector"
|
||||
t-key="vector.resId"
|
||||
class="item d-flex align-items-center"
|
||||
t-att-data-id="vector.id"
|
||||
>
|
||||
<i class="fa fa-sort m-3" />
|
||||
<div
|
||||
class="d-flex justify-content-between align-items-center"
|
||||
>
|
||||
<CheckBox
|
||||
value="vector.isVisible"
|
||||
t-on-change="() => this.onVectorChange(vector, 'onVisibleChanged', !vector.isVisible)"
|
||||
>
|
||||
<t t-esc="vector.name" />
|
||||
</CheckBox>
|
||||
<button
|
||||
t-if="vector.model_id !== false"
|
||||
class="btn btn-edit"
|
||||
t-on-click.prevent="() => this.onEditFilterButtonSelected(vector)"
|
||||
>
|
||||
<i class="fa fa-filter text-primary" />
|
||||
</button>
|
||||
<button
|
||||
t-if="isGeoengineAdmin"
|
||||
class="btn btn-edit"
|
||||
t-on-click.prevent="() => this.onEditButtonSelected(vector)"
|
||||
>
|
||||
<i class="fa fa-edit text-primary" />
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
<section class="o_search_panel_section">
|
||||
<header
|
||||
class="o_search_panel_section_header pt-4 pb-2 text-uppercase cursor-default"
|
||||
>
|
||||
<span class="fs-6 fw-bold">Rasters</span>
|
||||
</header>
|
||||
<ul class="raster list-group d-block o_search_panel_field">
|
||||
<li
|
||||
t-foreach="state.geoengineLayers.backgrounds"
|
||||
t-as="layer"
|
||||
t-key="layer.id"
|
||||
>
|
||||
<div class="form-check o_radio_item" aria-atomic="true">
|
||||
<input
|
||||
type="radio"
|
||||
t-att-checked="layer.isVisible"
|
||||
class="form-check-input o_radio_input"
|
||||
t-att-id="layer.name"
|
||||
name="raster"
|
||||
t-att-value="layer.id"
|
||||
t-on-change="() => this.onRasterChange(layer)"
|
||||
/>
|
||||
<label
|
||||
class="form-check-label o_form_label"
|
||||
t-att-for="layer.name"
|
||||
t-esc="layer.name"
|
||||
/>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
<div t-else="" class="d-flex justify-content-center text-900">
|
||||
<span class="title-panel">Layers (<t t-esc="numberOfLayers" />)</span>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
/** @odoo-module */
|
||||
|
||||
/**
|
||||
* Copyright 2023 ACSONE SA/NV
|
||||
*/
|
||||
import {useService} from "@web/core/utils/hooks";
|
||||
import {SearchBarRecords} from "./search_bar_records/search_bar_records.esm";
|
||||
|
||||
import {
|
||||
Component,
|
||||
onWillRender,
|
||||
onWillStart,
|
||||
onWillUpdateProps,
|
||||
useState,
|
||||
} from "@odoo/owl";
|
||||
|
||||
export class RecordsPanel extends Component {
|
||||
setup() {
|
||||
this.state = useState({
|
||||
isFolded: false,
|
||||
isClicked: 0,
|
||||
modelDescription: "",
|
||||
records: [],
|
||||
});
|
||||
this.orm = useService("orm");
|
||||
onWillStart(() => (this.state.records = this.props.list.records));
|
||||
onWillUpdateProps((nextProps) => (this.state.records = nextProps.list.records));
|
||||
onWillRender(async () => {
|
||||
// Retrieves the name of the current model
|
||||
const result = await this.orm.call("ir.model", "display_name_for", [
|
||||
[this.props.list.resModel],
|
||||
]);
|
||||
this.state.modelDescription = result[0].display_name;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This method allows you to open/close the panel.
|
||||
*/
|
||||
fold() {
|
||||
this.state.isFolded = !this.state.isFolded;
|
||||
this.state.records = this.props.list.records;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method reacts to the click on a record.
|
||||
* @param {*} record
|
||||
*/
|
||||
onDisplayPopupRecord(record) {
|
||||
const rec = this.props.list.records.find(
|
||||
(val) => val._values.id === record.resId
|
||||
);
|
||||
this.state.isClicked = record.resId;
|
||||
this.props.onDisplayPopupRecord(rec);
|
||||
}
|
||||
|
||||
/**
|
||||
* When you press a key, it automatically performs the search.
|
||||
* @param {*} value
|
||||
*/
|
||||
onInputKeyup(value) {
|
||||
const val = this.filterItems(value, this.props.list.records);
|
||||
this.state.records = val;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method allows you to filter items according to the value passed in parameter.
|
||||
* @param {*} value
|
||||
* @param {*} items
|
||||
* @returns
|
||||
*/
|
||||
filterItems(value, items) {
|
||||
const lowerValue = value.toLowerCase();
|
||||
return items.filter((item) =>
|
||||
item.data && item.data.display_name
|
||||
? item.data.display_name.toLowerCase().indexOf(lowerValue) >= 0
|
||||
: false
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
RecordsPanel.template = "base_geoengine.RecordsPanel";
|
||||
RecordsPanel.components = {SearchBarRecords};
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
.scroller {
|
||||
overflow-y: scroll;
|
||||
scrollbar-width: auto;
|
||||
}
|
||||
|
||||
.record {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.record:hover {
|
||||
background-color: #f6f7fa;
|
||||
}
|
||||
|
||||
.btn-record {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.btn-search {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<templates>
|
||||
<t t-name="base_geoengine.RecordsPanel" owl="1">
|
||||
<div
|
||||
class="menu border-end scroller"
|
||||
t-attf-class="{{ state.isFolded ? 'o_layer_panel_fold ' : 'o_layer_panel bg-view' }}"
|
||||
>
|
||||
<div
|
||||
class="w-100 d-flex"
|
||||
t-attf-class="{{ state.isFolded ? 'justify-content-center' : 'justify-content-start'}}"
|
||||
>
|
||||
<button
|
||||
class="btn p-0 mb-3"
|
||||
t-attf-class="{{state.isFolded ? 'unfold text-900': 'fold'}}"
|
||||
t-on-click="fold"
|
||||
>
|
||||
<i class="fa fa-arrows-h" />
|
||||
</button>
|
||||
</div>
|
||||
<div t-if="!state.isFolded">
|
||||
<section class="o_search_panel_section">
|
||||
<header
|
||||
class="o_search_panel_section_header text-uppercase cursor-default mb-2"
|
||||
>
|
||||
<span class="fs-6 fw-bold">
|
||||
<t t-esc="state.modelDescription" />
|
||||
</span>
|
||||
</header>
|
||||
<SearchBarRecords onInputKeyup.bind="onInputKeyup" />
|
||||
<ul class="raster list-group d-block o_search_panel_field">
|
||||
<li
|
||||
class="mb-1 record d-flex justify-content-between"
|
||||
t-foreach="state.records"
|
||||
t-as="record"
|
||||
t-key="record.resId"
|
||||
>
|
||||
<button
|
||||
class="btn btn-record"
|
||||
t-on-click="() => this.onDisplayPopupRecord(record)"
|
||||
>
|
||||
<span>
|
||||
<t t-esc="record.data.display_name" />
|
||||
</span>
|
||||
</button>
|
||||
<t t-if="state.isClicked === record.resId">
|
||||
<div>
|
||||
<button
|
||||
class="btn btn-search p-0"
|
||||
t-on-click="() => this.props.zoomOnFeature(record)"
|
||||
>
|
||||
<i
|
||||
class="fa fa-search-plus me-2 text-primary"
|
||||
/>
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-search p-0"
|
||||
t-on-click="() => this.props.zoomOutOnFeature(record)"
|
||||
>
|
||||
<i
|
||||
class="fa fa-search-minus me-2 text-primary"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</t>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
<div t-else="" class="d-flex justify-content-center text-900">
|
||||
<span class="title-panel">Records (<t
|
||||
t-esc="props.list.records.length"
|
||||
/>)</span>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/** @odoo-module */
|
||||
|
||||
/**
|
||||
* Copyright 2023 ACSONE SA/NV
|
||||
*/
|
||||
|
||||
import {Component, useRef} from "@odoo/owl";
|
||||
|
||||
export class SearchBarRecords extends Component {
|
||||
setup() {
|
||||
this.searchComponentRef = useRef("searchComponent");
|
||||
}
|
||||
|
||||
/**
|
||||
* When a key is pressed, the props onInputKeyup method is called.
|
||||
* @param {*} ev
|
||||
*/
|
||||
onInputKeyup(ev) {
|
||||
this.props.onInputKeyup(this.searchComponentRef.el.value);
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
}
|
||||
}
|
||||
|
||||
SearchBarRecords.template = "base_geoengine.SearchBarRecords";
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<templates>
|
||||
<t t-name="base_geoengine.SearchBarRecords" owl="1">
|
||||
<div class="o_cp_searchview d-flex flex-grow-1" role="search">
|
||||
<div
|
||||
class="o_searchview pb-1 align-self-center border-bottom flex-grow-1"
|
||||
role="search"
|
||||
>
|
||||
<i
|
||||
class="o_searchview_icon oi oi-search"
|
||||
role="img"
|
||||
aria-label="Search..."
|
||||
title="Search..."
|
||||
/>
|
||||
<div class="o_searchview_input_container">
|
||||
<input
|
||||
t-ref="searchComponent"
|
||||
type="text"
|
||||
class="o_searchview_input"
|
||||
placeholder="Search..."
|
||||
t-on-keyup="onInputKeyup"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/** @odoo-module **/
|
||||
|
||||
import {DomainField} from "@web/views/fields/domain/domain_field";
|
||||
import {registry} from "@web/core/registry";
|
||||
|
||||
export class DomainFieldExtend extends DomainField {
|
||||
async loadCount(props) {
|
||||
if (!this.getResModel(props)) {
|
||||
Object.assign(this.state, {recordCount: 0, isValid: true});
|
||||
}
|
||||
|
||||
let recordCount = 0;
|
||||
try {
|
||||
let value = props.value.slice();
|
||||
value = value.replace("not in active_ids", "not in");
|
||||
value = value.replace("in active_ids", "in");
|
||||
value = value.replace('"{ACTIVE_IDS}"', "[]");
|
||||
const domain = this.getDomain(value).toList(this.getContext(props));
|
||||
recordCount = await this.orm.silent.call(
|
||||
this.getResModel(props),
|
||||
"search_count",
|
||||
[domain],
|
||||
{context: this.getContext(props)}
|
||||
);
|
||||
} catch (_e) {
|
||||
// WOWL TODO: rethrow error when not the expected type
|
||||
Object.assign(this.state, {recordCount: 0, isValid: false});
|
||||
return;
|
||||
}
|
||||
Object.assign(this.state, {recordCount, isValid: true});
|
||||
}
|
||||
}
|
||||
|
||||
registry.category("fields").add("domain", DomainFieldExtend, {force: true});
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
/** @odoo-module **/
|
||||
|
||||
/**
|
||||
* Copyright 2023 ACSONE SA/NV
|
||||
*/
|
||||
|
||||
import {Component, onRendered} from "@odoo/owl";
|
||||
|
||||
/**
|
||||
* It allows you to set a default value for the field and a readonly property for the active_ids value.
|
||||
*/
|
||||
export class DomainSelectorFieldInputForActiveIds extends Component {
|
||||
setup() {
|
||||
onRendered(() => {
|
||||
if (this.props.value !== "{ACTIVE_IDS}") {
|
||||
this.props.update({value: "{ACTIVE_IDS}"});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
DomainSelectorFieldInputForActiveIds.template =
|
||||
"base_geoengine.DomainSelectorFieldInputForActiveIds";
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<templates xml:space="preserve">
|
||||
<t t-name="base_geoengine.DomainSelectorFieldInputForActiveIds" owl="1">
|
||||
<input
|
||||
type="text"
|
||||
class="o_input o_domain_leaf_value_input"
|
||||
t-att-value="props.value"
|
||||
t-on-change="onChange"
|
||||
readonly="1"
|
||||
/>
|
||||
</t>
|
||||
</templates>
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
/** @odoo-module **/
|
||||
|
||||
/**
|
||||
* Copyright 2023 ACSONE SA/NV
|
||||
*/
|
||||
|
||||
import {_lt} from "@web/core/l10n/translation";
|
||||
import {registry} from "@web/core/registry";
|
||||
import {DomainSelectorGeoFieldInput} from "../domain_selector_geo_field_input/domain_selector_geo_field_input.esm";
|
||||
import {onDidChange} from "../domain_selector_operators.esm";
|
||||
import {Component} from "@odoo/owl";
|
||||
|
||||
const dsf = registry.category("domain_selector/fields");
|
||||
|
||||
/**
|
||||
* This class allows you to adapt the right-hand operand and the operator of the domain
|
||||
* if the selected field is of type geo_field.
|
||||
*/
|
||||
export class DomainSelectorGeoField extends Component {}
|
||||
Object.assign(DomainSelectorGeoField, {
|
||||
template: "base_geoengine.DomainSelectorGeoField",
|
||||
components: {
|
||||
DomainSelectorGeoFieldInput,
|
||||
},
|
||||
|
||||
onDidTypeChange() {
|
||||
return {value: ""};
|
||||
},
|
||||
|
||||
getOperators() {
|
||||
return [
|
||||
{
|
||||
category: "geospatial",
|
||||
label: _lt("geo_contains"),
|
||||
value: "geo_contains",
|
||||
onDidChange: onDidChange((fieldChange) => fieldChange()),
|
||||
matches({operator}) {
|
||||
return operator === this.value;
|
||||
},
|
||||
},
|
||||
{
|
||||
category: "geospatial",
|
||||
label: _lt("geo_greater"),
|
||||
value: "geo_greater",
|
||||
onDidChange: onDidChange((fieldChange) => fieldChange()),
|
||||
matches({operator}) {
|
||||
return operator === this.value;
|
||||
},
|
||||
},
|
||||
{
|
||||
category: "geospatial",
|
||||
label: _lt("geo_lesser"),
|
||||
value: "geo_lesser",
|
||||
onDidChange: onDidChange((fieldChange) => fieldChange()),
|
||||
matches({operator}) {
|
||||
return operator === this.value;
|
||||
},
|
||||
},
|
||||
{
|
||||
category: "geospatial",
|
||||
label: _lt("geo_equal"),
|
||||
value: "geo_equal",
|
||||
onDidChange: onDidChange((fieldChange) => fieldChange()),
|
||||
matches({operator}) {
|
||||
return operator === this.value;
|
||||
},
|
||||
},
|
||||
{
|
||||
category: "geospatial",
|
||||
label: _lt("geo_touch"),
|
||||
value: "geo_touch",
|
||||
onDidChange: onDidChange((fieldChange) => fieldChange()),
|
||||
matches({operator}) {
|
||||
return operator === this.value;
|
||||
},
|
||||
},
|
||||
{
|
||||
category: "geospatial",
|
||||
label: _lt("geo_within"),
|
||||
value: "geo_within",
|
||||
onDidChange: onDidChange((fieldChange) => fieldChange()),
|
||||
matches({operator}) {
|
||||
return operator === this.value;
|
||||
},
|
||||
},
|
||||
{
|
||||
category: "geospatial",
|
||||
label: _lt("geo_intersect"),
|
||||
value: "geo_intersect",
|
||||
onDidChange: onDidChange((fieldChange) => fieldChange()),
|
||||
matches({operator}) {
|
||||
return operator === this.value;
|
||||
},
|
||||
},
|
||||
];
|
||||
},
|
||||
});
|
||||
|
||||
dsf.add("geo_multi_polygon", DomainSelectorGeoField);
|
||||
dsf.add("geo_multi_point", DomainSelectorGeoField);
|
||||
dsf.add("geo_multi_line", DomainSelectorGeoField);
|
||||
dsf.add("geo_polygon", DomainSelectorGeoField);
|
||||
dsf.add("geo_point", DomainSelectorGeoField);
|
||||
dsf.add("geo_line", DomainSelectorGeoField);
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<templates xml:space="preserve">
|
||||
<t t-name="base_geoengine.DomainSelectorGeoField" owl="1">
|
||||
<div class="o_ds_value_cell">
|
||||
<DomainSelectorGeoFieldInput t-props="props" />
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/** @odoo-module **/
|
||||
|
||||
/**
|
||||
* Copyright 2023 ACSONE SA/NV
|
||||
*/
|
||||
|
||||
import {DomainSelectorDialog} from "@web/core/domain_selector_dialog/domain_selector_dialog";
|
||||
import {_t} from "@web/core/l10n/translation";
|
||||
|
||||
/**
|
||||
* This class is extended from DomainSelectorGeoField in order to be able to
|
||||
* modify the title of the dialog window and to add some props to it.
|
||||
*/
|
||||
export class DomainSelectorGeoFieldDialog extends DomainSelectorDialog {
|
||||
get dialogTitle() {
|
||||
return _t(this.props.title);
|
||||
}
|
||||
}
|
||||
|
||||
DomainSelectorGeoFieldDialog.template = "base_geoengine.DomainSelectorGeoFieldDialog";
|
||||
DomainSelectorGeoFieldDialog.props = {
|
||||
close: Function,
|
||||
className: {type: String, optional: true},
|
||||
resModel: String,
|
||||
readonly: {type: Boolean, optional: true},
|
||||
isDebugMode: {type: Boolean, optional: true},
|
||||
defaultLeafValue: {type: Array, optional: true},
|
||||
initialValue: {type: String, optional: true},
|
||||
onSelected: Function,
|
||||
fieldName: {type: String, optional: true},
|
||||
title: {type: String, optional: true},
|
||||
model: {type: Object, optional: true},
|
||||
};
|
||||
|
||||
DomainSelectorGeoFieldDialog.defaultProps = {
|
||||
initialValue: "",
|
||||
readonly: true,
|
||||
isDebugMode: false,
|
||||
title: "Domain",
|
||||
};
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<templates xml:space="preserve">
|
||||
<t
|
||||
t-name="base_geoengine.DomainSelectorGeoFieldDialog"
|
||||
t-inherit="web.DomainSelectorDialog"
|
||||
t-inherit-mode="primary"
|
||||
owl="1"
|
||||
>
|
||||
</t>
|
||||
</templates>
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
/** @odoo-module **/
|
||||
|
||||
/**
|
||||
* Copyright 2023 ACSONE SA/NV
|
||||
*/
|
||||
|
||||
import {ModelFieldSelector} from "@web/core/model_field_selector/model_field_selector";
|
||||
import {ModelSelector} from "@web/core/model_selector/model_selector";
|
||||
import {Domain} from "@web/core/domain";
|
||||
import {evaluate} from "@web/core/py_js/py_interpreter";
|
||||
import {useOwnedDialogs} from "@web/core/utils/hooks";
|
||||
import {DomainSelectorGeoFieldDialog} from "../domain_selector_geo_field_dialog/domain_selector_geo_field_dialog.esm";
|
||||
|
||||
import {Component, onWillStart, onWillUpdateProps, useState} from "@odoo/owl";
|
||||
|
||||
/**
|
||||
* This class correspond to the value of the right operand when a geo_field has
|
||||
* been selected.
|
||||
*/
|
||||
export class DomainSelectorGeoFieldInput extends Component {
|
||||
setup() {
|
||||
this.state = useState({
|
||||
resModel: "",
|
||||
fieldName: "",
|
||||
subField: "",
|
||||
operator: "",
|
||||
value: "",
|
||||
domain: {},
|
||||
});
|
||||
this.addDialog = useOwnedDialogs();
|
||||
|
||||
/**
|
||||
* Before starting, if a value is already selected we had to know the fieldName and
|
||||
* the resModel.
|
||||
*/
|
||||
onWillStart(async () => {
|
||||
if (this.props.value instanceof Object) {
|
||||
this.defaultKey = Object.keys(this.props.value)[0];
|
||||
const index = this.defaultKey.lastIndexOf(".");
|
||||
this.state.fieldName = this.defaultKey.substring(index + 1);
|
||||
this.state.resModel = this.defaultKey.substring(0, index);
|
||||
this.loadDomain();
|
||||
} else {
|
||||
this.state.value = this.props.value;
|
||||
}
|
||||
});
|
||||
|
||||
onWillUpdateProps((nextProps) => this.loadDomain(nextProps));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method allow the domain to be loaded into a state.
|
||||
* @param {*} nextProps
|
||||
*/
|
||||
loadDomain(nextProps) {
|
||||
const props = nextProps === undefined ? this.props : nextProps;
|
||||
if (this.defaultKey !== undefined) {
|
||||
this.key = this.defaultKey;
|
||||
}
|
||||
this.state.domain = new Domain(props.value[this.key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method updates the value of the right operand of the domain.
|
||||
* @param {*} value
|
||||
*/
|
||||
update(value) {
|
||||
this.key = this.state.resModel + "." + this.state.fieldName;
|
||||
const obj = {};
|
||||
let jsDomain = [];
|
||||
if (value !== undefined) {
|
||||
const domain = new Domain(value);
|
||||
jsDomain = evaluate(domain.ast, {});
|
||||
}
|
||||
obj[this.key] = jsDomain;
|
||||
this.props.update({value: obj});
|
||||
}
|
||||
|
||||
/**
|
||||
* This method reacts to changes of the sub field name.
|
||||
* @param {*} fieldName
|
||||
*/
|
||||
async onFieldModelChange(fieldName) {
|
||||
this.state.fieldName = fieldName;
|
||||
this.update();
|
||||
}
|
||||
|
||||
/**
|
||||
* When we click on the edit button, this launches a dialog window allowing you to
|
||||
* edit the sub-domain.
|
||||
*/
|
||||
display() {
|
||||
const initialValue =
|
||||
this.state.domain !== undefined ? this.state.domain.toString() : "[]";
|
||||
this.addDialog(DomainSelectorGeoFieldDialog, {
|
||||
resModel: this.state.resModel,
|
||||
initialValue,
|
||||
readonly: false,
|
||||
isDebugMode: Boolean(this.env.debug),
|
||||
fieldName: this.state.fieldName,
|
||||
onSelected: (value) => this.update(value),
|
||||
title: this.env._t("Subdomain"),
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This method react to changes of the sub model.
|
||||
* @param {*} newModel
|
||||
*/
|
||||
onModelChange(newModel) {
|
||||
this.state.resModel = newModel.technical;
|
||||
this.state.fieldName = "id";
|
||||
this.state.subField = "";
|
||||
this.update();
|
||||
}
|
||||
}
|
||||
|
||||
DomainSelectorGeoFieldInput.template = "base_geoengine.DomainSelectorGeoFieldInput";
|
||||
DomainSelectorGeoFieldInput.components = {ModelFieldSelector, ModelSelector};
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<templates xml:space="preserve">
|
||||
<t t-name="base_geoengine.DomainSelectorGeoFieldInput" owl="1">
|
||||
<div class="d-flex align-items-center">
|
||||
<ModelSelector
|
||||
value="state.resModel"
|
||||
onModelSelected.bind="onModelChange"
|
||||
/>
|
||||
<div t-if="state.resModel.length > 0" class="col-5">
|
||||
<ModelFieldSelector
|
||||
fieldName="state.fieldName"
|
||||
resModel="state.resModel"
|
||||
readonly="false"
|
||||
update="(name) => this.onFieldModelChange(name)"
|
||||
isDebugMode="false"
|
||||
/>
|
||||
</div>
|
||||
<button class="btn btn-link col-1" t-on-click.prevent="display">
|
||||
<i class="fa fa-pencil-square" />
|
||||
</button>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
/** @odoo-module **/
|
||||
|
||||
/**
|
||||
* Copyright 2023 ACSONE SA/NV
|
||||
*/
|
||||
|
||||
import {registry} from "@web/core/registry";
|
||||
import {_lt} from "@web/core/l10n/translation";
|
||||
import {DomainSelectorFieldInput} from "@web/core/domain_selector/fields/domain_selector_field_input";
|
||||
import {DomainSelectorFieldInputForActiveIds} from "../domain_selector_field_input_for_active_ids/domain_selector_field_input_for_active_ids.esm";
|
||||
import {DomainSelectorFieldInputWithTags} from "@web/core/domain_selector/fields/domain_selector_field_input_with_tags";
|
||||
import {onDidChange} from "../domain_selector_operators.esm";
|
||||
|
||||
const dso = registry.category("domain_selector/operator");
|
||||
|
||||
import {Component} from "@odoo/owl";
|
||||
|
||||
/**
|
||||
* This method is extended from DomainSelectorNumberField to add some operators
|
||||
* ("in active_ids", "not in active_ids", "in", "not in").
|
||||
*/
|
||||
export class DomainSelectorNumberFieldExtend extends Component {}
|
||||
Object.assign(DomainSelectorNumberFieldExtend, {
|
||||
template: "base_geoengine.DomainSelectorNumberFieldExtend",
|
||||
components: {
|
||||
DomainSelectorFieldInput,
|
||||
DomainSelectorFieldInputWithTags,
|
||||
DomainSelectorFieldInputForActiveIds,
|
||||
},
|
||||
|
||||
onDidTypeChange() {
|
||||
return {value: 0};
|
||||
},
|
||||
getOperators() {
|
||||
const addOperators = [
|
||||
{
|
||||
category: "active_ids",
|
||||
label: _lt("in active_ids"),
|
||||
value: "in active_ids",
|
||||
onDidChange: onDidChange((fieldChange) => fieldChange()),
|
||||
matches({operator}) {
|
||||
return operator === this.value;
|
||||
},
|
||||
},
|
||||
{
|
||||
category: "active_ids",
|
||||
label: _lt("not in active_ids"),
|
||||
value: "not in active_ids",
|
||||
onDidChange: onDidChange((fieldChange) => fieldChange()),
|
||||
matches({operator}) {
|
||||
return operator === this.value;
|
||||
},
|
||||
},
|
||||
];
|
||||
const operators = [
|
||||
"=",
|
||||
"!=",
|
||||
">",
|
||||
"<",
|
||||
">=",
|
||||
"<=",
|
||||
"ilike",
|
||||
"not ilike",
|
||||
"in",
|
||||
"not in",
|
||||
"set",
|
||||
"not set",
|
||||
].map((key) => dso.get(key));
|
||||
return operators.concat(addOperators);
|
||||
},
|
||||
});
|
||||
registry
|
||||
.category("domain_selector/fields")
|
||||
.add("integer", DomainSelectorNumberFieldExtend, {force: true});
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<templates xml:space="preserve">
|
||||
|
||||
<t t-name="base_geoengine.DomainSelectorNumberFieldExtend" owl="1">
|
||||
<t t-if="props.operator.category === 'in'">
|
||||
<DomainSelectorFieldInputWithTags t-props="props" />
|
||||
</t>
|
||||
<t t-elif="props.operator.category === 'active_ids'">
|
||||
<DomainSelectorFieldInputForActiveIds
|
||||
value="props.value"
|
||||
update="props.update"
|
||||
/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<div class="o_ds_value_cell">
|
||||
<DomainSelectorFieldInput t-props="props" />
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</templates>
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
/** @odoo-module */
|
||||
|
||||
/**
|
||||
* This is method is called when an operator changes its value.
|
||||
*/
|
||||
export function onDidChange(action) {
|
||||
return function (oldOperator, fieldChange) {
|
||||
if (this.category !== oldOperator.category) {
|
||||
return action(fieldChange);
|
||||
}
|
||||
return {};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
.o_field_geo_multi_polygon,
|
||||
.o_field_geo_point,
|
||||
.o_field_geo_polygon,
|
||||
.o_field_geo_multi_line,
|
||||
.o_field_geo_multi_point,
|
||||
.o_field_geo_line {
|
||||
width: 100%;
|
||||
height: 550px;
|
||||
}
|
||||
.ol_map {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
|
@ -0,0 +1,324 @@
|
|||
/** @odoo-module **/
|
||||
|
||||
/**
|
||||
* Copyright 2023 ACSONE SA/NV
|
||||
*/
|
||||
|
||||
import {loadBundle} from "@web/core/assets";
|
||||
import {registry} from "@web/core/registry";
|
||||
import {useService} from "@web/core/utils/hooks";
|
||||
import {standardFieldProps} from "@web/views/fields/standard_field_props";
|
||||
|
||||
import {Component, onMounted, onRendered, onWillStart, useEffect} from "@odoo/owl";
|
||||
|
||||
export class FieldGeoEngineEditMap extends Component {
|
||||
setup() {
|
||||
// Allows you to have a unique id if you put the same field in the view several times
|
||||
this.id = `map_${Date.now()}`;
|
||||
this.orm = useService("orm");
|
||||
|
||||
onWillStart(() =>
|
||||
Promise.all([
|
||||
loadBundle({
|
||||
jsLibs: [
|
||||
"/base_geoengine/static/lib/ol-7.2.2/ol.js",
|
||||
"/base_geoengine/static/lib/chromajs-2.4.2/chroma.js",
|
||||
],
|
||||
}),
|
||||
])
|
||||
);
|
||||
|
||||
// Is executed when component is mounted.
|
||||
onMounted(async () => {
|
||||
const result = await this.orm.call(
|
||||
this.props.record.resModel,
|
||||
"get_edit_info_for_geo_column",
|
||||
[this.props.name]
|
||||
);
|
||||
this.projection = result.projection;
|
||||
this.defaultExtent = result.default_extent;
|
||||
this.defaultZoom = result.default_zoom;
|
||||
this.restrictedExtent = result.restricted_extent;
|
||||
this.srid = result.srid;
|
||||
this.createLayers();
|
||||
this.renderMap();
|
||||
this.setValue(this.props.value);
|
||||
});
|
||||
|
||||
useEffect(
|
||||
() => {
|
||||
if (!this.props.readonly && this.map !== undefined) {
|
||||
this.setupControls();
|
||||
}
|
||||
},
|
||||
() => [this.props.value]
|
||||
);
|
||||
|
||||
// Is executed after component is rendered. When we use pagination.
|
||||
onRendered(() => {
|
||||
this.setValue(this.props.value);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays geo data on the map using the collection of features.
|
||||
*/
|
||||
createVectorLayer() {
|
||||
this.features = new ol.Collection();
|
||||
this.source = new ol.source.Vector({features: this.features});
|
||||
const colorHex = this.props.color !== undefined ? this.props.color : "#ee9900";
|
||||
const opacity = this.props.opacity !== undefined ? this.props.opacity : 1;
|
||||
const color = chroma(colorHex).alpha(opacity).css();
|
||||
const fill = new ol.style.Fill({
|
||||
color: color,
|
||||
});
|
||||
const stroke = new ol.style.Stroke({
|
||||
color,
|
||||
width: 2,
|
||||
});
|
||||
return new ol.layer.Vector({
|
||||
source: this.source,
|
||||
style: new ol.style.Style({
|
||||
fill,
|
||||
stroke,
|
||||
image: new ol.style.Circle({
|
||||
radius: 5,
|
||||
fill,
|
||||
stroke,
|
||||
}),
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Call the method that creates the layer to display the geo data on the map.
|
||||
*/
|
||||
createLayers() {
|
||||
this.vectorLayer = this.createVectorLayer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows you to centre the area defined for the user.
|
||||
* If there is an item to display.
|
||||
*/
|
||||
updateMapZoom() {
|
||||
if (this.source) {
|
||||
var extent = this.source.getExtent();
|
||||
var infinite_extent = [Infinity, Infinity, -Infinity, -Infinity];
|
||||
if (extent !== infinite_extent) {
|
||||
var map_view = this.map.getView();
|
||||
if (map_view) {
|
||||
map_view.fit(extent, {maxZoom: 14});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows you to centre the area defined for the user.
|
||||
* If there is not item to display.
|
||||
*/
|
||||
updateMapEmpty() {
|
||||
var map_view = this.map.getView();
|
||||
if (map_view) {
|
||||
var extent = this.defaultExtent.replace(/\s/g, "").split(",");
|
||||
extent = extent.map((coord) => Number(coord));
|
||||
map_view.fit(extent, {maxZoom: this.defaultZoom || 5});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Based on the value passed in props, adds a new feature to the collection.
|
||||
* @param {*} value
|
||||
*/
|
||||
setValue(value) {
|
||||
if (this.map) {
|
||||
/**
|
||||
* If the value to be displayed is equal to the one passed in props, do nothing
|
||||
* otherwise clear the map and display the new value.
|
||||
*/
|
||||
if (this.displayValue == value) return;
|
||||
this.displayValue = value;
|
||||
var ft = new ol.Feature({
|
||||
geometry: new ol.format.GeoJSON().readGeometry(value),
|
||||
labelPoint: new ol.format.GeoJSON().readGeometry(value),
|
||||
});
|
||||
this.source.clear();
|
||||
this.source.addFeature(ft);
|
||||
|
||||
if (value) {
|
||||
this.updateMapZoom();
|
||||
} else {
|
||||
this.updateMapEmpty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is triggered when the view changed. When we have finished drawing our geo data, or
|
||||
* when we clear the map.
|
||||
* @param {*} geometry
|
||||
*/
|
||||
onUIChange(geometry) {
|
||||
var value = null;
|
||||
if (geometry) {
|
||||
value = this.format.writeGeometry(geometry);
|
||||
}
|
||||
this.props.update(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow you to setup the trash button and the draw interaction.
|
||||
*/
|
||||
setupControls() {
|
||||
if (!this.props.value) {
|
||||
void (
|
||||
this.selectInteraction !== undefined &&
|
||||
this.map.removeInteraction(this.selectInteraction)
|
||||
);
|
||||
void (
|
||||
this.modifyInteraction !== undefined &&
|
||||
this.map.removeInteraction(this.modifyInteraction)
|
||||
);
|
||||
this.drawInteraction = new ol.interaction.Draw({
|
||||
type: this.geoType,
|
||||
source: this.source,
|
||||
});
|
||||
this.map.addInteraction(this.drawInteraction);
|
||||
|
||||
this.drawInteraction.on("drawend", (e) => {
|
||||
this.onUIChange(e.feature.getGeometry());
|
||||
});
|
||||
} else {
|
||||
void (
|
||||
this.drawInteraction !== undefined &&
|
||||
this.map.removeInteraction(this.drawInteraction)
|
||||
);
|
||||
this.selectInteraction = new ol.interaction.Select();
|
||||
this.modifyInteraction = new ol.interaction.Modify({
|
||||
features: this.selectInteraction.getFeatures(),
|
||||
});
|
||||
this.map.addInteraction(this.selectInteraction);
|
||||
this.map.addInteraction(this.modifyInteraction);
|
||||
|
||||
this.modifyInteraction.on("modifyend", (e) => {
|
||||
e.features.getArray().forEach((item) => {
|
||||
this.onUIChange(item.getGeometry());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const element = this.createTrashControl();
|
||||
|
||||
this.clearmapControl = new ol.control.Control({element: element});
|
||||
|
||||
this.map.addControl(this.clearmapControl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the trash button that clears the map.
|
||||
* @returns the div in which the button is located.
|
||||
*/
|
||||
createTrashControl() {
|
||||
const button = document.createElement("button");
|
||||
button.innerHTML = '<i class="fa fa-trash"/>';
|
||||
button.addEventListener("click", () => {
|
||||
this.source.clear();
|
||||
this.onUIChange(null);
|
||||
});
|
||||
const element = document.createElement("div");
|
||||
element.className = "ol-clear ol-unselectable ol-control";
|
||||
element.appendChild(button);
|
||||
return element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the map in the div provided.
|
||||
*/
|
||||
renderMap() {
|
||||
this.map = new ol.Map({
|
||||
target: this.id,
|
||||
layers: [
|
||||
new ol.layer.Tile({
|
||||
source: new ol.source.OSM(),
|
||||
}),
|
||||
],
|
||||
view: new ol.View({
|
||||
center: [0, 0],
|
||||
zoom: 5,
|
||||
}),
|
||||
});
|
||||
this.map.addLayer(this.vectorLayer);
|
||||
this.format = new ol.format.GeoJSON({
|
||||
internalProjection: this.map.getView().getProjection(),
|
||||
externalProjection: "EPSG:" + this.srid,
|
||||
});
|
||||
|
||||
if (!this.props.readonly) {
|
||||
this.setupControls();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FieldGeoEngineEditMap.template = "base_geoengine.FieldGeoEngineEditMap";
|
||||
FieldGeoEngineEditMap.props = {
|
||||
...standardFieldProps,
|
||||
opacity: {type: Number, optional: true},
|
||||
color: {type: String, optional: true},
|
||||
};
|
||||
|
||||
FieldGeoEngineEditMap.extractProps = ({attrs}) => {
|
||||
return {
|
||||
opacity: attrs.options.opacity,
|
||||
color: attrs.options.color,
|
||||
};
|
||||
};
|
||||
|
||||
export class FieldGeoEngineEditMapMultiPolygon extends FieldGeoEngineEditMap {
|
||||
setup() {
|
||||
this.geoType = "MultiPolygon";
|
||||
super.setup();
|
||||
}
|
||||
}
|
||||
|
||||
export class FieldGeoEngineEditMapPolygon extends FieldGeoEngineEditMap {
|
||||
setup() {
|
||||
this.geoType = "Polygon";
|
||||
super.setup();
|
||||
}
|
||||
}
|
||||
|
||||
export class FieldGeoEngineEditMapPoint extends FieldGeoEngineEditMap {
|
||||
setup() {
|
||||
this.geoType = "Point";
|
||||
super.setup();
|
||||
}
|
||||
}
|
||||
|
||||
export class FieldGeoEngineEditMapMultiPoint extends FieldGeoEngineEditMap {
|
||||
setup() {
|
||||
this.geoType = "MultiPoint";
|
||||
super.setup();
|
||||
}
|
||||
}
|
||||
|
||||
export class FieldGeoEngineEditMapLine extends FieldGeoEngineEditMap {
|
||||
setup() {
|
||||
this.geoType = "LineString";
|
||||
super.setup();
|
||||
}
|
||||
}
|
||||
|
||||
export class FieldGeoEngineEditMapMultiLine extends FieldGeoEngineEditMap {
|
||||
setup() {
|
||||
this.geoType = "MultiLineString";
|
||||
super.setup();
|
||||
}
|
||||
}
|
||||
|
||||
registry.category("fields").add("geo_multi_polygon", FieldGeoEngineEditMapMultiPolygon);
|
||||
registry.category("fields").add("geo_polygon", FieldGeoEngineEditMapPolygon);
|
||||
registry.category("fields").add("geo_point", FieldGeoEngineEditMapPoint);
|
||||
registry.category("fields").add("geo_multi_point", FieldGeoEngineEditMapMultiPoint);
|
||||
registry.category("fields").add("geo_line", FieldGeoEngineEditMapLine);
|
||||
registry.category("fields").add("geo_multi_line", FieldGeoEngineEditMapMultiLine);
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<templates xml:space="preserve">
|
||||
<t t-name="base_geoengine.FieldGeoEngineEditMap" owl="1">
|
||||
<div class="ol_map" t-att-id="id" />
|
||||
</t>
|
||||
</templates>
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
# Copyright 2023 ACSONE SA/NV
|
||||
from . import test_model
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
# Copyright 2023 ACSONE SA/NV
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class GeoModelTest(models.Model):
|
||||
"""GeoModel for testing"""
|
||||
|
||||
_name = "geo.model.test"
|
||||
name = fields.Char("GeoModelTest")
|
||||
geo_multi_polygon = fields.GeoMultiPolygon()
|
||||
geo_polygon = fields.GeoPolygon()
|
||||
geo_line = fields.GeoLine()
|
||||
geo_point = fields.GeoPoint()
|
||||
geo_multi_line = fields.GeoMultiLine()
|
||||
geo_multi_point = fields.GeoMultiPoint()
|
||||
|
||||
|
||||
class DummyZip(models.Model):
|
||||
"""DummyZip model for testing"""
|
||||
|
||||
_name = "dummy.zip"
|
||||
_description = "Geoengine demo ZIP"
|
||||
|
||||
name = fields.Char("ZIP", index=True, required=True)
|
||||
city = fields.Char(index=True, required=True)
|
||||
the_geom = fields.GeoMultiPolygon("NPA Shape")
|
||||
the_poly = fields.GeoPolygon()
|
||||
|
||||
|
||||
class RetailMachine(models.Model):
|
||||
"""RetailMachine model for testing"""
|
||||
|
||||
_name = "retail.machine"
|
||||
_description = "Geoengine demo retailing machine"
|
||||
|
||||
the_point = fields.GeoPoint("Coordinate")
|
||||
total_sales = fields.Float("Total sale", index=True)
|
||||
money_level = fields.Char(index=True)
|
||||
state = fields.Selection([("hs", "HS"), ("ok", "OK")], index=True)
|
||||
name = fields.Char("Serial number", required=True)
|
||||
|
|
@ -0,0 +1,704 @@
|
|||
# Copyright 2023 ACSONE SA/NV
|
||||
|
||||
import geojson
|
||||
from odoo_test_helper import FakeModelLoader
|
||||
from shapely import wkt
|
||||
from shapely.geometry import shape
|
||||
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
from ..fields import GeoPoint
|
||||
|
||||
|
||||
class TestModel(TransactionCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestModel, cls).setUpClass()
|
||||
cls.loader = FakeModelLoader(cls.env, cls.__module__)
|
||||
cls.loader.backup_registry()
|
||||
|
||||
from .models import DummyZip, GeoModelTest, RetailMachine
|
||||
|
||||
cls.loader.update_registry((GeoModelTest, DummyZip, RetailMachine))
|
||||
cls.geo_model = cls.env["geo.model.test"].create({})
|
||||
cls.env["dummy.zip"].create(
|
||||
{
|
||||
"name": "1146",
|
||||
"city": "Mollens (VD))",
|
||||
"the_geom": "MULTIPOLYGON (((711089.693203108 5873735.48072837, "
|
||||
+ "711092.576313001 5873519.88384687,"
|
||||
+ "711067.054090924 5873435.51305599,710995.218898879 5873198.04330687,"
|
||||
+ "710996.388615927 5873110.64387336,711039.179454242 5873060.22832024,"
|
||||
+ "711042.287896265 5872936.43418925,711026.423105771 5872819.67065428,"
|
||||
+ "711261.754450894 5872597.025222,711241.609394529 5872474.38185775,"
|
||||
+ "711059.74912495 5872499.61499977,710956.020676372 5872329.22952511,"
|
||||
+ "710692.244689654 5872290.70879558,710486.478264092 5871933.93784652,"
|
||||
+ "710024.93171231 5872025.28274803,710005.024342666 5871778.82753806,"
|
||||
+ "709728.110667306 5871639.59028651,709724.582871056 5871578.36223351,"
|
||||
+ "709682.212415895 5871490.38595657,709610.808017364 5871402.01470814,"
|
||||
+ "709552.306572401 5871356.73905814,709495.853317159 5871313.04976156,"
|
||||
+ "709236.521364341 5871163.84756429,709195.304008703 5871128.42409022,"
|
||||
+ "709150.409305552 5871089.84044459,709093.837273492 5871008.051534,"
|
||||
+ "709008.015634898 5870883.97195414,708922.106609628 5870795.4022844,"
|
||||
+ "708836.258869397 5870702.46391409,708174.672218121 5871197.33373336,"
|
||||
+ "707846.164800298 5870800.97891085,707605.589841331 5870979.71730235,"
|
||||
+ "706369.331113847 5871966.12906172,706306.149363559 5872332.34885008,"
|
||||
+ "705390.804735349 5873401.94343156,704603.284854186 5873838.0955764,"
|
||||
+ "704092.91256737 5873980.90856737,704011.87512573 5873857.35915706,"
|
||||
+ "703030.73225885 5874621.40143472,702006.482932752 5874937.39404808,"
|
||||
+ "702849.34839414 5875420.27638601,705799.405382342 5875341.31671473,"
|
||||
+ "707632.65678248 5875553.44607092,708858.019414722 5875286.16417218,"
|
||||
+ "709639.976192618 5874932.54154212,709800.865455979 5874636.00773277,"
|
||||
+ "710188.467536495 5874437.27183537,710138.406154331 5874271.93819522,"
|
||||
+ "710464.959230515 5874290.93364989,711089.693203108 5873735.48072837)))",
|
||||
}
|
||||
)
|
||||
|
||||
cls.env["dummy.zip"].create(
|
||||
{
|
||||
"name": "1169",
|
||||
"city": "Yens",
|
||||
"the_geom": "MULTIPOLYGON (((712499.646588959 5867275.9182732,"
|
||||
+ "713419.026718887 5867001.27747293,714015.722251894 5866538.88540113,"
|
||||
+ "714694.030364397 5866492.43868073,714765.262342783 5865922.7082706,"
|
||||
+ "714997.785886538 5865558.90341594,715151.666992536 5865665.71173242,"
|
||||
+ "715609.031373263 5865079.20249973,715885.038705088 5865053.65786512,"
|
||||
+ "716495.789172412 5864492.40980924,716976.367311019 5864008.08379334,"
|
||||
+ "716781.749152281 5863910.99389739,716608.651725694 5863833.09642092,"
|
||||
+ "716518.052861577 5863201.78267731,716064.089435707 5863535.02734419,"
|
||||
+ "715643.594094414 5862954.76617529,715325.079468014 5863244.60059218,"
|
||||
+ "715203.241075229 5863130.96403033,715274.223325112 5862913.60004965,"
|
||||
+ "714897.772002756 5862635.12980843,714563.017533803 5862610.39226806,"
|
||||
+ "714258.266707042 5862620.95887512,714249.030777221 5862438.94330443,"
|
||||
+ "713724.197313172 5862641.59763197,713517.069387174 5862507.90536999,"
|
||||
+ "712861.144693087 5862860.12184101,713026.004126525 5862898.68588355,"
|
||||
+ "712886.267874965 5863045.26900106,712827.103281182 5863131.79990304,"
|
||||
+ "712738.929710136 5863217.94640341,712691.900706143 5863250.04961387,"
|
||||
+ "712592.546151257 5863317.87261312,712504.368398659 5863404.01855574,"
|
||||
+ "712405.215033586 5863533.04505435,712371.521154897 5863576.88960266,"
|
||||
+ "712355.411589612 5863605.09059754,712223.007660214 5863836.87550522,"
|
||||
+ "712156.578632893 5863923.31295655,712134.435332338 5863952.12551606,"
|
||||
+ "712134.049617032 5863981.22835121,712079.319781245 5864066.52919356,"
|
||||
+ "712059.980001849 5864096.67295644,712051.318250669 5864144.84287664,"
|
||||
+ "712044.316598475 5864183.7895569,711908.743067266 5864560.40002656,"
|
||||
+ "711809.521376786 5864821.06690256,711185.861440992 5865020.84754387,"
|
||||
+ "710829.505021716 5865627.41104201,710236.389289627 5865815.90923937,"
|
||||
+ "710091.432898977 5866557.84150433,709133.629951634 5866771.90114324,"
|
||||
+ "709458.164419682 5866919.01207252,709913.809001053 5867137.78068809,"
|
||||
+ "710889.333222594 5868419.19110438,711446.96086477 5867965.10731405,"
|
||||
+ "711555.097159712 5867474.42262634,711838.254231148 5867572.85286263,"
|
||||
+ "711873.968689887 5867287.95989594,712499.646588959 5867275.9182732)))",
|
||||
}
|
||||
)
|
||||
|
||||
cls.env["retail.machine"].create(
|
||||
{
|
||||
"name": "34",
|
||||
"total_sales": 734.0,
|
||||
"money_level": "low",
|
||||
"the_point": "POINT(711341.795470746 5866150.25857961)",
|
||||
"state": "ok",
|
||||
}
|
||||
)
|
||||
|
||||
cls.env["retail.machine"].create(
|
||||
{
|
||||
"name": "33",
|
||||
"total_sales": 492.0,
|
||||
"money_level": "low",
|
||||
"the_point": "POINT(711652.69365366 5866548.27641024)",
|
||||
"state": "ok",
|
||||
}
|
||||
)
|
||||
|
||||
cls.env["retail.machine"].create(
|
||||
{
|
||||
"name": "18",
|
||||
"total_sales": 892.0,
|
||||
"money_level": "high",
|
||||
"the_point": "POINT(708451.36372351 5872547.88349207)",
|
||||
"state": "ok",
|
||||
}
|
||||
)
|
||||
|
||||
cls.env["retail.machine"].create(
|
||||
{
|
||||
"name": "23",
|
||||
"total_sales": 1781.0,
|
||||
"money_level": "high",
|
||||
"the_point": "POINT(708037.67602773 5873788.9465794)",
|
||||
"state": "ok",
|
||||
}
|
||||
)
|
||||
|
||||
cls.env["retail.machine"].create(
|
||||
{
|
||||
"name": "21",
|
||||
"total_sales": 1533.0,
|
||||
"money_level": "high",
|
||||
"the_point": "POINT(706962.088018701 5873623.47150109)",
|
||||
"state": "ok",
|
||||
}
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
cls.loader.restore_registry()
|
||||
super(TestModel, cls).tearDownClass()
|
||||
|
||||
def test_create_multipolygon_wkt_format(self):
|
||||
"""Create a multi polygon"""
|
||||
multi_polygon = """MULTIPOLYGON (((726469.938970306 5873145.03456248,
|
||||
726520.174105436 5872946.03059195,726394.076006275 5872675.04267336,
|
||||
726404.709252018 5872259.98652277,726212.557712441 5871801.78900894,
|
||||
726471.645243121 5871748.01187117,726384.798016214 5871474.60597039,
|
||||
726524.862821204 5871416.52279756,726560.408193573 5870936.9668625,
|
||||
726765.583679957 5870941.58021817,726800.675791552 5870794.8818083,
|
||||
726830.398385972 5870610.25496982,726667.324961485 5870525.33567258,
|
||||
726559.158856422 5870713.41380138,726483.618814776 5870842.15916191,
|
||||
726282.880000044 5870874.76667995,726075.942331799 5870940.79690473,
|
||||
726060.620082161 5870636.20922038,725995.373875086 5870504.36168216,
|
||||
725871.917698916 5870508.73664946,725866.910956205 5870440.22483982,
|
||||
725760.074408205 5870513.2465806,724947.130321146 5870506.55170525,
|
||||
724956.64886783 5870684.35364044,724709.437725183 5870717.82930599,
|
||||
724640.837901402 5870502.91208435,723632.716917063 5871035.58668793,
|
||||
723353.587063504 5870580.71145654,722975.340414945 5870644.60022452,
|
||||
723063.193608096 5871187.48904965,723286.565782157 5871691.25884814,
|
||||
722865.254617585 5871951.28387527,722963.962738856 5872074.84140304,
|
||||
722831.245902295 5872122.76389775,722813.837916803 5872242.00526964,
|
||||
722827.655983236 5872300.44254147,722913.370119188 5872418.02105384,
|
||||
722942.233783707 5872432.93796481,722984.741992683 5872520.85895895,
|
||||
723012.381471722 5872637.73702376,723086.082443995 5872667.76380156,
|
||||
723157.229378648 5872668.62290333,723214.748202491 5872698.34771906,
|
||||
723250.508284339 5872761.5280976,723286.16249158 5872815.86084868,
|
||||
723315.028102666 5872830.77719621,723502.328395902 5872819.6206505,
|
||||
723518.483057357 5872818.65863173,723567.82777813 5872844.15493286,
|
||||
723749.413939088 5872937.98130854,723848.429817139 5873019.41326079,
|
||||
723893.228455684 5873056.25562596,724000.782399525 5873179.05937195,
|
||||
724022.179653074 5873203.48913931,724167.213521721 5873219.79321866,
|
||||
724240.443943894 5873257.62460164,724345.033870514 5873311.65740904,
|
||||
724427.033053176 5873354.0176493,724458.116953997 5873354.38826826,
|
||||
724601.342527281 5873356.09453768,724659.368258544 5873356.78513641,
|
||||
724699.259216658 5873263.86039926,724734.038257937 5873182.84407915,
|
||||
724769.196071982 5873148.4004069,724792.808935311 5873125.2670227,
|
||||
724828.594968331 5873107.84535952,724909.660761314 5873068.37954232,
|
||||
724968.429515518 5873010.80204763,724969.116329931 5872952.53572905,
|
||||
725027.883915669 5872894.95858978,725144.902548535 5872823.50310579,
|
||||
725202.982873244 5872824.19072548,725231.165281494 5872845.9215328,
|
||||
725260.549561619 5872868.5770444,725323.492507265 5872998.67536266,
|
||||
725345.617620278 5873044.40573114,725374.316461685 5873073.88235996,
|
||||
725461.097697554 5873104.044911,725548.221016413 5873105.07306152,
|
||||
725593.723206956 5873117.05713947,725633.818030441 5873127.61507632,
|
||||
725664.044374598 5873135.57621915,725715.023293758 5873205.45921561,
|
||||
725835.567474206 5873370.70034401,725849.407491127 5873429.14029691,
|
||||
725878.279489341 5873444.04917682,725936.874293492 5873401.02996477,
|
||||
725995.978527806 5873314.30901098,726070.62161125 5873140.35732493,
|
||||
726085.312084189 5873125.96087534,726100.002508819 5873111.56442448,
|
||||
726217.015284978 5873040.09276485,726304.138055426 5873041.11333845,
|
||||
726469.938970306 5873145.03456248)))"""
|
||||
multi_polygon_loaded = wkt.loads(multi_polygon)
|
||||
self.geo_model.geo_multi_polygon = multi_polygon
|
||||
self.assertTrue(
|
||||
self.geo_model.geo_multi_polygon.equals_exact(
|
||||
multi_polygon_loaded, tolerance=0.2
|
||||
)
|
||||
)
|
||||
|
||||
def test_create_multipolygon_geojson_format(self):
|
||||
multi_polygon_geojson = """{"type":"MultiPolygon","coordinates":[[[
|
||||
[726469.938970306,5873145.03456248],[726520.174105436,5872946.03059195],
|
||||
[726394.076006275,5872675.04267336],[726404.709252018,5872259.98652277],
|
||||
[726212.557712441,5871801.78900894],[726471.645243121,5871748.01187117],
|
||||
[726384.798016214,5871474.60597039],[726524.862821204,5871416.52279756],
|
||||
[726560.408193573,5870936.9668625],[726765.583679957,5870941.58021817],
|
||||
[726800.675791552,5870794.8818083],[726830.398385972,5870610.25496982],
|
||||
[726667.324961485,5870525.33567258],[726559.158856422,5870713.41380138],
|
||||
[726483.618814776,5870842.15916191],[726282.880000044,5870874.76667995],
|
||||
[726075.942331799,5870940.79690473],[726060.620082161,5870636.20922038],
|
||||
[725995.373875086,5870504.36168216],[725871.917698916,5870508.73664946],
|
||||
[725866.910956205,5870440.22483982],[725760.074408205,5870513.2465806],
|
||||
[724947.130321146,5870506.55170525],[724956.64886783,5870684.35364044],
|
||||
[724709.437725183,5870717.82930599],[724640.837901402,5870502.91208435],
|
||||
[723632.716917063,5871035.58668793],[723353.587063504,5870580.71145654],
|
||||
[722975.340414945,5870644.60022452],[723063.193608096,5871187.48904965],
|
||||
[723286.565782157,5871691.25884814],[722865.254617585,5871951.28387527],
|
||||
[722963.962738856,5872074.84140304],[722831.245902295,5872122.76389775],
|
||||
[722813.837916803,5872242.00526964],[722827.655983236,5872300.44254147],
|
||||
[722913.370119188,5872418.02105384],[722942.233783707,5872432.93796481],
|
||||
[722984.741992683,5872520.85895895],[723012.381471722,5872637.73702376],
|
||||
[723086.082443995,5872667.76380156],[723157.229378648,5872668.62290333],
|
||||
[723214.748202491,5872698.34771906],[723250.508284339,5872761.5280976],
|
||||
[723286.16249158,5872815.86084868],[723315.028102666,5872830.77719621],
|
||||
[723502.328395902,5872819.6206505],[723518.483057357,5872818.65863173],
|
||||
[723567.82777813,5872844.15493286],[723749.413939088,5872937.98130854],
|
||||
[723848.429817139,5873019.41326079],[723893.228455684,5873056.25562596],
|
||||
[724000.782399525,5873179.05937195],[724022.179653074,5873203.48913931],
|
||||
[724167.213521721,5873219.79321866],[724240.443943894,5873257.62460164],
|
||||
[724345.033870514,5873311.65740904],[724427.033053176,5873354.0176493],
|
||||
[724458.116953997,5873354.38826826],[724601.342527281,5873356.09453768],
|
||||
[724659.368258544,5873356.78513641],[724699.259216658,5873263.86039926],
|
||||
[724734.038257937,5873182.84407915],[724769.196071982,5873148.4004069],
|
||||
[724792.808935311,5873125.2670227],[724828.594968331,5873107.84535952],
|
||||
[724909.660761314,5873068.37954232],[724968.429515518,5873010.80204763],
|
||||
[724969.116329931,5872952.53572905],[725027.883915669,5872894.95858978],
|
||||
[725144.902548535,5872823.50310579],[725202.982873244,5872824.19072548],
|
||||
[725231.165281494,5872845.9215328],[725260.549561619,5872868.5770444],
|
||||
[725323.492507265,5872998.67536266],[725345.617620278,5873044.40573114],
|
||||
[725374.316461685,5873073.88235996],[725461.097697554,5873104.044911],
|
||||
[725548.221016413,5873105.07306152],[725593.723206956,5873117.05713947],
|
||||
[725633.818030441,5873127.61507632],[725664.044374598,5873135.57621915],
|
||||
[725715.023293758,5873205.45921561],[725835.567474206,5873370.70034401],
|
||||
[725849.407491127,5873429.14029691],[725878.279489341,5873444.04917682],
|
||||
[725936.874293492,5873401.02996477],[725995.978527806,5873314.30901098],
|
||||
[726070.62161125,5873140.35732493],[726085.312084189,5873125.96087534],
|
||||
[726100.002508819,5873111.56442448],[726217.015284978,5873040.09276485],
|
||||
[726304.138055426,5873041.11333845],[726469.938970306,5873145.03456248]]]]}"""
|
||||
geo_dict = geojson.loads(multi_polygon_geojson)
|
||||
multi_polygon_loaded = shape(geo_dict)
|
||||
self.geo_model.geo_multi_polygon = multi_polygon_geojson
|
||||
self.assertTrue(
|
||||
self.geo_model.geo_multi_polygon.equals_exact(
|
||||
multi_polygon_loaded, tolerance=0.2
|
||||
)
|
||||
)
|
||||
|
||||
def test_create_polygon_wkt_format(self):
|
||||
"""Create a polygon"""
|
||||
polygon = """POLYGON((-95.80078125000001 40.09488212232117,
|
||||
-95.07568359375001 36.68604127658193,
|
||||
-90.439453125 37.80544394934273,-91.03271484375001 39.97712009843963,
|
||||
-95.80078125000001 40.09488212232117))"""
|
||||
polygon_loaded = wkt.loads(polygon)
|
||||
self.geo_model.geo_polygon = polygon
|
||||
self.assertTrue(
|
||||
self.geo_model.geo_polygon.equals_exact(polygon_loaded, tolerance=0.2)
|
||||
)
|
||||
|
||||
def test_create_polygon_geojson_format(self):
|
||||
polygon_geojson = """{"type":"Polygon","coordinates":[[
|
||||
[-95.80078125000001,40.09488212232117],
|
||||
[-95.07568359375001,36.68604127658193],[-90.439453125,37.80544394934273],
|
||||
[-91.03271484375001,39.97712009843963],[-95.80078125000001,40.09488212232117]]]}"""
|
||||
geo_dict = geojson.loads(polygon_geojson)
|
||||
polygon_loaded = shape(geo_dict)
|
||||
self.geo_model.geo_polygon = polygon_geojson
|
||||
self.assertTrue(
|
||||
self.geo_model.geo_polygon.equals_exact(polygon_loaded, tolerance=0.2)
|
||||
)
|
||||
|
||||
def test_create_line_wkt_format(self):
|
||||
"""Create a line"""
|
||||
line = """LINESTRING(-98.81103515625001 38.97649248553944,
|
||||
-90.06591796875 38.99357205820945)"""
|
||||
self.geo_model.geo_line = line
|
||||
line_loaded = wkt.loads(line)
|
||||
self.assertTrue(
|
||||
self.geo_model.geo_line.equals_exact(line_loaded, tolerance=0.2)
|
||||
)
|
||||
|
||||
def test_create_line_geosjon_format(self):
|
||||
line_geojson = """{"type":"LineString","coordinates":[
|
||||
[-98.81103515625001,38.97649248553944],
|
||||
[-90.06591796875,38.99357205820945]]}"""
|
||||
geo_dict = geojson.loads(line_geojson)
|
||||
line_loaded = shape(geo_dict)
|
||||
self.geo_model.geo_line = line_geojson
|
||||
self.assertTrue(
|
||||
self.geo_model.geo_line.equals_exact(line_loaded, tolerance=0.2)
|
||||
)
|
||||
|
||||
def test_create_point_wkt_format(self):
|
||||
"""Create a point"""
|
||||
point = "POINT(-99.2724609375 38.25543637637949)"
|
||||
self.geo_model.geo_point = point
|
||||
point_loaded = wkt.loads(point)
|
||||
self.assertTrue(
|
||||
self.geo_model.geo_point.equals_exact(point_loaded, tolerance=0.2)
|
||||
)
|
||||
|
||||
def test_create_point_geosjon_format(self):
|
||||
point_geosjon = (
|
||||
'{ "type": "Point", "coordinates": [-99.2724609375, 38.25543637637949] }'
|
||||
)
|
||||
geo_dict = geojson.loads(point_geosjon)
|
||||
point_loaded = shape(geo_dict)
|
||||
self.geo_model.geo_point = point_geosjon
|
||||
self.assertTrue(
|
||||
self.geo_model.geo_point.equals_exact(point_loaded, tolerance=0.2)
|
||||
)
|
||||
|
||||
def test_create_multi_line_wkt_format(self):
|
||||
"""Create multiline"""
|
||||
multi_line = (
|
||||
"MULTILINESTRING ((10 10, 20 20, 10 40),(40 40, 30 30, 40 20, 30 10))"
|
||||
)
|
||||
self.geo_model.geo_multi_line = multi_line
|
||||
multi_line_loaded = wkt.loads(multi_line)
|
||||
self.assertTrue(
|
||||
self.geo_model.geo_multi_line.equals_exact(multi_line_loaded, tolerance=0.2)
|
||||
)
|
||||
|
||||
def test_create_multi_line_geojson_format(self):
|
||||
multi_line_geojson = """{"type":"MultiLineString","coordinates":[[
|
||||
[10,10],[20,20],[10,40]],[[40,40],[30,30],[40,20],[30,10]]]}"""
|
||||
geo_dict = geojson.loads(multi_line_geojson)
|
||||
multi_line_loaded = shape(geo_dict)
|
||||
self.geo_model.geo_multi_line = multi_line_geojson
|
||||
self.assertTrue(
|
||||
self.geo_model.geo_multi_line.equals_exact(multi_line_loaded, tolerance=0.2)
|
||||
)
|
||||
|
||||
def test_create_multi_point_wkt_format(self):
|
||||
"""Create multipoint"""
|
||||
multi_point = "MULTIPOINT ((10 40), (40 30), (20 20), (30 10))"
|
||||
self.geo_model.geo_multi_point = multi_point
|
||||
multi_point_loaded = wkt.loads(multi_point)
|
||||
self.assertTrue(
|
||||
self.geo_model.geo_multi_point.equals_exact(
|
||||
multi_point_loaded, tolerance=0.2
|
||||
)
|
||||
)
|
||||
|
||||
def test_create_multi_point_geosjson_format(self):
|
||||
multi_point_geojson = (
|
||||
'{"type":"MultiPoint","coordinates":[[10,40],[40,30],[20,20],[30,10]]}'
|
||||
)
|
||||
geo_dict = geojson.loads(multi_point_geojson)
|
||||
multi_point_loaded = shape(geo_dict)
|
||||
self.geo_model.geo_multi_point = multi_point_geojson
|
||||
self.assertTrue(
|
||||
self.geo_model.geo_multi_point.equals_exact(
|
||||
multi_point_loaded, tolerance=0.2
|
||||
)
|
||||
)
|
||||
|
||||
def test_delete(self):
|
||||
self.geo_model.unlink()
|
||||
self.assertFalse(self.geo_model.exists())
|
||||
|
||||
def test_search_intersect_for_zip_1169(self):
|
||||
retails = self.env["retail.machine"]
|
||||
zip_item = self.env["dummy.zip"].search([("name", "ilike", "1169")])
|
||||
result = retails.search([("the_point", "geo_intersect", zip_item.the_geom)])
|
||||
self.assertEqual(len(result.ids), 2)
|
||||
result = retails.search(
|
||||
[
|
||||
(
|
||||
"the_point",
|
||||
"geo_intersect",
|
||||
{"dummy.zip.the_geom": [("id", "=", zip_item.id)]},
|
||||
)
|
||||
]
|
||||
)
|
||||
self.assertEqual(len(result.ids), 2)
|
||||
|
||||
def test_search_intersect_with_dict_id(self):
|
||||
retails = self.env["retail.machine"]
|
||||
result = retails.search(
|
||||
[
|
||||
(
|
||||
"the_point",
|
||||
"geo_intersect",
|
||||
{"dummy.zip.the_geom": [("id", "in", ["1"])]},
|
||||
)
|
||||
]
|
||||
)
|
||||
self.assertEqual(len(result.ids), 3)
|
||||
result = retails.search(
|
||||
[
|
||||
(
|
||||
"the_point",
|
||||
"geo_intersect",
|
||||
{"dummy.zip.the_geom": [("id", "in", ["2"])]},
|
||||
)
|
||||
]
|
||||
)
|
||||
self.assertEqual(len(result.ids), 2)
|
||||
result = retails.search(
|
||||
[
|
||||
(
|
||||
"the_point",
|
||||
"geo_intersect",
|
||||
{"dummy.zip.the_geom": [("id", "in", ["1", "2"])]},
|
||||
)
|
||||
]
|
||||
)
|
||||
self.assertEqual(len(result.ids), 5)
|
||||
|
||||
def test_search_intersect_for_zip_1169_with_multiple_domain(self):
|
||||
retails = self.env["retail.machine"]
|
||||
result = retails.search(
|
||||
[
|
||||
(
|
||||
"the_point",
|
||||
"geo_intersect",
|
||||
{
|
||||
"dummy.zip.the_geom": [
|
||||
("id", "in", ["1", "2"]),
|
||||
("name", "ilike", "1169"),
|
||||
]
|
||||
},
|
||||
)
|
||||
]
|
||||
)
|
||||
self.assertEqual(len(result.ids), 2)
|
||||
|
||||
def test_search_intersect_for_zip_1149(self):
|
||||
retails = self.env["retail.machine"]
|
||||
zip_item = self.env["dummy.zip"].search([("name", "ilike", "1146")])
|
||||
result = retails.search([("the_point", "geo_intersect", zip_item.the_geom)])
|
||||
self.assertEqual(len(result.ids), 3)
|
||||
|
||||
def test_search_contains_for_retails_34(self):
|
||||
zip_item = self.env["dummy.zip"]
|
||||
retails = self.env["retail.machine"].search([("name", "=", "34")])
|
||||
result = zip_item.search([("the_geom", "geo_contains", retails.the_point)])
|
||||
|
||||
self.assertEqual(1, len(result))
|
||||
self.assertEqual(result.city, "Yens")
|
||||
|
||||
result = zip_item.search(
|
||||
[
|
||||
(
|
||||
"the_geom",
|
||||
"geo_contains",
|
||||
{"retail.machine.the_point": [("id", "=", retails.id)]},
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
self.assertEqual(1, len(result))
|
||||
self.assertEqual(result.city, "Yens")
|
||||
|
||||
def test_search_contains_for_retails_21(self):
|
||||
zip_item = self.env["dummy.zip"]
|
||||
retails = self.env["retail.machine"].search([("name", "ilike", "21")])
|
||||
result = zip_item.search([("the_geom", "geo_contains", retails.the_point)])
|
||||
self.assertEqual(1, len(result))
|
||||
self.assertEqual(result.city, "Mollens (VD))")
|
||||
|
||||
def test_search_within_for_retails_34(self):
|
||||
retails = self.env["retail.machine"]
|
||||
zip_item = self.env["dummy.zip"].search([("city", "ilike", "Yens")])
|
||||
result = retails.search(
|
||||
[("name", "ilike", "34"), ("the_point", "geo_within", zip_item.the_geom)]
|
||||
)
|
||||
|
||||
self.assertEqual(1, len(result))
|
||||
self.assertEqual(result.name, "34")
|
||||
|
||||
result = retails.search(
|
||||
[
|
||||
("name", "ilike", "34"),
|
||||
(
|
||||
"the_point",
|
||||
"geo_within",
|
||||
{"dummy.zip.the_geom": [("id", "=", zip_item.id)]},
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
self.assertEqual(1, len(result))
|
||||
self.assertEqual(result.name, "34")
|
||||
|
||||
def test_search_within_for_retails_21(self):
|
||||
retails = self.env["retail.machine"]
|
||||
zip_item = self.env["dummy.zip"].search([("city", "ilike", "Mollens (VD))")])
|
||||
result = retails.search(
|
||||
[("name", "ilike", "21"), ("the_point", "geo_within", zip_item.the_geom)]
|
||||
)
|
||||
self.assertEqual(1, len(result))
|
||||
self.assertEqual(result.name, "21")
|
||||
|
||||
def test_search_equals(self):
|
||||
zip_item = self.env["dummy.zip"].search([("city", "ilike", "Mollens (VD))")])
|
||||
|
||||
result = zip_item.search(
|
||||
[
|
||||
(
|
||||
"the_geom",
|
||||
"geo_equal",
|
||||
{"dummy.zip.the_geom": [("name", "ilike", "1146")]},
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
self.assertEqual(1, len(result))
|
||||
self.assertEqual(result.city, "Mollens (VD))")
|
||||
|
||||
def test_search_touch_polygon(self):
|
||||
zip_item = self.env["dummy.zip"]
|
||||
|
||||
self.env["dummy.zip"].create(
|
||||
{
|
||||
"name": "10000",
|
||||
"city": "Poly1",
|
||||
"the_poly": "POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0))",
|
||||
}
|
||||
)
|
||||
|
||||
poly2 = self.env["dummy.zip"].create(
|
||||
{
|
||||
"name": "11000",
|
||||
"city": "Poly2",
|
||||
"the_poly": "POLYGON ((1 0, 1 1, 2 1, 2 0, 1 0))",
|
||||
}
|
||||
)
|
||||
result = zip_item.search([("the_poly", "geo_touch", poly2.the_poly)])
|
||||
|
||||
self.assertEqual(1, len(result))
|
||||
self.assertEqual(result.city, "Poly1")
|
||||
|
||||
result = zip_item.search(
|
||||
[("the_poly", "geo_touch", {"dummy.zip.the_poly": [("id", "=", poly2.id)]})]
|
||||
)
|
||||
|
||||
self.assertEqual(1, len(result))
|
||||
self.assertEqual(result.city, "Poly1")
|
||||
|
||||
def test_search_touch_multi_polygon(self):
|
||||
zip_item = self.env["dummy.zip"]
|
||||
self.env["dummy.zip"].create(
|
||||
{
|
||||
"name": "1192",
|
||||
"city": "Multi1",
|
||||
"the_geom": """MULTIPOLYGON (((0 0, 0 1, 1 1, 1 0, 0 0)),
|
||||
((1 0, 1 1, 2 1, 2 0, 1 0)))""",
|
||||
}
|
||||
)
|
||||
|
||||
multi_poly_2 = self.env["dummy.zip"].create(
|
||||
{
|
||||
"name": "6708",
|
||||
"city": "Multi2",
|
||||
"the_geom": """MULTIPOLYGON (((2 0, 2 1, 3 1, 3 0, 2 0)),
|
||||
((3 0, 3 1, 4 1, 4 0, 3 0)))""",
|
||||
}
|
||||
)
|
||||
result = zip_item.search([("the_geom", "geo_touch", multi_poly_2.the_geom)])
|
||||
|
||||
self.assertEqual(1, len(result))
|
||||
self.assertEqual(result.city, "Multi1")
|
||||
|
||||
def test_search_greater_multi_polygon(self):
|
||||
zip_item = self.env["dummy.zip"]
|
||||
mp1 = self.env["dummy.zip"].create(
|
||||
{
|
||||
"name": "1192",
|
||||
"city": "Mp1",
|
||||
"the_geom": """MULTIPOLYGON (((0 0, 0 5, 5 5, 5 0, 0 0)),
|
||||
((1 1, 2 1, 2 2, 1 2, 1 1)), ((3 3, 4 3, 4 4, 3 4, 3 3)))""",
|
||||
}
|
||||
)
|
||||
|
||||
self.env["dummy.zip"].create(
|
||||
{
|
||||
"name": "6708",
|
||||
"city": "Mp2",
|
||||
"the_geom": """MULTIPOLYGON (((-5 -5, -5 10, 10 10, 10 -5, -5 -5)),
|
||||
((-4 -4, -3 -4, -3 -3, -4 -3, -4 -4)), ((6 6, 7 6, 7 7, 6 7, 6 6)))""",
|
||||
}
|
||||
)
|
||||
result = zip_item.search(
|
||||
[("city", "ilike", "Mp2"), ("the_geom", "geo_greater", mp1.the_geom)]
|
||||
)
|
||||
self.assertEqual(1, len(result))
|
||||
self.assertEqual(result.city, "Mp2")
|
||||
|
||||
result = zip_item.search(
|
||||
[
|
||||
("city", "ilike", "Mp2"),
|
||||
(
|
||||
"the_geom",
|
||||
"geo_greater",
|
||||
{"dummy.zip.the_geom": [("id", "=", mp1.id)]},
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
self.assertEqual(1, len(result))
|
||||
self.assertEqual(result.city, "Mp2")
|
||||
|
||||
def test_search_lesser_multi_polygon(self):
|
||||
zip_item = self.env["dummy.zip"]
|
||||
self.env["dummy.zip"].create(
|
||||
{
|
||||
"name": "1192",
|
||||
"city": "Mp1",
|
||||
"the_geom": """MULTIPOLYGON (((0 0, 0 5, 5 5, 5 0, 0 0)),
|
||||
((1 1, 2 1, 2 2, 1 2, 1 1)), ((3 3, 4 3, 4 4, 3 4, 3 3)))""",
|
||||
}
|
||||
)
|
||||
|
||||
mp2 = self.env["dummy.zip"].create(
|
||||
{
|
||||
"name": "6708",
|
||||
"city": "Mp2",
|
||||
"the_geom": """MULTIPOLYGON (((-5 -5, -5 10, 10 10, 10 -5, -5 -5)),
|
||||
((-4 -4, -3 -4, -3 -3, -4 -3, -4 -4)), ((6 6, 7 6, 7 7, 6 7, 6 6)))""",
|
||||
}
|
||||
)
|
||||
result = zip_item.search(
|
||||
[("city", "ilike", "Mp1"), ("the_geom", "geo_lesser", mp2.the_geom)]
|
||||
)
|
||||
|
||||
self.assertEqual(1, len(result))
|
||||
self.assertEqual(result.city, "Mp1")
|
||||
|
||||
result = zip_item.search(
|
||||
[
|
||||
("city", "ilike", "Mp1"),
|
||||
(
|
||||
"the_geom",
|
||||
"geo_lesser",
|
||||
{"dummy.zip.the_geom": [("id", "=", mp2.id)]},
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
self.assertEqual(1, len(result))
|
||||
self.assertEqual(result.city, "Mp1")
|
||||
|
||||
def test_from_lat_lon(self):
|
||||
latitude = 49.72842315886126
|
||||
longitude = 5.400488376617026
|
||||
|
||||
# This is computed with postgis in postgres:
|
||||
|
||||
expected_coordinates = [601179.61612, 6399375.681364]
|
||||
|
||||
geo_point = GeoPoint.from_latlon(self.env.cr, latitude, longitude)
|
||||
|
||||
self.assertAlmostEqual(geo_point.x, expected_coordinates[0], 4)
|
||||
self.assertAlmostEqual(geo_point.y, expected_coordinates[1], 4)
|
||||
|
||||
def test_to_lat_lon(self):
|
||||
|
||||
geo_point = '{ "type": "Point", "coordinates": [601179.61612, 6399375.681364] }'
|
||||
|
||||
longitude, latitude = GeoPoint.to_latlon(self.env.cr, geo_point)
|
||||
|
||||
self.assertAlmostEqual(latitude, 49.72842315886126, 4)
|
||||
self.assertAlmostEqual(longitude, 5.400488376617026, 4)
|
||||
|
||||
def test_deprecated_geo_search__intersect_for_zip_1169(self):
|
||||
retails = self.env["retail.machine"]
|
||||
zip_item = self.env["dummy.zip"].search([("name", "ilike", "1169")])
|
||||
result = retails.geo_search(
|
||||
geo_domain=[("the_point", "geo_intersect", zip_item.the_geom)]
|
||||
)
|
||||
self.assertEqual(len(result), 2)
|
||||
|
||||
def test_deprecated_geo_search__intersect_for_zip_1169_with_dict(self):
|
||||
retails = self.env["retail.machine"]
|
||||
zip_item = self.env["dummy.zip"].search([("name", "ilike", "1169")])
|
||||
result = retails.geo_search(
|
||||
geo_domain=[
|
||||
(
|
||||
"the_point",
|
||||
"geo_intersect",
|
||||
{"dummy.zip.the_geom": [("id", "=", zip_item.id)]},
|
||||
)
|
||||
]
|
||||
)
|
||||
self.assertEqual(len(result), 2)
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
<menuitem
|
||||
name="GeoEngine Backend"
|
||||
id="geoengine_base_menu"
|
||||
web_icon="base_geoengine,images/map.png"
|
||||
groups="group_geoengine_admin"
|
||||
/>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
|
||||
<record model="ir.ui.view" id="geo_raster_view_form">
|
||||
<field name="name">geoengine.raster.layer.form</field>
|
||||
<field name="model">geoengine.raster.layer</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Raster Layer View">
|
||||
<sheet>
|
||||
<group string="General" col="4">
|
||||
<field name="name" />
|
||||
<field name="view_id" />
|
||||
<field name="raster_type" />
|
||||
<field name="sequence" />
|
||||
<field name="overlay" />
|
||||
<field name="use_to_edit" />
|
||||
<field
|
||||
name="url"
|
||||
colspan="4"
|
||||
widget="url"
|
||||
attrs="{'required': ['|',('is_wmts', '=', True),('is_wms', '=', True)]}"
|
||||
/>
|
||||
</group>
|
||||
<field name="is_wmts" invisible="1" />
|
||||
<group
|
||||
string="WMTS options"
|
||||
attrs="{'invisible': [('is_wmts', '=', False)]}"
|
||||
colspan="4"
|
||||
>
|
||||
<field
|
||||
name="matrix_set"
|
||||
attrs="{'required': [('is_wmts', '=', True)]}"
|
||||
/>
|
||||
<field
|
||||
name="format_suffix"
|
||||
attrs="{'required': [('is_wmts', '=', True)]}"
|
||||
/>
|
||||
<field name="request_encoding" />
|
||||
<field
|
||||
name="projection"
|
||||
attrs="{'required': [('is_wmts', '=', True)]}"
|
||||
/>
|
||||
<field name="units" /> <!-- Not used -->
|
||||
<field
|
||||
name="resolutions"
|
||||
attrs="{'required': [('is_wmts', '=', True)]}"
|
||||
/>
|
||||
<field name="max_extent" />
|
||||
<field name="dimensions" />
|
||||
<field name="params" />
|
||||
</group>
|
||||
<field name="is_wms" invisible="1" />
|
||||
<group
|
||||
string="WMS options"
|
||||
attrs="{'invisible': [('is_wms', '=', False)]}"
|
||||
colspan="4"
|
||||
>
|
||||
<field
|
||||
name="params_wms"
|
||||
attrs="{'required': [('is_wms', '=', True)]}"
|
||||
/>
|
||||
<field
|
||||
name="server_type"
|
||||
attrs="{'required': [('is_wms', '=', True)]}"
|
||||
/>
|
||||
</group>
|
||||
<field name="has_type" invisible="1" />
|
||||
<group
|
||||
string="Layer data"
|
||||
attrs="{'invisible': [('has_type', '=', False)]}"
|
||||
colspan="4"
|
||||
>
|
||||
<field
|
||||
name="type_id"
|
||||
widget="selection"
|
||||
attrs="{'required': [('has_type', '=', True)]}"
|
||||
/>
|
||||
</group>
|
||||
<group
|
||||
string="Odoo layer data (Not implemented)"
|
||||
attrs="{'invisible': [('raster_type', '!=', 'odoo')]}"
|
||||
colspan="4"
|
||||
>
|
||||
<field name="field_id" />
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="geo_raster_view_tree">
|
||||
<field name="name">geoengine.raster.layer.tree</field>
|
||||
<field name="model">geoengine.raster.layer</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree>
|
||||
<field name="name" select="1" />
|
||||
<field name="raster_type" select="1" />
|
||||
<field name="sequence" />
|
||||
<field name="overlay" select="1" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="geo_engine_view_rater_action" model="ir.actions.act_window">
|
||||
<field name="name">Raster Layer</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">geoengine.raster.layer</field>
|
||||
<field name="view_id" ref="geo_raster_view_tree" />
|
||||
</record>
|
||||
|
||||
<menuitem
|
||||
name="Raster Layer Management"
|
||||
id="geoengine_raster_layer_menu"
|
||||
parent="geoengine_base_view_menu"
|
||||
action="geo_engine_view_rater_action"
|
||||
groups="group_geoengine_admin"
|
||||
/>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,180 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
|
||||
<record model="ir.ui.view" id="geo_vector_view_form">
|
||||
<field name="name">geoengine.vector.layer.form</field>
|
||||
<field name="model">geoengine.vector.layer</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Vector">
|
||||
<sheet>
|
||||
<group string="General" col="4">
|
||||
<field name="name" />
|
||||
<field name="view_id" />
|
||||
<field name="geo_field_id" />
|
||||
<field
|
||||
name="attribute_field_id"
|
||||
attrs="{'required': [('geo_repr', 'in', ['choropleth', 'proportion', 'colored'])]}"
|
||||
/>
|
||||
<field name="active_on_startup" />
|
||||
<field name="display_polygon_labels" />
|
||||
<field name="sequence" />
|
||||
<field name="readonly" />
|
||||
<field name="layer_opacity" />
|
||||
</group>
|
||||
<group string="Related Model" col="4">
|
||||
<field name="model_id" />
|
||||
<field
|
||||
name="model_view_id"
|
||||
domain="[('mode', '=', 'geoengine')]"
|
||||
/>
|
||||
<field name="model_name" invisible="1" />
|
||||
<field
|
||||
name="model_domain"
|
||||
colspan="4"
|
||||
widget="domain"
|
||||
options="{'model': 'model_name'}"
|
||||
/>
|
||||
</group>
|
||||
<group string="Representation" col="4" colspan="4">
|
||||
<field name="geo_repr" />
|
||||
</group>
|
||||
<group
|
||||
string="Classification"
|
||||
colspan="4"
|
||||
attrs="{'invisible': [('geo_repr', '=', 'basic')]}"
|
||||
>
|
||||
<field
|
||||
name="classification"
|
||||
attrs="{'invisible': [('geo_repr', '=', 'basic')], 'required': [('geo_repr', 'in', ['choropleth', 'proportion', 'colored'])]}"
|
||||
/>
|
||||
</group>
|
||||
<group string="Colors" col="4" colspan="4">
|
||||
<field name="begin_color" widget="color" />
|
||||
<group
|
||||
colspan="4"
|
||||
attrs="{'invisible': [('geo_repr', 'in', ['basic', 'proportion'])]}"
|
||||
>
|
||||
<field
|
||||
name="end_color"
|
||||
attrs="{'invisible': [('classification', 'in', ['unique', False])], 'required': [('classification', 'in', ['interval', 'quantil'])]}"
|
||||
widget="color"
|
||||
/>
|
||||
<field
|
||||
name="nb_class"
|
||||
attrs="{'invisible': [('classification', 'in', ['unique', False])], 'required': [('classification', 'in', ['interval', 'quantil'])]}"
|
||||
/>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="geo_vector_geoengine_view_form">
|
||||
<field name="name">geoengine.vector.layer.geoengine.form</field>
|
||||
<field name="model">geoengine.vector.layer</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<sheet>
|
||||
<group string="General" col="4">
|
||||
<field name="name" />
|
||||
<field name="geo_field_id" />
|
||||
<field
|
||||
name="attribute_field_id"
|
||||
attrs="{'required': [('geo_repr', 'in', ['choropleth', 'proportion', 'colored'])]}"
|
||||
/>
|
||||
<field name="display_polygon_labels" />
|
||||
<field name="sequence" readonly="1" />
|
||||
<field name="readonly" />
|
||||
<field name="layer_opacity" />
|
||||
</group>
|
||||
<!-- <group string="Related Model" col="4">
|
||||
<field name="model_id" />
|
||||
<field
|
||||
name="model_view_id"
|
||||
domain="[('mode', '=', 'geoengine')]"
|
||||
/>
|
||||
<field name="model_name" invisible="1" />
|
||||
<field
|
||||
name="model_domain"
|
||||
colspan="4"
|
||||
widget="domain"
|
||||
options="{'model': 'model_name'}"
|
||||
/>
|
||||
</group> -->
|
||||
<group string="Representation" col="4" colspan="4">
|
||||
<field name="geo_repr" />
|
||||
</group>
|
||||
<group
|
||||
string="Classification"
|
||||
colspan="4"
|
||||
attrs="{'invisible': [('geo_repr', '=', 'basic')]}"
|
||||
>
|
||||
<field
|
||||
name="classification"
|
||||
attrs="{'invisible': [('geo_repr', '=', 'basic')], 'required': [('geo_repr', 'in', ['choropleth', 'proportion', 'colored'])]}"
|
||||
/>
|
||||
</group>
|
||||
<group string="Colors" col="4" colspan="4">
|
||||
<field name="begin_color" widget="color" />
|
||||
<group
|
||||
colspan="4"
|
||||
attrs="{'invisible': [('geo_repr', 'in', ['basic', 'proportion'])]}"
|
||||
>
|
||||
<field
|
||||
name="end_color"
|
||||
attrs="{'invisible': [('classification', 'in', ['unique', False])], 'required': [('classification', 'in', ['interval', 'quantil'])]}"
|
||||
widget="color"
|
||||
/>
|
||||
<field
|
||||
name="nb_class"
|
||||
attrs="{'invisible': [('classification', 'in', ['unique', False])], 'required': [('classification', 'in', ['interval', 'quantil'])]}"
|
||||
/>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="geo_vector_geoengine_view_action" model="ir.actions.act_window">
|
||||
<field name="name">Vector Layer</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">geoengine.vector.layer</field>
|
||||
<field name="target">new</field>
|
||||
<field name="view_id" ref="geo_vector_geoengine_view_form" />
|
||||
</record>
|
||||
|
||||
|
||||
<record model="ir.ui.view" id="geo_vector_view_tree">
|
||||
<field name="name">geoengine.vector.layer.tree</field>
|
||||
<field name="model">geoengine.vector.layer</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree>
|
||||
<field name="name" select="1" />
|
||||
<field name="geo_repr" select="1" />
|
||||
<field name="classification" select="1" />
|
||||
<field name="geo_field_id" select="1" />
|
||||
<field name="attribute_field_id" select="1" />
|
||||
<field name="active_on_startup" />
|
||||
<field name="sequence" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="geo_engine_view_raster_action" model="ir.actions.act_window">
|
||||
<field name="name">Vector Layer</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">geoengine.vector.layer</field>
|
||||
<field name="view_id" ref="geo_vector_view_tree" />
|
||||
</record>
|
||||
|
||||
<menuitem
|
||||
name="Vector Layer Management"
|
||||
id="geoengine_vector_layer_menu"
|
||||
parent="geoengine_base_view_menu"
|
||||
action="geo_engine_view_raster_action"
|
||||
groups="group_geoengine_admin"
|
||||
/>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
|
||||
<record model="ir.ui.view" id="view_model_fields_form_geo">
|
||||
<!-- must be unique in this module. -->
|
||||
<field name="name">ir.model.fields.form.geo</field>
|
||||
<field name="model">ir.model.fields</field>
|
||||
<field name="inherit_id" ref="base.view_model_fields_form" />
|
||||
<field name="arch" type="xml">
|
||||
<sheet position="inside">
|
||||
<group>
|
||||
<!-- nasty attrs but ilike operator does not work as expected -->
|
||||
<field
|
||||
name="srid"
|
||||
attrs="{'readonly': [('ttype', 'not in', ['geo_polygon', 'geo_multi_polygon', 'geo_point', 'geo_multi_point', 'geo_line', 'geo_multi_line'])]}"
|
||||
/>
|
||||
<field
|
||||
name="geo_type"
|
||||
attrs="{'readonly': [('ttype', 'not in', ['geo_polygon', 'geo_multi_polygon', 'geo_point', 'geo_multi_point', 'geo_line', 'geo_multi_line'])]}"
|
||||
/>
|
||||
<field
|
||||
name="dim"
|
||||
attrs="{'readonly': [('ttype', 'not in', ['geo_polygon', 'geo_multi_polygon', 'geo_point', 'geo_multi_point', 'geo_line', 'geo_multi_line'])]}"
|
||||
/>
|
||||
<field
|
||||
name="gist_index"
|
||||
attrs="{'readonly': [('ttype', 'not in', ['geo_polygon', 'geo_multi_polygon', 'geo_point', 'geo_multi_point', 'geo_line', 'geo_multi_line'])]}"
|
||||
/>
|
||||
</group>
|
||||
</sheet>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
|
||||
<record model="ir.ui.view" id="geoengine_view_form">
|
||||
<field name="name">geoengine.view.form</field>
|
||||
<field name="model">ir.ui.view</field>
|
||||
<field name="inherit_id" ref="base.view_view_form" />
|
||||
<field name="arch" type="xml">
|
||||
<notebook position="inside">
|
||||
<page
|
||||
string="GeoEngine Data"
|
||||
col="4"
|
||||
attrs="{'invisible': [('type', '!=', 'geoengine')]}"
|
||||
>
|
||||
<group>
|
||||
<field name="projection" />
|
||||
<field name="restricted_extent" />
|
||||
<field name="default_extent" />
|
||||
<field name="default_zoom" />
|
||||
</group>
|
||||
<separator string="Vector (Active layers)" colspan="4" />
|
||||
<field name="vector_layer_ids" colspan="4" nolabel="1" />
|
||||
<separator string="Raster (Background layers)" colspan="4" />
|
||||
<field name="raster_layer_ids" colspan="4" nolabel="1" />
|
||||
</page>
|
||||
</notebook>
|
||||
</field>
|
||||
</record>
|
||||
<menuitem
|
||||
name="Configuration"
|
||||
id="geoengine_base_view_menu"
|
||||
parent="geoengine_base_menu"
|
||||
groups="group_geoengine_admin"
|
||||
/>
|
||||
|
||||
<record id="geo_engine_view_action" model="ir.actions.act_window">
|
||||
<field name="name">Views</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">ir.ui.view</field>
|
||||
<field name="view_id" ref="base.view_view_tree" />
|
||||
<field name="search_view_id" ref="base.action_view_search" />
|
||||
<field name="domain">[('type', '=', 'geoengine')]</field>
|
||||
</record>
|
||||
|
||||
<menuitem
|
||||
name="View Management"
|
||||
id="geoengine_view_menu"
|
||||
parent="geoengine_base_view_menu"
|
||||
action="geo_engine_view_action"
|
||||
groups="group_geoengine_admin"
|
||||
/>
|
||||
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
# Architecture
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
U[Users] -->|HTTP| V[Views and QWeb Templates]
|
||||
V --> C[Controllers]
|
||||
V --> W[Wizards – Transient Models]
|
||||
C --> M[Models and ORM]
|
||||
W --> M
|
||||
M --> R[Reports]
|
||||
DX[Data XML] --> M
|
||||
S[Security – ACLs and Groups] -. enforces .-> M
|
||||
|
||||
subgraph Base_geoengine Module - base_geoengine
|
||||
direction LR
|
||||
M:::layer
|
||||
W:::layer
|
||||
C:::layer
|
||||
V:::layer
|
||||
R:::layer
|
||||
S:::layer
|
||||
DX:::layer
|
||||
end
|
||||
|
||||
classDef layer fill:#eef8ff,stroke:#6ea8fe,stroke-width:1px
|
||||
```
|
||||
|
||||
Notes
|
||||
- Views include tree/form/kanban templates and report templates.
|
||||
- Controllers provide website/portal routes when present.
|
||||
- Wizards are UI flows implemented with `models.TransientModel`.
|
||||
- Data XML loads data/demo records; Security defines groups and access.
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# Configuration
|
||||
|
||||
Refer to Odoo settings for base_geoengine. Configure related models, access rights, and options as needed.
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# Controllers
|
||||
|
||||
This module does not define custom HTTP controllers.
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
# Dependencies
|
||||
|
||||
This addon depends on:
|
||||
|
||||
- base
|
||||
- [web](../../odoo-bringout-oca-ocb-web)
|
||||
4
odoo-bringout-oca-geospatial-base_geoengine/doc/FAQ.md
Normal file
4
odoo-bringout-oca-geospatial-base_geoengine/doc/FAQ.md
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
# FAQ
|
||||
|
||||
- Q: Which Odoo version? A: 16.0 (OCA/OCB packaged).
|
||||
- Q: How to enable? A: Start server with --addon base_geoengine or install in UI.
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
# Install
|
||||
|
||||
```bash
|
||||
pip install odoo-bringout-oca-geospatial-base_geoengine"
|
||||
# or
|
||||
uv pip install odoo-bringout-oca-geospatial-base_geoengine"
|
||||
```
|
||||
17
odoo-bringout-oca-geospatial-base_geoengine/doc/MODELS.md
Normal file
17
odoo-bringout-oca-geospatial-base_geoengine/doc/MODELS.md
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
# Models
|
||||
|
||||
Detected core models and extensions in base_geoengine.
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class geoengine_raster_layer
|
||||
class geoengine_raster_layer_type
|
||||
class geoengine_vector_layer
|
||||
class base
|
||||
class ir_model_fields
|
||||
class ir_ui_view
|
||||
```
|
||||
|
||||
Notes
|
||||
- Classes show model technical names; fields omitted for brevity.
|
||||
- Items listed under _inherit are extensions of existing models.
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
# Overview
|
||||
|
||||
Packaged Odoo addon: base_geoengine. Provides features documented in upstream Odoo 16 under this addon.
|
||||
|
||||
- Source: OCA/OCB 16.0, addon base_geoengine
|
||||
- License: LGPL-3
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# Reports
|
||||
|
||||
This module does not define custom reports.
|
||||
42
odoo-bringout-oca-geospatial-base_geoengine/doc/SECURITY.md
Normal file
42
odoo-bringout-oca-geospatial-base_geoengine/doc/SECURITY.md
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
# Security
|
||||
|
||||
Access control and security definitions in base_geoengine.
|
||||
|
||||
## Access Control Lists (ACLs)
|
||||
|
||||
Model access permissions defined in:
|
||||
- **[ir.model.access.csv](../base_geoengine/security/ir.model.access.csv)**
|
||||
- 6 model access rules
|
||||
|
||||
## Record Rules
|
||||
|
||||
Row-level security rules defined in:
|
||||
|
||||
## Security Groups & Configuration
|
||||
|
||||
Security groups and permissions defined in:
|
||||
- **[data.xml](../base_geoengine/security/data.xml)**
|
||||
- 4 security groups defined
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "Security Layers"
|
||||
A[Users] --> B[Groups]
|
||||
B --> C[Access Control Lists]
|
||||
C --> D[Models]
|
||||
B --> E[Record Rules]
|
||||
E --> F[Individual Records]
|
||||
end
|
||||
```
|
||||
|
||||
Security files overview:
|
||||
- **[data.xml](../base_geoengine/security/data.xml)**
|
||||
- Security groups, categories, and XML-based rules
|
||||
- **[ir.model.access.csv](../base_geoengine/security/ir.model.access.csv)**
|
||||
- Model access permissions (CRUD rights)
|
||||
|
||||
Notes
|
||||
- Access Control Lists define which groups can access which models
|
||||
- Record Rules provide row-level security (filter records by user/group)
|
||||
- Security groups organize users and define permission sets
|
||||
- All security is enforced at the ORM level by Odoo
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
# Troubleshooting
|
||||
|
||||
- Ensure Python and Odoo environment matches repo guidance.
|
||||
- Check database connectivity and logs if startup fails.
|
||||
- Validate that dependent addons listed in DEPENDENCIES.md are installed.
|
||||
7
odoo-bringout-oca-geospatial-base_geoengine/doc/USAGE.md
Normal file
7
odoo-bringout-oca-geospatial-base_geoengine/doc/USAGE.md
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# Usage
|
||||
|
||||
Start Odoo including this addon (from repo root):
|
||||
|
||||
```bash
|
||||
python3 scripts/nix_odoo_web_server.py --db-name mydb --addon base_geoengine
|
||||
```
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# Wizards
|
||||
|
||||
This module does not include UI wizards.
|
||||
43
odoo-bringout-oca-geospatial-base_geoengine/pyproject.toml
Normal file
43
odoo-bringout-oca-geospatial-base_geoengine/pyproject.toml
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
[project]
|
||||
name = "odoo-bringout-oca-geospatial-base_geoengine"
|
||||
version = "16.0.0"
|
||||
description = "Geospatial support for Odoo - Odoo addon"
|
||||
authors = [
|
||||
{ name = "Ernad Husremovic", email = "hernad@bring.out.ba" }
|
||||
]
|
||||
dependencies = [
|
||||
"odoo-bringout-oca-ocb-base>=16.0.0",
|
||||
"odoo-bringout-oca-ocb-web>=16.0.0",
|
||||
"requests>=2.25.1"
|
||||
]
|
||||
readme = "README.md"
|
||||
requires-python = ">= 3.11"
|
||||
classifiers = [
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
"Intended Audience :: Developers",
|
||||
"License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
"Programming Language :: Python :: 3.12",
|
||||
"Topic :: Office/Business",
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
homepage = "https://github.com/bringout/0"
|
||||
repository = "https://github.com/bringout/0"
|
||||
|
||||
[build-system]
|
||||
requires = ["hatchling"]
|
||||
build-backend = "hatchling.build"
|
||||
|
||||
[tool.hatch.metadata]
|
||||
allow-direct-references = true
|
||||
|
||||
[tool.hatch.build.targets.wheel]
|
||||
packages = ["base_geoengine"]
|
||||
|
||||
[tool.rye]
|
||||
managed = true
|
||||
dev-dependencies = [
|
||||
"pytest>=8.4.1",
|
||||
]
|
||||
Loading…
Add table
Add a link
Reference in a new issue