Пример #1
0
    def handle(self, *args, **options):
        try_seeding = True
        #asyncio.get_event_loop().run_until_complete(start_headless_browser())
        #x = DBManager()

        #c = '/usr/bin/chromium --headless --disable-gpu --no-sandbox --remote-debugging-port=9222 http://localhost/gsvpanoramacollector/link_browser/default/'.split(' ')
        #c = '/usr/bin/google-chrome-stable --headless --disable-gpu --no-sandbox --remote-debugging-port=9222 http://localhost/gsvpanoramacollector/link_browser/default/'
        #process = subprocess.Popen(c, stdout=subprocess.PIPE)

        #self.stdout.write('process opened, waiting 5 seconds to start...')
        #sleep(5)
        self.stdout.write('Starting!')

        iterations = 1
        while True:
            self.stdout.write(f'Collecting...')
            try:
                self.stdout.write('Starting DBManager')
                x = DBManager()
                self.stdout.write('Starting headless browser')
                asyncio.get_event_loop().run_until_complete(self.start_headless_browser())
                self.stdout.write('x = DBManager()')
                if try_seeding:
                    try_seeding = False
                    self.stdout.write('Trying to seed')
                    x._seed_panorama()
                
                self.stdout.write('x._update_panorama_references()')
                self.stdout.write(f'{datetime.now().time()}')
                x._update_panorama_references()
                self.stdout.write(f'Success: {iterations}')
                iterations += 1
                if iterations % 20 == 0:
                    self.stdout.write(f'20 successes, restarting neo4j to avoid the memory leak issue...')
                    os.system('neo4j restart')
                    sleep(5)
                self.stdout.write('x.close()')
                x.close()
                self.stdout.write('asyncio.get_event_loop().run_until_complete(stop_headless_browser())')
                asyncio.get_event_loop().run_until_complete(self.stop_headless_browser())
            except Exception as e:
                self.stdout.write(f'Failed (iteration {iterations}) updating trying to reset chromium')
                #print(f'e.__str__(): {e.__str__()}')
                traceback.print_exc(file=sys.stdout)
                #process.kill()
                asyncio.get_event_loop().run_until_complete(self.stop_headless_browser())
                if x is not None:
                    x.close()
                #process = subprocess.Popen(c, stdout=subprocess.PIPE)
                asyncio.get_event_loop().run_until_complete(self.start_headless_browser())
                #sleep(5)
            finally:
                #process.kill()
                asyncio.get_event_loop().run_until_complete(self.stop_headless_browser())
Пример #2
0
def get_comments_view(request):
    jsondata = request.data
    geoimage = jsondata['geoimage']
    geoimage = json.loads(geoimage)
    geoimage = GeoImage.fromJSON(geoimage)
    filteruserid = jsondata.get('filteruserid')
    dbmanager = DBManager()
    comments = dbmanager.get_comments_for_view(geoImage=geoimage,
                                               user_id=filteruserid)
    comments = {"comments": comments}
    #write_to_log(comments)
    return JsonResponse(comments, CustomJSONEncoder)
Пример #3
0
def comment_view(request):
    jsondata = request.data
    geoimage = jsondata['geoimage']
    geoimage = json.loads(geoimage)
    geoimage = GeoImage.fromJSON(geoimage)
    comment = jsondata['comment']
    dbmanager = DBManager()
    view = dbmanager.get_view_from_geoimage(geoImage=geoimage, include_id=True)
    if not view:
        return HttpResponseNotFound('View associated with GeoImage not found!')
    view_id = view[0]
    UserViewComments.objects.create(user=request.user,
                                    last_update=datetime.date.today(),
                                    viewid=view_id,
                                    comment=comment)
    dbmanager.insert_comment_for_view(geoImage=geoimage,
                                      user_id=request.user.id,
                                      comment=comment)
    return HttpResponse(comment, status=201)
Пример #4
0
    def _setOutput(cls, geoImage, featureLeaf, index):
        try:
            write_to_log('_setOutput')
            dbmanager = DBManager()
            result = dbmanager.load_processed_data_for_geoImage(
                geoImage, cls.filterId)
            if result:
                filter_result = result[0]
                geoImage.setProcessedData(cls.filterId,
                                          'base64',
                                          result[1],
                                          density=filter_result['density'])
            else:
                if geoImage.dataType == 'data:image/jpeg;base64':
                    base64decoded = base64.b64decode(geoImage.data)
                    ndarrayImage = img_as_float(imageio.imread(base64decoded))
                elif geoImage.dataType == 'URL':
                    ndarrayImage = img_as_float(imageio.imread(geoImage.data))

                mask = mt_li_espectral(ndarrayImage)
                density = np.count_nonzero(mask) / mask.size
                mask = img_as_ubyte(overlay_mask(ndarrayImage, mask))
                geoImage.setProcessedData(cls.filterId,
                                          'ndarray',
                                          mask,
                                          density=density)
                dbmanager.store_geoImage_as_view(geoImage)
            featureLeaf[index] = geoImage
            #dbmanager.store_geoImage_as_view(geoImage)
        except HTTPError:
            traceback.print_exc()
            write_to_log(f"Http error - Have the quota been achieved?")
        except ValueError:
            traceback.print_exc()
            write_to_log(f'Image bytes: {ndarrayImage[:100]}')
        except Exception as e:
            traceback.print_exc()
            write_to_log(f"Unexpected error: {sys.exc_info()[0]}")
            write_to_log(f"Error message: {e.args}")
            write_to_log(f'Offending url: {geoImage.data[:300]}')
Пример #5
0
    def _getPanoramasInBoundingBoxes(
            regions: FeatureCollection) -> MultiLineString:
        """Collect a set of Ways (from GSVPanoramaManager)
        and convert them to a MultiLineString"""

        neo4jDB = DBManager()

        featuresList = []

        for feature in regions['features']:
            geom = feature['geometry']
            assert type(geom is Polygon)
            singleLineString = geom.get('coordinates')[0]
            bottom_left, top_right = GSVPanoramaMiner._get_bottom_left_top_right_corners(
                singleLineString)
            result = neo4jDB.retrieve_panorama_subgraphs_in_bounding_box(
                bottom_left, top_right)
            addresses = dict.fromkeys(
                [d['r'].get('description') for d in result])
            addresses.pop(None, 'None')
            leftNodes = set()
            rightNodes = set()
            for record in result:
                try:
                    leftNode = record['left']
                    rightNode = record['right']
                    arrow = record['r']
                    if (arrow['description'] in leftNode['description'])\
                            and (arrow['description'] in rightNode['description']):
                        if leftNode['pano'] in leftNodes:
                            continue
                        address = addresses[arrow['description']]
                        if address is None:
                            address = addresses[arrow['description']] = {}
                        linestrings = address.get('linestrings')

                        leftNodeProps = leftNode.__dict__['_properties'].copy()
                        leftNodeProps['heading'] = arrow.get('heading')

                        rightNodeProps = rightNode.__dict__[
                            '_properties'].copy()
                        # Temporarily sets the heading of the last node from a
                        # linestring. If a 'new' last node is found then
                        # this heading will be updated (following the arrow)
                        rightNodeProps['heading'] = arrow.get('heading')

                        if linestrings is None:
                            address['linestrings'] = []
                            linestrings = address.get('linestrings')

                            linestrings.append([leftNodeProps, rightNodeProps])
                            leftNodes.add(leftNodeProps['pano'])
                            rightNodes.add(rightNodeProps['pano'])

                        else:
                            # This segment merges two linestrings already
                            # added
                            if (leftNodeProps['pano'] in rightNodes)\
                                    and (rightNodeProps['pano'] in leftNodes):
                                leftLinestringIdx = None
                                rightLinestringIdx = None
                                counter = -1
                                for linestring in linestrings:
                                    counter = counter + 1
                                    # Notice that only one direction
                                    # can be extended at once
                                    # so if backward arrows are found
                                    # they will be discarded since they
                                    # require both directions to be treated
                                    # in a single check.
                                    if linestring[-1]['pano'] == leftNodeProps[
                                            'pano']:
                                        leftLinestringIdx = counter
                                    elif linestring[0][
                                            'pano'] == rightNodeProps['pano']:
                                        rightLinestringIdx = counter
                                    else:
                                        continue
                                    if (leftLinestringIdx is not None)\
                                            and (rightLinestringIdx is not None):
                                        linestrings[leftLinestringIdx] = \
                                            linestrings[leftLinestringIdx] +\
                                            linestrings[rightLinestringIdx]
                                        linestrings.pop(rightLinestringIdx)
                                        #leftLinestring = leftLinestring + rightLinestring
                                        break
                            # The line can be extended to the right
                            elif leftNodeProps['pano'] in rightNodes:
                                for linestring in linestrings:
                                    if linestring[-1]['pano'] == leftNodeProps[
                                            'pano']:
                                        print(
                                            f"extending (->) {linestring[-1]['pano']} with {rightNodeProps['pano']}"
                                        )
                                        # this updates the heading
                                        linestring[-1] = leftNodeProps
                                        # Updating the nodes that have been found as
                                        # left nodes. This keeps the navigation
                                        # consistently following a single direction.
                                        leftNodes.add(leftNodeProps['pano'])
                                        rightNodes.add(rightNodeProps['pano'])
                                        linestring.append(rightNodeProps)
                            # The line can be extended to the left
                            elif rightNodeProps['pano'] in leftNodes:
                                for linestring in linestrings:
                                    if linestring[0]['pano'] == rightNodeProps[
                                            'pano']:
                                        print(
                                            f"extending (<-) {linestring[0]['pano']} with {leftNodeProps['pano']}"
                                        )
                                        # This time the heading of the existing node doesn't
                                        # need to be updated.
                                        rightNodes.add(rightNodeProps['pano'])
                                        leftNodes.add(leftNodeProps['pano'])
                                        linestring.insert(0, leftNodeProps)
                            # A new linestring must be created
                            else:
                                linestrings.append(
                                    [leftNodeProps, rightNodeProps])
                                leftNodes.add(leftNodeProps['pano'])
                                rightNodes.add(rightNodeProps['pano'])

                                # Pegar a lista de endereços presentes na consulta.
                                # Cada dois nós de um mesmo endereço definem um segmento.
                                # Um segmento pode ser extendido.
                                # Somente um sentido de cada rua é exibido.
                                # Se dois segmentos de uma mesma rua forem desconexos
                                # então esta rua será representada por 2 linestrings
                                # cada linestring tem sua própria orientação
                except TypeError:
                    if (arrow['description'] is None)\
                       or (rightNode['description'] is None)\
                       or (leftNode['description'] is None):
                        continue
                    else:
                        print("Unexpected error:", sys.exc_info()[0])
                        raise
                except:
                    print("Unexpected error:", sys.exc_info()[0])
                    raise
            for address in addresses:
                MLS = []
                geoImageMLS = []
                if addresses[address] is None:
                    continue
                for linestring in addresses[address]['linestrings']:
                    LS = []
                    geoImageLS = []
                    for node in linestring:
                        geoJsonPoint = Point(
                            [node['location'].x, node['location'].y])
                        LS.append(geoJsonPoint)
                        geoImage = GeoImage.fromJSON({
                            'id':
                            node['pano'],
                            'location':
                            geoJsonPoint,
                            'heading':
                            node['heading'],
                            'pitch':
                            node.get('pitch', 0)
                        })
                        geoImage.data=GSVPanoramaMiner.\
                            _imageURLBuilderForGeoImage(geoImage)
                        geoImage.dataType = 'URL'
                        geoImageLS.append(geoImage)

                    MLS.append(LineString(LS))
                    geoImageMLS.append(geoImageLS)

                newFeature = Feature(id=address,
                                     properties={
                                         'name': address,
                                         'geoImages': geoImageMLS
                                     },
                                     geometry=MultiLineString(MLS))
                featuresList.append(newFeature)

        return FeatureCollection(featuresList, crs=GSVPanoramaMiner._crs)
Пример #6
0
    def getImageForFeature(feature: Feature) -> Feature:
        """
        Receives a single Feature from a 
        Feature Collection of point/line or their
        multi equivalents and inserts a "geoimages"
        property with images for the coordinates of this
        Feature.

        Works in-place.

        The geoimages property will have the same structure 
        of the geometry property.

        The coordinates without a corresponding panorama will
        be represented by a string "NOT FOUND" in the geoimages
        correspondent position.
        """

        write_to_log(f'getImageForFeature')
        dbmanager = DBManager()

        def ffunction(feature, clonedTree):
            """
            ffunction - Feature's function
            Defines how each feature (e.g. street) must be
            processed.
            """
            feature['properties']['geoImages'] = clonedTree
            pass

        def cfunction(coordinates, pointAtCoordinate=False):
            """
            cfunction - Coordinates's function
            Defines how each coordinate must be processed.

            pointAtCoordinate: If true then the heading
            will be defined to be one that points to the
            coordinate rather than the frontal direction
            from the camera.
            """
            #Try to retrieve or collect the panorama
            panorama = dbmanager.retrieve_nearest_panorama(coordinates)\
                or dbmanager.collect_panorama_by_location(coordinates)
            if panorama:
                #Get view and consequently the stored image or its url
                pano_id = panorama['pano']
                if pointAtCoordinate:
                    originP = (panorama['location']['lng'],
                        panorama['location']['lat'])
                    destinationP = (coordinates[0], coordinates[1])
                    heading = calculate_initial_compass_bearing(originP, destinationP)
                else:
                    heading = panorama['centerHeading']
                pitch = panorama['originPitch']
                
                # Optional: Just used to keep track of which views
                # were already collected.

                view = dbmanager.retrieve_panorama_view(
                    pano_id,
                    target_heading=heading,
                    heading_tolerance=10,
                    target_pitch=pitch,
                    pitch_tolerance=1
                    ) or dbmanager.create_update_view(
                        pano_id,
                        heading,
                        pitch
                        )
                
                #img_filename = dbmanager.image_filename_from_panorama_parameters(
                #    pano_id,
                #    heading,
                #    pitch
                #)
                #img_path = os.path.join(
                #    settings.PICTURES_FOLDER,
                #    img_filename
                #)
                #if os.path.exists(img_path):

                local_img = dbmanager._retrieve_local_image(
                    pano_id,
                    view
                    )
                if not local_img:
                    dbmanager._store_image_local(
                        pano_id,
                        view
                        )
                    local_img = dbmanager._retrieve_local_image(
                        pano_id,
                        view
                        )
                    pass
                return GoogleStreetViewProvider.createGeoImage(
                    pano_id,
                    panorama['location'],
                    view,
                    local_img
                ).__dict__
                #).toJSON()
            else:
                return "NOT FOUND"
        
        pointAtCoordinate = (feature['geometry']['type'].lower() == 'multipoint')

        clonedTree = ImageProvider.traverseFeature(feature, cfunction, pointAtCoordinate)
        ffunction(feature, clonedTree)
        return True
Пример #7
0
    def getImageForFeatureCollection(featureCollection: FeatureCollection) -> FeatureCollection:
        """
        Receives a feature collection of point/line or their
        multi equivalents and returns a list of GeoImage's
        """
        write_to_log(f'getImageForFeatureCollection')

        dbmanager = DBManager()

        def ffunction(feature, clonedTree):
            """
            ffunction - Feature's function
            Defines how each feature (e.g. street) must be
            processed.
            """
            feature['properties']['geoImages'] = clonedTree
            pass
        
        def cfunction(coordinates):
            """
            cfunction - Coordinates's function
            Defines how each coordinate must be processed.
            """
            #Try to retrieve or collect the panorama
            panorama = dbmanager.retrieve_nearest_panorama(coordinates)\
                or dbmanager.collect_panorama_by_location(coordinates)
            if panorama:
                #Get view and consequently the stored image or its url
                pano_id = panorama['pano']
                heading = panorama['centerHeading']
                pitch = panorama['originPitch']
                
                # Optional: Just used to keep track of which views
                # were already collected.

                view = dbmanager.retrieve_panorama_view(
                    pano_id,
                    target_heading=heading,
                    heading_tolerance=10,
                    target_pitch=pitch,
                    pitch_tolerance=1
                    ) or dbmanager.create_update_view(
                        pano_id,
                        heading,
                        pitch
                        )
                
                #img_filename = dbmanager.image_filename_from_panorama_parameters(
                #    pano_id,
                #    heading,
                #    pitch
                #)
                #img_path = os.path.join(
                #    settings.PICTURES_FOLDER,
                #    img_filename
                #)
                #if os.path.exists(img_path):

                local_img = dbmanager._retrieve_local_image(
                    pano_id,
                    view
                    )
                if not local_img:
                    dbmanager._store_image_local(
                        pano_id,
                        view
                        )
                    local_img = dbmanager._retrieve_local_image(
                        pano_id,
                        view
                        )
                    pass
                return GoogleStreetViewProvider.createGeoImage(
                    pano_id,
                    panorama['location'],
                    view,
                    local_img
                ).__dict__
                #).toJSON()
            else:
                return "NOT FOUND"                

        ImageProvider.traverseFeatureCollection(featureCollection, ffunction, cfunction)
        return True