<commit_before>import math
from urlparse import urljoin
import logging
import HTMLParser

from django.db import connection
from django.conf import settings
from django.utils.timezone import utc
from django.utils.html import escape, strip_tags
from django.contrib.gis.gdal.error import OGRException
from django.contrib.gis.geos import GEOSException, fromstr, LineString, Point

logger = logging.getLogger(__name__)


class classproperty(object):
    def __init__(self, getter):
        self.getter = getter

    def __get__(self, instance, owner):
        return self.getter(owner)


# This one come from pyramid
# https://github.com/Pylons/pyramid/blob/master/pyramid/decorator.py
class reify(object):

    """ Put the result of a method which uses this (non-data)
    descriptor decorator in the instance dict after the first call,
    effectively replacing the decorator with an instance variable."""

    def __init__(self, wrapped):
        self.wrapped = wrapped
        try:
            self.__doc__ = wrapped.__doc__
        except:  # pragma: no cover
            pass

    def __get__(self, inst, objtype=None):
        if inst is None:
            return self
        val = self.wrapped(inst)
        setattr(inst, self.wrapped.__name__, val)
        return val


def dbnow():
    cursor = connection.cursor()
    cursor.execute("SELECT statement_timestamp() AT TIME ZONE 'UTC';")
    row = cursor.fetchone()
    return row[0].replace(tzinfo=utc)


def distance3D(a, b):
    """
    Utility function computing distance between 2 points in 3D-space.
    Will work with coordinates tuples instead of full-fledged geometries,
    that's why is is more convenient than GEOS functions.
    """
    return math.sqrt((b[0] - a[0]) ** 2 +
                     (b[1] - a[1]) ** 2 +
                     (b[2] - a[2]) ** 2)


def elevation_profile(g, maxitems=None):
    """
    Extract elevation profile from a 3D geometry.
    - maxitems : maximum number of points
    """
    if g.geom_type == 'MultiLineString':
        profile = []
        offset = 0.0
        for subcoords in g.coords:
            subline = LineString(subcoords)
            subprofile = elevation_profile(subline, maxitems=maxitems)
            profile.extend(subprofile)
            offset += subprofile[-1][0]
        return profile

    step = 1
    if maxitems is not None:
        nb = len(g.coords)
        step = max(1, nb / maxitems)
    # Initialize with null distance at start point
    distance = 0.0
    profile = [(distance, g.coords[0][2])]
    # Add elevation and cumulative distance at each point
    for i in range(1, len(g.coords), step):
        a = g.coords[i - step]
        b = g.coords[i]
        distance += distance3D(a, b)
        profile.append((distance, b[2],))
    return profile


def force3D(geom):
    if not geom or geom.geom_type != 'Point':
        raise ValueError('Cannot force 3D on %s' % geom)
    if geom.z != 0:
        return geom
    return Point(geom.x, geom.y, 0)


def wkt_to_geom(wkt, srid_from=None, silent=False):
    if srid_from is None:
        srid_from = settings.API_SRID
    try:
        return fromstr(wkt, srid=srid_from)
    except (OGRException, GEOSException) as e:
        if not silent:
            raise e
        return None


def transform_wkt(wkt, srid_from=None, srid_to=None):
    """
    Changes SRID, and returns 3D wkt
    """
    if srid_from is None:
        srid_from = settings.API_SRID
    if srid_to is None:
        srid_to = settings.SRID
    try:
        geom = fromstr(wkt, srid=srid_from)
        if srid_from != srid_to:
            geom.transform(srid_to)
        dim = 3
        extracoords = ' 0.0' * (dim - 2)  # add missing dimensions
        wkt3d = geom.wkt.replace(',', extracoords + ',')
        return wkt3d
    except (OGRException, GEOSException, TypeError, ValueError), e:
        if not settings.TEST:
            logger.error("wkt_to_geom('%s', %s, %s) : %s" % (wkt, srid_from, srid_to, e))
        return None


def sqlfunction(function, *args):<commit_msg>Make sure last coordinates does have a Z (ref #543)<commit_after>import math
from urlparse import urljoin
import logging
import HTMLParser

from django.db import connection
from django.conf import settings
from django.utils.timezone import utc
from django.utils.html import escape, strip_tags
from django.contrib.gis.gdal.error import OGRException
from django.contrib.gis.geos import GEOSException, fromstr, LineString, Point

logger = logging.getLogger(__name__)


class classproperty(object):
    def __init__(self, getter):
        self.getter = getter

    def __get__(self, instance, owner):
        return self.getter(owner)


# This one come from pyramid
# https://github.com/Pylons/pyramid/blob/master/pyramid/decorator.py
class reify(object):

    """ Put the result of a method which uses this (non-data)
    descriptor decorator in the instance dict after the first call,
    effectively replacing the decorator with an instance variable."""

    def __init__(self, wrapped):
        self.wrapped = wrapped
        try:
            self.__doc__ = wrapped.__doc__
        except:  # pragma: no cover
            pass

    def __get__(self, inst, objtype=None):
        if inst is None:
            return self
        val = self.wrapped(inst)
        setattr(inst, self.wrapped.__name__, val)
        return val


def dbnow():
    cursor = connection.cursor()
    cursor.execute("SELECT statement_timestamp() AT TIME ZONE 'UTC';")
    row = cursor.fetchone()
    return row[0].replace(tzinfo=utc)


def distance3D(a, b):
    """
    Utility function computing distance between 2 points in 3D-space.
    Will work with coordinates tuples instead of full-fledged geometries,
    that's why is is more convenient than GEOS functions.
    """
    return math.sqrt((b[0] - a[0]) ** 2 +
                     (b[1] - a[1]) ** 2 +
                     (b[2] - a[2]) ** 2)


def elevation_profile(g, maxitems=None):
    """
    Extract elevation profile from a 3D geometry.
    - maxitems : maximum number of points
    """
    if g.geom_type == 'MultiLineString':
        profile = []
        offset = 0.0
        for subcoords in g.coords:
            subline = LineString(subcoords)
            subprofile = elevation_profile(subline, maxitems=maxitems)
            profile.extend(subprofile)
            offset += subprofile[-1][0]
        return profile

    step = 1
    if maxitems is not None:
        nb = len(g.coords)
        step = max(1, nb / maxitems)
    # Initialize with null distance at start point
    distance = 0.0
    profile = [(distance, g.coords[0][2])]
    # Add elevation and cumulative distance at each point
    for i in range(1, len(g.coords), step):
        a = g.coords[i - step]
        b = g.coords[i]
        distance += distance3D(a, b)
        profile.append((distance, b[2],))
    return profile


def force3D(geom):
    if not geom or geom.geom_type != 'Point':
        raise ValueError('Cannot force 3D on %s' % geom)
    if geom.z != 0:
        return geom
    return Point(geom.x, geom.y, 0)


def wkt_to_geom(wkt, srid_from=None, silent=False):
    if srid_from is None:
        srid_from = settings.API_SRID
    try:
        return fromstr(wkt, srid=srid_from)
    except (OGRException, GEOSException) as e:
        if not silent:
            raise e
        return None


def transform_wkt(wkt, srid_from=None, srid_to=None):
    """
    Changes SRID, and returns 3D wkt
    """
    if srid_from is None:
        srid_from = settings.API_SRID
    if srid_to is None:
        srid_to = settings.SRID
    try:
        geom = fromstr(wkt, srid=srid_from)
        if srid_from != srid_to:
            geom.transform(srid_to)
        dim = 3
        extracoords = ' 0.0' * (dim - 2)  # add missing dimensions
        wkt3d = geom.wkt.replace(',', extracoords + ',')
        wkt3d = wkt3d.replace(')', extracoords + ')')
        return wkt3d
    except (OGRException, GEOSException, TypeError, ValueError), e:
        if not settings.TEST:
            logger.error("wkt_to_geom('%s', %s, %s) : %s" % (wkt, srid_from, srid_to, e))
        return None


def sqlfunction(function, *args):
{'fraction_non_alphanumeric': 0.10259867614611425, 'fraction_numerical': 0.009928904143172346, 'mean_word_length': 2.491228070175439, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5654709', 'n_tokens_mistral': 2674, 'n_tokens_neox': 2560, 'n_words': 761}