def situation_map_gen(cls, records): """Render the situation map""" CadPlot = Pool().get('cadastre.parcelle') Plot = Pool().get('forest.plot') for record in records: cad_plots = [plot.geom for plot in record.cad_plots] cad_plots, envelope, cad_area = get_as_epsg4326(cad_plots) plots = [plot.geom for plot in record.plots] plots, plot_bbox, _plots_area = get_as_epsg4326(plots) if envelope is None: continue # Compute the envelope if plot_bbox is not None: envelope = envelope_union(envelope, plot_bbox) # Include the geometry of the town in the bbox of the map if record.address is not None and record.address.my_city is not None: # Include the town from the address in the bbox town_geo = osr_geo_from_field(record.address.my_city.contour) dst = osr.SpatialReference() dst.SetWellKnownGeogCS("EPSG:4326") town_geo.TransformTo(dst) envelope = envelope_union(envelope, town_geo.GetEnvelope()) # Map title title = u'Plan de situation\n' title += u'Propriétaire: %s\n' % record.owner.name if record.address is not None \ and record.address.city is not None \ and record.address.my_city is not None: city = record.address.city dep = record.address.my_city.subdivision.parent.code.split('-')[1] title += u'Commune: %s (%s)\n' % (city, dep) title += u'Surface: %02i ha %02i a %02i ca\n\nLe ' % cls._area_to_a(cad_area) title += date.today().strftime('%02d/%02m/%Y') m = MapRender(1024, 768, envelope, True) m.add_bg() for plot in cad_plots: m.plot_geom(plot, None, u'Bois de La Forêt', color=CadPlot.COLOR, bgcolor=CadPlot.BGCOLOR) for plot in plots: m.plot_geom(plot, None, u'Parcelle forestière', linestyle='--', color=Plot.COLOR, bgcolor=Plot.BGCOLOR) data_nl = m.render() m.plot_legend() m.plot_compass() m.plot_scaling() cls._plot_logo(m) m.plot_title(title) data = m.render() cls.write([record], { 'situation_map': buffer(data), 'situation_map_nl': buffer(data_nl), })
def generate(cls, records): for record in records: if record.address is None: continue town, envelope, area = get_as_epsg4326([record.address.my_city.contour]) # Calcule de la bbox contenant tout les points _envelope = None for points in cls.search([]): _points, envelope, _area = get_as_epsg4326([points.geom]) if envelope is None: continue _envelope = envelope_union(envelope, _envelope) # Léger dézoom pour afficher correctement les points qui touchent la bbox envelope = [ _envelope[0] - 0.001, _envelope[1] + 0.001, _envelope[2] - 0.001, _envelope[3] + 0.001, ] m = MapRender(640, 480, envelope, True) m.add_bg() for entry in cls.search([]): points, _envelope, _area = get_as_epsg4326([entry.geom]) if len(points) == 0: continue if record == entry: m.plot_geom(points[0], None, None, color=cls.COLOR, bgcolor=cls.BGCOLOR) else: m.plot_geom(points[0], None, None, color=(0, 0, 1, 1), bgcolor=cls.BGCOLOR) data = m.render() cls.write([record], {'image_map': buffer(data)})
def situation_map_gen(cls, records): """Render the situation map""" for record in records: # Récupère l'étendu de la zone de travaux areas, _envelope, _area = get_as_epsg4326([record.geom]) # Léger dézoom pour afficher correctement les points qui touchent la bbox envelope = [ _envelope[0] - 0.001, _envelope[1] + 0.001, _envelope[2] - 0.001, _envelope[3] + 0.001, ] if envelope is None: continue # Include the geometry of the town in the bbox of the map if record.commune is not None and record.commune.name is not None: # Include the town from the commune in the bbox town_geo = osr_geo_from_field(record.commune.contour) dst = osr.SpatialReference() dst.SetWellKnownGeogCS("EPSG:4326") town_geo.TransformTo(dst) envelope = envelope_union(envelope, town_geo.GetEnvelope()) # Map title title = u'Plan de situation communal\n' title += u'Propriétaire: %s\n' % record.owner.name if record.commune is not None \ and record.commune.name is not None \ and record.commune.name is not None: city = record.commune.name dep = record.commune.subdivision.parent.code.split('-')[1] title += u'Commune: %s (%s)\n' % (city, dep) title += u'Surface: %02i ha %02i a %02i ca\n\nLe ' % cls._area_to_a(_area) title += date.today().strftime('%02d/%02m/%Y') m = MapRender(1024, 768, envelope, True) # Ajoute le fond de carte m.add_bg() # Ajoute la zone de chantier m.plot_geom(areas[0], None, u'Site', color=cls.COLOR, bgcolor=cls.BGCOLOR) data_nl = m.render() m.plot_legend() m.plot_compass() m.plot_scaling() cls._plot_logo(m) m.plot_title(title) data = m.render() cls.write([record], { 'situation_map': buffer(data), })
def situation_closeup_map_gen(cls, records): """Render the situation map closeup""" CadPlot = Pool().get('cadastre.parcelle') Plot = Pool().get('forest.plot') for record in records: cad_plots = [plot.geom for plot in record.cad_plots] cad_plots, envelope, cad_area = get_as_epsg4326(cad_plots) plots = [plot.geom for plot in record.plots] plots, plot_bbox, _plots_area = get_as_epsg4326(plots) if envelope is None: continue # Compute the envelope if plot_bbox is not None: envelope = envelope_union(envelope, plot_bbox) # Map title title = u'Plan de situation\n' title += u'Propriétaire: %s\n' % record.owner.name if record.address is not None \ and record.address.city is not None \ and record.address.my_city is not None: city = record.address.city dep = record.address.my_city.subdivision.parent.code.split('-')[1] title += u'Commune: %s (%s)\n' % (city, dep) title += u'Surface: %02i ha %02i a %02i ca\n\nLe ' % cls._area_to_a(cad_area) title += date.today().strftime('%02d/%02m/%Y') m = MapRender(1024, 768, envelope, True) m.add_bg() cls._plot_misc_areas(m, record, False) for plot in cad_plots: m.plot_geom(plot, None, u'Bois de La Forêt', color=CadPlot.COLOR, bgcolor=CadPlot.BGCOLOR) for plot, rec in zip(plots, record.plots): m.plot_geom(plot, rec.short_name, None, linestyle='--', color=Plot.COLOR, bgcolor=Plot.BGCOLOR) cls._plot_misc_points(m, record, False) data_nl = m.render() m.plot_legend() m.plot_compass() m.plot_scaling() cls._plot_logo(m) m.plot_title(title) data = m.render() cls.write([record], { 'situation_closeup_map': buffer(data), 'situation_closeup_map_nl': buffer(data_nl), })
def get_image(self, ids): if self.forest is None: return buffer("") MiscObj = Pool().get(self.__name__) CadPlot = Pool().get("forest.cad_plot") objs = MiscObj.search([("forest", "=", self.forest.id)]) misc_obj, envelope, area = get_as_epsg4326([obj.geom for obj in objs]) if misc_obj == []: return buffer("") cad_plots = [plot.geom for plot in self.forest.cad_plots] if cad_plots != []: cad_plots, cad_bbox, cad_area = get_as_epsg4326(cad_plots) envelope = envelope_union(envelope, cad_bbox) envelope = bbox_aspect(envelope, 640, 480) m = MapRender(640, 480, envelope) for plot in cad_plots: m.plot_geom(plot, None, None, color=CadPlot.COLOR, bgcolor=CadPlot.BGCOLOR) m.plot_geom(get_as_epsg4326([self.geom])[0][0], None, None, color=self.COLOR, bgcolor=self.BGCOLOR) return buffer(m.render())
def tracks_map_gen(cls, records): """Render the tracks map""" Tracks = Pool().get('forest.track') CadPlot = Pool().get('cadastre.parcelle') Plot = Pool().get('forest.plot') for record in records: cad_plots = [plot.geom for plot in record.cad_plots] cad_plots, envelope, cad_area = get_as_epsg4326(cad_plots) plots = [plot.geom for plot in record.plots] plots, plot_bbox, _plots_area = get_as_epsg4326(plots) tracks = [track.geom for track in record.tracks] tracks, _tracks_bbox, _tracks_area = get_as_epsg4326(tracks) if envelope is None: continue # Compute the envelope if plot_bbox is not None: envelope = envelope_union(envelope, plot_bbox) # Map title title = u'Carte de la desserte\n' title += u'Propriétaire: %s\n' % record.owner.name if record.address is not None \ and record.address.city is not None \ and record.address.my_city is not None: city = record.address.city dep = record.address.my_city.subdivision.parent.code.split('-')[1] title += u'Commune: %s (%s)\n' % (city, dep) title += u'Surface: %02i ha %02i a %02i ca\n\nLe ' % cls._area_to_a(cad_area) title += date.today().strftime('%02d/%02m/%Y') # Cadastral plots m = MapRender(1024, 768, envelope, True) for plot, rec in zip(cad_plots, record.cad_plots): m.plot_geom(plot, None, None, color=CadPlot.COLOR) cls._plot_misc_areas(m, record) # Forest plots for plot, rec in zip(plots, record.plots): m.plot_geom(plot, rec.short_name, u'Parcelle forestière', linestyle='--', color=Plot.COLOR, bgcolor=Plot.BGCOLOR) # Track plots # Legend Track #gris colgris = (0, 0, 0, 0.3) #rouge colred = (1, 0, 0, 1) #jaune colyel = (1, 1, 0, 1) #blanc colwhi = (0, 0, 0, 1) m.add_legend(str('Piste'), '-', color=colwhi, bgstyle='-', bgcolor=colwhi) m.add_legend(str('Route en terrain naturel'), '-', color=colyel, bgstyle='-', bgcolor=colyel) m.add_legend(str('Route empierrée'), '-', color=colred, bgstyle='-', bgcolor=colred) m.add_legend(str('Route goudronnée'), '-', color=colgris, bgstyle='-', bgcolor=colgris) # Track for track, rec in zip(tracks, record.tracks): if rec.typo == 'rgou': m.plot_geom(track, rec.name, None, color=colgris, bgcolor=colgris) elif rec.typo == 'remp': m.plot_geom(track, rec.name, None, color=colred, bgcolor=colred) elif rec.typo == 'rternat': m.plot_geom(track, rec.name, None, color=colyel, bgcolor=colyel) else: m.plot_geom(track, rec.name, None, color=colwhi, bgcolor=colwhi) cls._plot_misc_points(m, record) m.plot_legend() m.plot_compass() m.plot_scaling() cls._plot_logo(m) m.plot_title(title) data = m.render() cls.write([record], {'tracks_map': buffer(data)})
def varieties_map_gen(cls, records): """Render the varieties map""" Varieties = Pool().get('forest.variety') CadPlot = Pool().get('cadastre.parcelle') Plot = Pool().get('forest.plot') for record in records: cad_plots = [plot.geom for plot in record.cad_plots] cad_plots, envelope, cad_area = get_as_epsg4326(cad_plots) plots = [plot.geom for plot in record.plots] plots, plot_bbox, _plots_area = get_as_epsg4326(plots) varieties = [variety.geom for variety in record.varieties] varieties, _varieties_bbox, _varieties_area = get_as_epsg4326(varieties) if envelope is None: continue # Compute the envelope if plot_bbox is not None: envelope = envelope_union(envelope, plot_bbox) # Map title title = u'Carte des peuplements\n' title += u'Propriétaire: %s\n' % record.owner.name if record.address is not None \ and record.address.city is not None \ and record.address.my_city is not None: city = record.address.city dep = record.address.my_city.subdivision.parent.code.split('-')[1] title += u'Commune: %s (%s)\n' % (city, dep) title += u'Surface: %02i ha %02i a %02i ca\n\nLe ' % cls._area_to_a(cad_area) title += date.today().strftime('%02d/%02m/%Y') # Cadastral plots m = MapRender(1024, 768, envelope, True) for plot, rec in zip(cad_plots, record.cad_plots): m.plot_geom(plot, None, None, color=CadPlot.COLOR) cls._plot_misc_areas(m, record) # Stand plots # Legend Stand for stand, rec in zip(varieties, record.varieties): if rec.stand is None: bgcolor = (0, 0, 0, 0) else: r = float(rec.stand.r)/float(255) g = float(rec.stand.g)/float(255) b = float(rec.stand.b)/float(255) bgcolor = (r, g, b, 1) m.add_legend(rec.stand.name, '-', color=(0, 0, 0, 1), bgstyle='-', bgcolor=bgcolor) # Stand for stand, rec in zip(varieties, record.varieties): if rec.stand is None: bgcolor = (0, 0, 0, 0) else: r = float(rec.stand.r)/float(255) g = float(rec.stand.g)/float(255) b = float(rec.stand.b)/float(255) bgcolor = (r, g, b, 1) m.plot_geom(stand, None, None, color=(0, 0, 0, 1), bgcolor=bgcolor) # Legend Dom Species 1 for stand, rec in zip(varieties, record.varieties): if rec.domspecies1 is None: bgcolor = (0, 0, 0, 0) else: r = float(rec.domspecies1.r)/float(255) g = float(rec.domspecies1.g)/float(255) b = float(rec.domspecies1.b)/float(255) bgcolor = (r, g, b, 1) m.add_legend(rec.domspecies1.name, '-', color=(0, 0, 0, 1), bgstyle = None, bgcolor=bgcolor) # Dom Species 1 for stand, rec in zip(varieties, record.varieties): if rec.domspecies1 is None: bgcolor = (0, 0, 0, 0) bgstyle = '.' else: r = float(rec.domspecies1.r)/float(255) g = float(rec.domspecies1.g)/float(255) b = float(rec.domspecies1.b)/float(255) bgcolor = (r, g, b, 1) bgstyle = rec.domspecies1.form m.plot_geom(stand, None, None, color=(0, 0, 0, 1), bgstyle=bgstyle, bgcolor=bgcolor) # Forest plots for plot, rec in zip(plots, record.plots): m.plot_geom(plot, rec.short_name, u'Parcelle forestière', linestyle='--', color=Plot.COLOR, bgcolor=Plot.BGCOLOR) cls._plot_misc_points(m, record) m.plot_legend() m.plot_compass() m.plot_scaling() cls._plot_logo(m) m.plot_title(title) data = m.render() cls.write([record], {'varieties_map': buffer(data)})
def situation_map_gen(cls, records): """Render the situation map""" for record in records: _envelope = None # Récupère les géométries de la zone d'information aires = [aire.geom for aire in record.pres_obj_poly] aires, _aires_bbox, _aires_area = get_as_epsg4326(aires) if _aires_bbox is None: _envelope = _envelope else: _envelope = envelope_union(_aires_bbox, _envelope) lignes = [ligne.geom for ligne in record.pres_obj_line] lignes, _lignes_bbox, _lignes_area = get_as_epsg4326(lignes) if _lignes_bbox is None: _envelope = _envelope else: _envelope = envelope_union(_lignes_bbox, _envelope) points = [point.geom for point in record.pres_obj_point] points, _points_bbox, _points_area = get_as_epsg4326(points) if _points_bbox is None: _envelope = _envelope else: _envelope = envelope_union(_points_bbox, _envelope) # Léger dézoom pour afficher correctement les points qui touchent la bbox envelope = [ _envelope[0] - 0.001, _envelope[1] + 0.001, _envelope[2] - 0.001, _envelope[3] + 0.001, ] # Map title title = u'Plan de situation\n' title += u'Surface: %02i ha %02i a %02i ca\n\nLe ' % cls._area_to_a(_aires_area) title += date.today().strftime('%02d/%02m/%Y') m = MapRender(1024, 768, envelope, True) # Ajoute le fond de carte m.add_bg() # Ajoute les polygones for aire, rec in zip(aires, record.pres_obj_poly): m.plot_geom(aire, rec.name, u'Zones', color=(1, 1, 1, 1), bgcolor=(0, 0, 1, 0.2)) # Ajoute les polylignes for ligne, rec in zip(lignes, record.pres_obj_line): m.plot_geom(ligne, rec.name, None, color=(1, 1, 1, 1), bgcolor=(1, 1, 1, 1)) # Ajoute les points for point, rec in zip(points, record.pres_obj_point): m.plot_geom(point, rec.name, None, color=(1, 1, 1, 1), bgcolor=(1, 1, 1, 1)) data_nl = m.render() m.plot_legend() m.plot_compass() m.plot_scaling() cls._plot_logo(m) m.plot_title(title) data = m.render() cls.write([record], { 'situation_map': buffer(data), })
def parse(cls, report, records, data, localcontext): """Create QGis project file based on the selected record: the fields referenced in the model FIELDS variable will each have a separate layer in the renderd file. """ User = Pool().get('res.user') Translation = Pool().get('ir.translation') filename = os.path.join(os.path.dirname(__file__), 'qgis.qgs') report = RelatorioReport(filename, 'text/plain', ReportFactory(), MIMETemplateLoader()) QGisConf = Pool().get('qgis.conf') conf = QGisConf.search([]) if len(conf) != 0: version = conf[0].version else: version = '1.9.0-Master' legend = OrderedDict() if cls.FIELDS is None: layers, bbox, srid = cls.get_layer(records, records[0].__name__) for layer in layers: legend[layer['title']] = layer else: layers = [] bbox = None Model = Pool().get(records[0].__name__) for field, val in cls.FIELDS.iteritems(): if val is None: fields = [field] else: fields = val.keys() sublayers = [] for _field in fields: recs = getattr(records[0], _field) relation = getattr(Model, _field).model_name _layers, _bbox, srid = cls.get_layer(recs, relation) if _bbox is not None: bbox = envelope_union(_bbox, bbox) sublayers += _layers # Remove sublayers that are already added _sublayers = [] for layer in sublayers: if layer['model'] in [_layer['model'] for _layer in layers]: continue _sublayers.append(layer) sublayers = _sublayers layers += sublayers if val is None: for layer in sublayers: legend[layer['title']] = layer else: if field not in legend: legend[field] = OrderedDict() for layer in sublayers: legend[field][layer['title']] = layer if bbox is None: bbox = [ -357823.2365, 6037008.6939, 1313632.3628, 7230727.3772 ] WfsConf = Pool().get('wfs.conf') wfs_url = WfsConf.get_url() localcontext.update({ 'data': data, 'user': User(Transaction().user), 'formatLang': cls.format_lang, 'StringIO': StringIO.StringIO, 'time': time, 'datetime': datetime, 'context': Transaction().context, 'qgis_version': version, 'wfs_url': wfs_url, 'bbox': bbox, 'srid': srid, 'layers': layers, 'legend': legend, }) translate = TranslateFactory(cls.__name__, Transaction().language, Translation) localcontext['setLang'] = lambda language: translate.set_language(language) translator = Translator(lambda text: translate(text)) report.filters.insert(0, translator) localcontext = dict(map(lambda x: (str(x[0]), x[1]), localcontext.iteritems())) #Test compatibility with old relatorio version <= 0.3.0 if len(inspect.getargspec(report.__call__)[0]) == 2: data = report(records, **localcontext).render().getvalue() else: localcontext['objects'] = records # XXX to remove localcontext['records'] = records data = report(**localcontext).render() if hasattr(data, 'getvalue'): data = data.getvalue() return ('qgs', data)
def get_layer(cls, records, model_name): """Return parameters for the model @model_name@. If some records of the model are not contained in @records@, then those record are returned in a separate layer that will is displayed as "Unselected" values. """ # Look for a geometric field Field = Pool().get('ir.model.field') Model = Pool().get('ir.model') RecordModel = Pool().get(model_name) geo_field_name = '' geo_field = None m2o_fields = [] for attr_name in dir(RecordModel): if attr_name in TRYTON_FIELDS: continue attr = getattr(RecordModel, attr_name) if isinstance(attr, fields.Many2One): m2o_fields.append(attr) if isinstance(attr, fields.Geometry): geo_field = attr geo_field_name = attr_name bbox = None unselected = set() srid = getattr(RecordModel, geo_field_name).srid for record in records: geo_value = getattr(record, geo_field_name) if geo_value is not None: geo = osr_geo_from_field(geo_value) bbox = envelope_union(geo.GetEnvelope(), bbox) # Look for unselected related records for m2o_field in m2o_fields: # Find the corresponding one2many field in the parent parent_model = Model.search([('model', '=', m2o_field.model_name)], limit=1)[0] Parent = Pool().get(m2o_field.model_name) o2mfield = Field.search([('ttype', '=', 'one2many'), ('model', '=', parent_model.id)]) for o2m in o2mfield: parent_field = getattr(Parent, o2m.name) if parent_field.model_name == model_name and m2o_field.name == parent_field.field: break else: continue for record in records: parent_record = getattr(record, m2o_field.name) for child in getattr(parent_record, parent_field.name): if child in records: continue unselected.add(child.id) break layers = [] layers.append({ 'model': model_name, 'title': cls.TITLES.get(model_name, RecordModel.__doc__), 'layerid': 'tryton_%s' % model_name.replace('.', '_'), 'geo': True, 'srid': srid, 'filter': get_wfs_id_filter(sorted([record.id for record in records])), 'color': cls._qgis_color(RecordModel.BGCOLOR), 'color_border': cls._qgis_color(RecordModel.COLOR), 'edittypes': {'id': {'type': QGIS_WIDGET_HIDDEN}}, 'geo_type': TRYTON_TO_QGIS[geo_field._type], 'unfolded': 'true', 'aliases': cls._get_aliases(model_name), }) if len(unselected) != 0: layers.append({ 'model': model_name, 'title': cls.TITLES.get(model_name, RecordModel.__doc__) + ' (unselected)', 'layerid': 'tryton_unselected_%s' % model_name.replace('.', '_'), 'geo': True, 'srid': srid, 'filter': get_wfs_id_filter(sorted(unselected)), 'color': '255,255,255,0', 'color_border': cls._qgis_color(RecordModel.BGCOLOR), 'edittypes': {'id': {'type': QGIS_WIDGET_HIDDEN}}, 'geo_type': TRYTON_TO_QGIS[geo_field._type], 'unfolded': 'false', 'aliases': cls._get_aliases(model_name), }) base_layers = layers deps_models = set() Record = Pool().get(model_name) symbols = [] # Add dependency tables for m2o_field in m2o_fields: # Find the corresponding one2many field in the parent other_model_name = getattr(Record, m2o_field.name).model_name OtherModel = Pool().get(other_model_name) other_model = Model.search([('model', '=', other_model_name)], limit=1)[0] if OtherModel in deps_models: continue deps_models.add(OtherModel) layer_id = 'tryton_%s' % other_model.model.replace('.', '_') layers.append({ 'model': other_model.model, 'title': cls.TITLES.get(other_model.model, other_model.name), 'layerid': layer_id, 'geo': False, 'filter': None, 'edittypes': {'id': {'type': QGIS_WIDGET_HIDDEN}}, 'unfolded': 'false', 'aliases': cls._get_aliases(other_model.model), }) for layer in base_layers: layer['edittypes'][m2o_field.name] = { 'type': QGIS_WIDGET_RELATIONAL, 'layer': layer_id, 'value': 'name', } if symbols == [] and (parent_model is None or other_model_name != parent_model.model): symbol_recs = Record.search([('id', 'in', list(unselected) + [record.id for record in records])]) symbol_recs = set([getattr(symbol_rec, m2o_field.name) for symbol_rec in symbol_recs]) symbol_recs -= set([None]) for no, symbol in enumerate(symbol_recs): color = no * 255 / len(symbol_recs) symbols.append({ 'no': no, 'value': symbol.id, 'label': symbol.rec_name, 'color': '%i,%i,255,255' % (color, color), 'color_border': '0,0,0,0', }) if geo_field._type in ('linestring', 'multilinestring'): none_color = '0,0,0,255' else: none_color = '255,255,255,255' symbols.append({ 'no': len(symbol_recs), 'value': '', 'label': '(None)', 'color': none_color, 'color_border': '0,0,0,255', }) base_layers[0].update({ 'symbols': symbols, 'symbols_attr': m2o_field.name, }) cls._add_symbol_style(base_layers[0], geo_field) if len(base_layers) > 1: symbols = deepcopy(symbols) # Set the border color to black for selected geometries for symbol in symbols: symbol['color_border'] = '0,0,0,255' base_layers[1].update({ 'symbols': symbols, 'symbols_attr': m2o_field.name, }) cls._add_symbol_style(base_layers[1], geo_field) return layers, bbox, srid