Beispiel #1
0
    def redraw_markers_overlay_image(self, *args, new_image=False):
        if not args and not self._drawing_args or self.data is None:
            return

        if args:
            self._drawing_args = args
        north, east, south, west, width, height, zoom, origin, map_pane_pos = self._drawing_args

        lat, lon = self._latlon_data.T
        visible = ((lat <= north) & (lat >= south) &
                   (lon <= east) & (lon >= west)).nonzero()[0]
        in_subset = (np.in1d(self.data.ids, self._subset_ids)
                     if self._subset_ids.size else
                     np.tile(True, len(lon)))

        is_js_path = self.is_js_path = len(visible) < self.N_POINTS_PER_ITER

        self._update_legend(is_js_path)

        np.random.shuffle(visible)
        # Sort points in subset to be painted last
        visible = visible[np.lexsort((in_subset[visible],))]

        if is_js_path:
            self.evalJS('clear_markers_overlay_image()')
            self._update_js_markers(visible, in_subset[visible])
            self._owwidget.disable_some_controls(False)
            return

        self.evalJS('clear_markers_js();')
        self._owwidget.disable_some_controls(True)

        selected = (self._selected_indices
                    if self._selected_indices is not None else
                    np.zeros(len(lat), dtype=bool))
        cur = 0

        im = QImage(self._overlay_image_path)
        if im.isNull() or self._prev_origin != origin or new_image:
            im = QImage(width, height, QImage.Format_ARGB32)
            im.fill(Qt.transparent)
        else:
            dx, dy = self._prev_map_pane_pos - map_pane_pos
            im = im.copy(dx, dy, width, height)
        self._prev_map_pane_pos = np.array(map_pane_pos)
        self._prev_origin = origin

        painter = QPainter(im)
        painter.setRenderHint(QPainter.Antialiasing, True)
        self.evalJS('clear_markers_overlay_image(); markersImageLayer.setBounds(map.getBounds());0')

        self._image_token = image_token = np.random.random()

        n_iters = np.ceil(len(visible) / self.N_POINTS_PER_ITER)

        def add_points():
            nonlocal cur, image_token
            if image_token != self._image_token:
                return
            batch = visible[cur:cur + self.N_POINTS_PER_ITER]

            batch_lat = lat[batch]
            batch_lon = lon[batch]

            x, y = self.Projection.latlon_to_easting_northing(batch_lat, batch_lon)
            x, y = self.Projection.easting_northing_to_pixel(x, y, zoom, origin, map_pane_pos)

            if self._jittering:
                dx, dy = self._jittering_offsets[batch].T
                x, y = x + dx, y + dy

            colors = (self._colorgen.getRGB(self._scaled_color_values[batch]).tolist()
                      if self._color_attr else
                      repeat((0xff, 0, 0)))
            sizes = self._size_coef * \
                (self._sizes[batch] if self._size_attr else np.tile(10, len(batch)))

            opacity_subset, opacity_rest = self._opacity, int(.8 * self._opacity)
            for x, y, is_selected, size, color, _in_subset in \
                    zip(x, y, selected[batch], sizes, colors, in_subset[batch]):

                pensize2, selpensize2 = (.35, 1.5) if size >= 5 else (.15, .7)
                pensize2 *= self._size_coef
                selpensize2 *= self._size_coef

                size2 = size / 2
                if is_selected:
                    painter.setPen(QPen(QBrush(Qt.green), 2 * selpensize2))
                    painter.drawEllipse(x - size2 - selpensize2,
                                        y - size2 - selpensize2,
                                        size + selpensize2,
                                        size + selpensize2)
                color = QColor(*color)
                if _in_subset:
                    color.setAlpha(opacity_subset)
                    painter.setBrush(QBrush(color))
                    painter.setPen(QPen(QBrush(color.darker(180)), 2 * pensize2))
                else:
                    color.setAlpha(opacity_rest)
                    painter.setBrush(Qt.NoBrush)
                    painter.setPen(QPen(QBrush(color.lighter(120)), 2 * pensize2))

                painter.drawEllipse(x - size2 - pensize2,
                                    y - size2 - pensize2,
                                    size + pensize2,
                                    size + pensize2)

            im.save(self._overlay_image_path, 'PNG')
            self.evalJS('markersImageLayer.setUrl("{}#{}"); 0;'
                        .format(self.toFileURL(self._overlay_image_path),
                                np.random.random()))

            cur += self.N_POINTS_PER_ITER
            if cur < len(visible):
                QTimer.singleShot(10, add_points)
                self._owwidget.progressBarAdvance(100 / n_iters, None)
            else:
                self._owwidget.progressBarFinished(None)
                self._image_token = None

        self._owwidget.progressBarFinished(None)
        self._owwidget.progressBarInit(None)
        QTimer.singleShot(10, add_points)
Beispiel #2
0
    def redraw_markers_overlay_image(self, *args, new_image=False):
        if not args and not self._drawing_args or self.data is None:
            return

        if args:
            self._drawing_args = args
        north, east, south, west, width, height, zoom, origin, map_pane_pos = self._drawing_args

        lat, lon = self._latlon_data.T
        visible = ((lat <= north) & (lat >= south) &
                   (lon <= east) & (lon >= west)).nonzero()[0]
        in_subset = (np.in1d(self.data.ids, self._subset_ids)
                     if self._subset_ids.size else
                     np.tile(True, len(lon)))

        is_js_path = self.is_js_path = len(visible) < self.N_POINTS_PER_ITER

        self._update_legend(is_js_path)

        np.random.shuffle(visible)
        # Sort points in subset to be painted last
        visible = visible[np.lexsort((in_subset[visible],))]

        if is_js_path:
            self.evalJS('clear_markers_overlay_image()')
            self._update_js_markers(visible, in_subset[visible])
            self._owwidget.disable_some_controls(False)
            return

        self.evalJS('clear_markers_js();')
        self._owwidget.disable_some_controls(True)

        selected = (self._selected_indices
                    if self._selected_indices is not None else
                    np.zeros(len(lat), dtype=bool))
        cur = 0

        im = QImage(self._overlay_image_path)
        if im.isNull() or self._prev_origin != origin or new_image:
            im = QImage(width, height, QImage.Format_ARGB32)
            im.fill(Qt.transparent)
        else:
            dx, dy = self._prev_map_pane_pos - map_pane_pos
            im = im.copy(dx, dy, width, height)
        self._prev_map_pane_pos = np.array(map_pane_pos)
        self._prev_origin = origin

        painter = QPainter(im)
        painter.setRenderHint(QPainter.Antialiasing, True)
        self.evalJS('clear_markers_overlay_image(); markersImageLayer.setBounds(map.getBounds());0')

        self._image_token = image_token = np.random.random()

        n_iters = np.ceil(len(visible) / self.N_POINTS_PER_ITER)

        def add_points():
            nonlocal cur, image_token
            if image_token != self._image_token:
                return
            batch = visible[cur:cur + self.N_POINTS_PER_ITER]

            batch_lat = lat[batch]
            batch_lon = lon[batch]

            x, y = self.Projection.latlon_to_easting_northing(batch_lat, batch_lon)
            x, y = self.Projection.easting_northing_to_pixel(x, y, zoom, origin, map_pane_pos)

            if self._jittering:
                dx, dy = self._jittering_offsets[batch].T
                x, y = x + dx, y + dy

            colors = (self._colorgen.getRGB(self._scaled_color_values[batch]).tolist()
                      if self._color_attr else
                      repeat((0xff, 0, 0)))
            sizes = self._size_coef * \
                (self._sizes[batch] if self._size_attr else np.tile(10, len(batch)))

            opacity_subset, opacity_rest = self._opacity, int(.8 * self._opacity)
            for x, y, is_selected, size, color, _in_subset in \
                    zip(x, y, selected[batch], sizes, colors, in_subset[batch]):

                pensize2, selpensize2 = (.35, 1.5) if size >= 5 else (.15, .7)
                pensize2 *= self._size_coef
                selpensize2 *= self._size_coef

                size2 = size / 2
                if is_selected:
                    painter.setPen(QPen(QBrush(Qt.green), 2 * selpensize2))
                    painter.drawEllipse(x - size2 - selpensize2,
                                        y - size2 - selpensize2,
                                        size + selpensize2,
                                        size + selpensize2)
                color = QColor(*color)
                if _in_subset:
                    color.setAlpha(opacity_subset)
                    painter.setBrush(QBrush(color))
                    painter.setPen(QPen(QBrush(color.darker(180)), 2 * pensize2))
                else:
                    color.setAlpha(opacity_rest)
                    painter.setBrush(Qt.NoBrush)
                    painter.setPen(QPen(QBrush(color.lighter(120)), 2 * pensize2))

                painter.drawEllipse(x - size2 - pensize2,
                                    y - size2 - pensize2,
                                    size + pensize2,
                                    size + pensize2)

            im.save(self._overlay_image_path, 'PNG')
            self.evalJS('markersImageLayer.setUrl("{}#{}"); 0;'
                        .format(self.toFileURL(self._overlay_image_path),
                                np.random.random()))

            cur += self.N_POINTS_PER_ITER
            if cur < len(visible):
                QTimer.singleShot(10, add_points)
                self._owwidget.progressBarAdvance(100 / n_iters, None)
            else:
                self._owwidget.progressBarFinished(None)

        self._owwidget.progressBarFinished(None)
        self._owwidget.progressBarInit(None)
        QTimer.singleShot(10, add_points)
Beispiel #3
0
    def redraw_markers_overlay_image(self, *args, new_image=False):
        if (not args and not self._drawing_args or self.lat_attr is None
                or self.lon_attr is None):
            return

        if args:
            self._drawing_args = args
        north, east, south, west, width, height, zoom, origin, map_pane_pos = self._drawing_args

        lat = self.data.get_column_view(self.lat_attr)[0]
        lon = self.data.get_column_view(self.lon_attr)[0]
        visible = ((lat <= north) & (lat >= south) & (lon <= east) &
                   (lon >= west)).nonzero()[0]

        is_js_path = len(visible) <= 500

        self.evalJS('''
            window.legend_colors = %s;
            window.legend_shapes = %s;
            window.legend_sizes  = %s;
            legendControl.remove();
            legendControl.addTo(map);
        ''' % (self._legend_colors, self._legend_shapes if is_js_path else [],
               self._legend_sizes))

        if is_js_path:
            self.evalJS('clear_markers_overlay_image()')
            self._update_js_markers(visible)
            self._owwidget.disable_some_controls(False)
            return

        self.evalJS('clear_markers_js();')
        self._owwidget.disable_some_controls(True)

        np.random.shuffle(visible)

        selected = (self._selected_indices if self._selected_indices
                    is not None else np.zeros(len(lat), dtype=bool))

        N_POINTS_PER_ITER = 1000
        cur = 0

        im = QImage(self._overlay_image_path)
        if im.isNull() or self._prev_origin != origin or new_image:
            im = QImage(width, height, QImage.Format_ARGB32)
            im.fill(Qt.transparent)
        else:
            dx, dy = self._prev_map_pane_pos - map_pane_pos
            im = im.copy(dx, dy, width, height)
        self._prev_map_pane_pos = np.array(map_pane_pos)
        self._prev_origin = origin

        painter = QPainter(im)
        painter.setRenderHint(QPainter.Antialiasing, True)
        self.evalJS(
            'clear_markers_overlay_image(); markersImageLayer.setBounds(map.getBounds());0'
        )

        self._image_token = image_token = np.random.random()

        n_iters = np.ceil(len(visible) / N_POINTS_PER_ITER)

        def add_points():
            nonlocal cur, image_token
            if image_token != self._image_token:
                return
            batch = visible[cur:cur + N_POINTS_PER_ITER]

            batch_lat = lat[batch]
            batch_lon = lon[batch]
            batch_selected = selected[batch]

            x, y = self.Projection.latlon_to_easting_northing(
                batch_lat, batch_lon)
            x, y = self.Projection.easting_northing_to_pixel(
                x, y, zoom, origin, map_pane_pos)

            if self._jittering:
                x += (np.random.random(len(x)) - .5) * (self._jittering *
                                                        width)
                y += (np.random.random(len(x)) - .5) * (self._jittering *
                                                        height)

            colors = (self._colorgen.getRGB(
                self._scaled_color_values[batch]).tolist()
                      if self._color_attr else repeat((0xff, 0, 0)))
            sizes = self._sizes[batch] if self._size_attr else repeat(10)

            zipped = zip(x, y, batch_selected, sizes, colors)
            sortkey, penkey, sizekey, brushkey = itemgetter(
                2, 3, 4), itemgetter(2), itemgetter(3), itemgetter(4)
            for is_selected, points in groupby(sorted(zipped, key=sortkey),
                                               key=penkey):
                for size, points in groupby(points, key=sizekey):
                    pensize, pencolor = ((3, Qt.green) if is_selected else
                                         (.7, QColor(0, 0, 0, self._opacity)))
                    size *= self._size_coef
                    if size < 5:
                        pensize /= 3
                    size += pensize
                    size2 = size / 2
                    painter.setPen(Qt.NoPen if size < 5 and not is_selected
                                   else QPen(QBrush(pencolor), pensize))

                    for color, points in groupby(points, key=brushkey):
                        color = tuple(color) + (self._opacity, )
                        painter.setBrush(QBrush(QColor(*color)))
                        for x, y, *_ in points:
                            painter.drawEllipse(x - size2, y - size2, size,
                                                size)

            im.save(self._overlay_image_path, 'PNG')
            self.evalJS('markersImageLayer.setUrl("{}#{}"); 0;'.format(
                self._overlay_image_path, np.random.random()))

            cur += N_POINTS_PER_ITER
            if cur < len(visible):
                QTimer.singleShot(10, add_points)
                self._owwidget.progressBarAdvance(100 / n_iters, None)
            else:
                self._owwidget.progressBarFinished(None)

        self._owwidget.progressBarFinished(None)
        self._owwidget.progressBarInit(None)
        QTimer.singleShot(10, add_points)