CREATE OR REPLACE FUNCTION AXH_CrossDateLine_fn (oldg GEOMETRY, newg GEOMETRY) 
RETURNS geometry as $$ 
DECLARE
  westmost GEOMETRY; 
  eastmost GEOMETRY; 
  curstr GEOMETRY;
  endpoint GEOMETRY;
  newseg GEOMETRY := NULL;
  h FLOAT8;
  p FLOAT8;
  zy FLOAT8;
  i INT;
  dir INT := 1;
BEGIN 

	IF newg IS NULL THEN
		RETURN oldg;
	END IF;
	IF oldg IS NULL THEN
		IF newg IS NULL THEN
			RETURN NULL;
		END IF;
		RETURN newg;
	END IF;
	

	IF ST_SRID(newg) != 3857 THEN 
		RAISE EXCEPTION 'Expects the_geom_webmercator (SRID:3857) as input geometry';
	END IF;

	IF ST_GeometryType(oldg) = 'ST_MultiLineString' THEN
		curstr := ST_GeometryN(oldg, ST_NumGeometries(oldg));
	ELSE
		curstr := oldg;
	END IF;
	endpoint := ST_PointN(curstr, ST_NumPoints(curstr));

	IF ABS(ST_X(ST_Transform(newg,4326)) - ST_X(ST_Transform(endpoint,4326))) > 180 THEN 

		IF ST_X(endpoint) < ST_X(newg) THEN
			westmost := endpoint;
			eastmost := newg;
		ELSE
			westmost := newg;
			eastmost := endpoint;
			dir := 2;
		END IF;

		h := GREATEST(ST_Y(eastmost), ST_Y(westmost)) - LEAST(ST_Y(eastmost), ST_Y(westmost));

		p := (h / (20037508.34 - ST_X(eastmost) + ST_X(westmost) + 20037508.34 )) * (20037508.34 - ST_X(eastmost));

		zy := LEAST(ST_Y(eastmost), ST_Y(westmost)) + p;

		IF dir = 2 THEN
			curstr := ST_MakeLine(
					curstr, 
					ST_MakeLine(eastmost, ST_SetSRID(ST_MakePoint(20037508.34, zy),3857))
				);
	    	newseg := ST_MakeLine(ST_SetSRID(ST_MakePoint(-20037508.34, zy),3857), westmost);
	    ELSE
			curstr := ST_MakeLine(
					curstr, 
	    			ST_MakeLine(westmost, ST_SetSRID(ST_MakePoint(-20037508.34, zy),3857))
				);
			newseg := ST_MakeLine(ST_SetSRID(ST_MakePoint(20037508.34, zy),3857), eastmost);
		END IF;

	ELSE 
		curstr := ST_MakeLine(curstr, newg);
	END IF;

	IF ST_GeometryType(oldg) = 'ST_MultiLineString' THEN
		--put the multi back together
		IF ST_NumGeometries(oldg) > 1 THEN
			i := 2;
			eastmost := ST_GeometryN(oldg, 1);
			WHILE i < ST_NumGeometries(oldg) LOOP
				eastmost := ST_Collect(eastmost, ST_GeometryN(oldg, i));
				i := i+1;
			END LOOP;
			curstr := ST_Collect(eastmost, curstr);
		END IF;
	END IF;

	-- Add the latest segment if there was one
	IF newseg IS NOT NULL THEN 
		curstr := ST_Collect(curstr, newseg);
	END IF;

	RETURN curstr;

END; 
$$ language plpgsql IMMUTABLE;
