All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hazelcast.org.apache.calcite.runtime.HilbertCurve2D Maven / Gradle / Ivy

There is a newer version: 5.4.0
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.hazelcast.org.apache.calcite.runtime;

import com.hazelcast.com.google.common.collect.ImmutableList;
import com.hazelcast.com.google.uzaygezen.core.BacktrackingQueryBuilder;
import com.hazelcast.com.google.uzaygezen.core.BitVector;
import com.hazelcast.com.google.uzaygezen.core.BitVectorFactories;
import com.hazelcast.com.google.uzaygezen.core.CompactHilbertCurve;
import com.hazelcast.com.google.uzaygezen.core.FilteredIndexRange;
import com.hazelcast.com.google.uzaygezen.core.LongContent;
import com.hazelcast.com.google.uzaygezen.core.PlainFilterCombiner;
import com.hazelcast.com.google.uzaygezen.core.Query;
import com.hazelcast.com.google.uzaygezen.core.SimpleRegionInspector;
import com.hazelcast.com.google.uzaygezen.core.ZoomingSpaceVisitorAdapter;
import com.hazelcast.com.google.uzaygezen.core.ranges.LongRange;
import com.hazelcast.com.google.uzaygezen.core.ranges.LongRangeHome;

import java.util.ArrayList;
import java.util.List;

/**
 * 2-dimensional Hilbert space-filling curve.
 *
 * 

Includes code from * LocationTech SFCurve, * Copyright (c) 2015 Azavea. */ public class HilbertCurve2D implements SpaceFillingCurve2D { final long precision; final CompactHilbertCurve chc; private final int resolution; public HilbertCurve2D(int resolution) { this.resolution = resolution; precision = (long) Math.pow(2, resolution); chc = new CompactHilbertCurve(new int[] {resolution, resolution}); } long getNormalizedLongitude(double x) { return (long) ((x + 180) * (precision - 1) / 360d); } long getNormalizedLatitude(double y) { return (long) ((y + 90) * (precision - 1) / 180d); } long setNormalizedLatitude(long latNormal) { if (!(latNormal >= 0 && latNormal <= precision)) { throw new NumberFormatException( "Normalized latitude must be greater than 0 and less than the maximum precision"); } return (long) (latNormal * 180d / (precision - 1)); } long setNormalizedLongitude(long lonNormal) { if (!(lonNormal >= 0 && lonNormal <= precision)) { throw new NumberFormatException( "Normalized longitude must be greater than 0 and less than the maximum precision"); } return (long) (lonNormal * 360d / (precision - 1)); } @Override public long toIndex(double x, double y) { final long normX = getNormalizedLongitude(x); final long normY = getNormalizedLatitude(y); final BitVector[] p = { BitVectorFactories.OPTIMAL.apply(resolution), BitVectorFactories.OPTIMAL.apply(resolution) }; p[0].copyFrom(normX); p[1].copyFrom(normY); final BitVector hilbert = BitVectorFactories.OPTIMAL.apply(resolution * 2); chc.index(p, 0, hilbert); return hilbert.toLong(); } @Override public Point toPoint(long i) { final BitVector h = BitVectorFactories.OPTIMAL.apply(resolution * 2); h.copyFrom(i); final BitVector[] p = { BitVectorFactories.OPTIMAL.apply(resolution), BitVectorFactories.OPTIMAL.apply(resolution) }; chc.indexInverse(h, p); final long x = setNormalizedLongitude(p[0].toLong()) - 180; final long y = setNormalizedLatitude(p[1].toLong()) - 90; return new Point((double) x, (double) y); } @Override public List toRanges(double xMin, double yMin, double xMax, double yMax, RangeComputeHints hints) { final CompactHilbertCurve chc = new CompactHilbertCurve(new int[] {resolution, resolution}); final List region = new ArrayList<>(); final long minNormalizedLongitude = getNormalizedLongitude(xMin); final long minNormalizedLatitude = getNormalizedLatitude(yMin); final long maxNormalizedLongitude = getNormalizedLongitude(xMax); final long maxNormalizedLatitude = getNormalizedLatitude(yMax); region.add(LongRange.of(minNormalizedLongitude, maxNormalizedLongitude)); region.add(LongRange.of(minNormalizedLatitude, maxNormalizedLatitude)); final LongContent zero = new LongContent(0L); final SimpleRegionInspector inspector = SimpleRegionInspector.create(ImmutableList.of(region), new LongContent(1L), range -> range, LongRangeHome.INSTANCE, zero); final PlainFilterCombiner combiner = new PlainFilterCombiner<>(LongRange.of(0, 1)); final BacktrackingQueryBuilder queryBuilder = BacktrackingQueryBuilder.create(inspector, combiner, Integer.MAX_VALUE, true, LongRangeHome.INSTANCE, zero); chc.accept(new ZoomingSpaceVisitorAdapter(chc, queryBuilder)); final Query query = queryBuilder.get(); final List> ranges = query.getFilteredIndexRanges(); // result final List result = new ArrayList<>(); for (FilteredIndexRange l : ranges) { final LongRange range = l.getIndexRange(); final Long start = range.getStart(); final Long end = range.getEnd(); final boolean contained = l.isPotentialOverSelectivity(); result.add(0, IndexRanges.create(start, end, contained)); } return result; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy